this使用
在介绍this使用之前,先说明:this到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了。因为this的取值是执行上下文环境的一部分,每次调用函数,都会产生一个新的执行上下文环境。
构造函数
|
|
如果函数作为构造函数用,那么其中的this就代表它即将new出来的对象;反之如果直接调用函数,而不是new,this会指向window。
在构造函数的prototype和整个原型链中,this代表的也都是当前对象的值。
函数作为对象的一个属性
|
|
1。如果函数作为对象的一个属性,并且作为对象的一个属性被调用时,函数中的this指向该对象。如情况1
2。如果fnName函数被赋值到了另一个变量中,并没有作为一个属性被调用,那么this的值就是window,this.name为undefined。
函数用call或者apply调用
|
|
全局 & 调用普通函数
在全局环境
在全局环境下,this永远是window
普通函数
普通函数在调用时,其中的this也都是window。
执行上下文栈
执行全局代码时,会产生一个执行上下文环境,每次调用函数都又会产生执行上下文环境。当函数调用完成时,这个上下文环境以及其中的数据都会被消除,再重新回到全局上下文环境。处于活动状态的执行上下文环境只有一个。这是一个压栈出栈的过程——执行上下文栈。
全局上下文环境 =压栈=》(函数上下文环境/全局上下文环境) =出栈销毁=》全局上下文环境
理想情况
1、首先在执行代码之前,首先将创建全局上下文环境。
创建变量a,fn1,fn2,this
2、当执行到fn2时,上下文环境中的变量都在执行过程中被赋值。
3、执行fn2,并挑到fn2函数内部,会创建一个新的上下文环境。并将这个执行的上下文环境压栈,设置为活动状态。
4,执行到fn1时,跳到fn1中,在执行fn1语句之前,会创建fn1函数的执行上下文环境,并压栈,设置为活动状态。
5、待fn1函数执行完。此次调用fn1所生成的上下文环境出栈,并且被销毁(已经用完了,就要及时销毁,释放内存)。
6、待fn2函数执行完。此次调用fn2所生成的上下文环境出栈,并且被销毁(已经用完了,就要及时销毁,释放内存)。
闭包
闭包的两种情况
函数作为返回值
|
|
fn3函数作为返回值,赋值给fn1变量。执行fn2(120)时,用到了fn1作用域下的max变量的值。
注意:作用域取值,要到创建这个函数的那个作用域中取值——是创建,而不是调用的地方
函数作为参数传递
|
|
fn1函数作为一个参数被传递进入另一个函数,赋值给f参数。执行f(130)时,max变量的取值是100,而不是50。
|
|
分析闭包:
1、代码执行前生成全局上下文环境,并在执行时对其中的变量进行赋值。此时全局上下文环境是活动状态。
2、当执行到var fn2 = fn1()时,调用fn1函数,产生fn1()执行上下文环境,压栈,并设置为活动状态。
3、执行完fn1函数,fn1函数的执行上下文不能被销毁,因为执行fn1()时,返回的是一个函数。函数的特别之处在于可以创建一个独立的作用域。且这个函数中还有一个自由变量max要引用fn1作用域下的的max。因此不能销毁max,否则fn3函数将找不到max的值,因此fn1函数不能被销毁。即执行完fn1函数。全局上下文变成活动状态,fn1还是不能被销毁,依旧存在在执行栈中。
4、执行到fn2函数,即执行fn3(130),创建上下文,并将其设为活动状态。当执行fn3函数,需要用到max。但是fn1函数已经执行过了。但是其执行上下文环境还存在与栈中,因此fn3可以找到max。如果销毁fn1函数上下文,就找不到max了。
5、执行完fn3就是上下文环境的销毁过程。
(完)