要的就是你:this
引言
“人啊,认识你自己吧!” 这是太阳神阿波罗神庙的铭文,刻于公元前900年。
自己是谁?但凡做事情、想东西都需要一个主体,这个主体往往就是自己。当然,人们不需要清楚自己,也可以做事情、想东西。
this是啥?但凡取数值、调方法都需要一个主体,这个主体往往就是this。同样,开发者也许并不了解,但同样能取数值、调方法。
我曾经就是这样的开发者,所以今天找了些资料,希望有所改善。
理论
上下文就像一个容器,用来存储当前上下文中所有已定义或可获取的变量、函数等。位于最顶端的上下文称为全局上下文,如Node中的global和Browser中的window;
作用域链实际上就是自下而上地将所有嵌套定义的上下文所绑定的变量对象串接到一起,使嵌套的function可以“继承”上层上下文的变量,而并列的function之间互不干扰。
1、入栈:每个function开始执行,就会产生一个新的上下文,它会被压入js的上下文堆栈中;
2、传值:绑定该上下文的变量对象,其中包括arguments和该函数中定义的变量(变量提升);
3、继承:创建新的对象,把函数的prototype传递给该对象的__proto__,并返回该对象(this);
4、出栈:function执行结束后则被弹出,因此Js解释器总是在栈顶上下文中执行;
入栈和出栈容易理解,因为js是单线程的。arguments是形参,它记录调用者传递过来的实参。
至于第三步的继承,上一篇介绍过第一公民,函数被new的一瞬间,发生了以下四件事:
var obj ={};//创建空对象 obj.__proto__ = MyFunc.prototype;//将这个空对象的__proto__成员指向了构造函数对象的prototype成员对象 MyFunc.call(obj);//将构造函数的作用域赋给新对象 return obj//返回新对象obj
实际上这个返回的新对象,对于所有函数成员(变量或者方法)来说,就是this。
闭包
好了,现在我们知道函数新建和执行时发生了什么,下面来考虑一种特殊情况:嵌套定义function,并返回function
首先,返回的function所包含的作用域链将会一起返回;
然后,内层function可以在其他上下文中执行,其作用域链仍然保持原来的数据;
再后,当前的上下文可能无法获取外层function中的数据(内层function保存的那些);
最后,数据即所谓的自由变量,使得function内部的作用域链被保护起来,从而形成“闭包”。
引申
使用this时了能会猜到的坑,以及解决方案:传送门
建议了解call和apply方法,尽量避免踩坑: 传送门
总结
本文侧重的是原理,而非实例,顺便把前面的收获串起来当作复习。