详解JavaScript的闭包、IIFE、apply、函数与对象

前端之家收集整理的这篇文章主要介绍了详解JavaScript的闭包、IIFE、apply、函数与对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

目录

一、闭包(Closure)

1.1、闭包相关的问题

1.2、理解闭包

二、对象

2.1、对象常量(字面量)

2.2、取值

2.3、枚举(遍历)

2.4、更新与添加

2.5、对象的原型

2.6、删除

2.7、封装

三、函数

3.1、参数对象 (arguments)

3.2、构造函数

3.3、函数调用

3.3.1、call

3.3.2、apply

3.3.3、caller

3.3.4、Callee

3.5、立即执行函数表达式 (IIFE)

3.5.1、匿名函数与匿名对象

3.5.2、函数函数表达式

3.5.3、立即执行函数表达式与匿名对象

3.5.4、各种IIFE的写法

3.5.5、参数

3.5.6、添加分号

3.5.7、IIFE的作用

3.5.8、IIFE的变形

四、示例下载

一、闭包(Closure)

1.1、闭包相关的问题

请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9;方法:找到所有的div,for循环绑定事件。

示例代码

<Meta charset="UTF-8"> 闭包
a
b
c
d
e
f
g
h
i
j

运行结果:

原型关系是一种动态关系,如果修改原型,该原型创建的对象会受到影响。

var jack=Object.create(rose);
jack.name="jack";

//修改原型中的方法
rose.show=function(){
console.log("姓名->"+this.name);
}

lucy.show();
jack.show();

结果:

关于原型在函数中会再讲到。

2.6、删除

删除属性 delete mark.name; //调用方法输出:姓名:undefined mark.show(); //删除函数 delete mark.show; //错误,mark.show is not a function mark.show();

删除不用的属性是一个好习惯,在某些情况下可能引发内存泄漏。

2.7、封装

使用对象封装的好处是可以减少全局变量的污染机会,将属性函数都隶属一个对象。

"+name); console.log(++i); } //i是全局的 2 show(); //3 show();

封装后:

"+this.name); console.log(++i); } }; }; var bar1=bar(); //2 bar1.show(); //3 bar1.show(); var bar2=bar(); //2,因为被封装,且闭包,i是局部私有的 bar2.show();

运行结果:

三、函数

javascript中的函数就是对象,对象就是“键/值”对的集合并拥有一个连接到原型对隐藏连接。

3.1、参数对象 (arguments)

第一个函数中有一个默认对象叫arguments,类似数组,但不是数组,该对象是传递给函数的参数。

运行结果:

1205

0

这里的arguments是一个隐式对象,不声明也在函数中,内部函数可以访问外部函数的任意内容,但是不能直接访问外部函数的arguments与this对象。

运行结果:

3

0

3.2、构造函数

在javascript中对象构造函数可以创建一个对象。

rose.show();
jack.show();

3.3、函数调用

3.3.1、call

调用一个对象的一个方法,以另一个对象替换当前对象

call([thisObj[,args])

hisObj 可选项。将被用作当前对象的对象。args 将被传递方法参数序列。

call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

示例:

运行结果:

call方法中的参数都可以省去,第1个参数表示在哪个对象上调用该方法,或this指向谁,如果不指定则会指向window对象。

示例:

结果:

undefined:无名,18

3.3.2、apply

apply([thisObj[,argArray]])

应用某一对象的一个方法,用另一个对象替换当前对象,与call类似。

如果 argArray 不是一个有效的数组或者不是arguments对象,那么将导致一个 TypeError。

如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

对于第一个参数意义都一样,但对第二个参数:

apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。

如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var3])

同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入

示例代码:

运行结果:

从上面的示例中可以发现apply的第2个参数是一个数组,数组中的内容将映射到被调用方法的参数中,如果单这样看发现不如call方便,其实如果直接取方法的参数arguments则apply要方便一些。通过简单的变化就可以替代call。

结果:

hi:jack,20,224cm

javascript里call和apply操作符可以随意改变this指向

如果在javascript语言里没有通过new(包括对象字面量定义)、call和apply改变函数的this指针,函数的this指针都是指向window的。

关于this指针,我的总结是:是谁调用的函数,那么这个函数中的this指针就是它;如果没有明确看出是谁调用的,那么应该就是window调用的,那么this指针就是window。

3.3.3、caller

在一个函数调用另一个函数时,被调用函数会自动生成一个caller属性,指向调用它的函数对象。如果该函数当前未被调用,或并非被其他函数调用,则caller为null。

在JavaScript的早期版本中,Function对象的caller属性是对调用当前函数的函数的引用

运行结果:

caller与this还是有区别的,this是指调用方法的对象,而caller是指调用函数的函数。

结果:

3.3.4、Callee

当函数被调用时,它的arguments.callee对象就会指向自身,也就是一个对自己的引用

运行结果:

当第1次调用add方法时输入3,立即将函数返回再次调用,每次调用后又返回自己,这样可以实现链式编程。

3.5、立即执行函数表达式 (IIFE)

IIFE即Immediately-Invoked Function Expression,立即执行函数表达式

3.5.1、匿名函数与匿名对象

匿名函数就是没有名称的函数,javascript中经常会使用匿名函数实现事件绑定,回调,实现函数级的私有作用域,如下所示:

匿名对象:

没有名称的匿名函数也叫函数表达式,它们间是有区别的。

3.5.2、函数与函数表达式

下面是关于函数与函数表达式定义时的区别

a)、函数定义(Function Declaration)

function Identifier ( Parameters ){ FunctionBody }

function 函数名称(参数){函数主体}

在函数定义中,参数(Parameters)标识符(Identifier )是必不可少的。如果遗漏,会报提示错误:

代码:

结果:

b)、函数表达式(Function Expression)

function Identifier(Parameters){ FunctionBody }

函数表达式中,参数和标识符都是可选的,与函数定义的区别是标识符可省去。

其实,"function Identifier(Parameters){ FunctionBody }"并不是一个完整的函数表达式,完整的函数的表达式,需要一个赋值操作。

比如: var name=function Identifier(Parameters){ FunctionBody }

3.5.3、立即执行函数表达式与匿名对象

第3种写法为什么这样就能立即执行并且不报错呢?因为在javascript里,括号内部不能包含语句,当解析器对代码进行解释的时候,先碰到了(),然后碰到function关键字就会自动将()里面的代码识别为函数表达式而不是函数声明。

如果需要将函数表达式或匿名对象立即执行,可以使用如下方法:

IIFE

猜你在找的JavaScript相关文章