有人的地方就有江湖,有函数的地方就有
this
。而this在不一样的环境下,又表现为不一样的形式,不免让人有种此this非彼this的疑惑javascript
在java等面向对象的语言中,this指的就是当前对象,而在javascript中这就不灵了,javascript中this是在编译期动态绑定的,这就造成了一把双刃剑:足够灵活却又容易让人迷惑。在javascript中this能够是全局对象、当前对象甚至任意对象(obj.call(this)
)。
咱们经过函数的几种不一样调用方式来看一下各自this的意义:java
在javascript中函数也是个对象,所以,函数能够做为一个对象的属性出现:程序员
var object = { name:"jeffie", sayWhat:function(){ console.log(this.name + ":hello"); //jeffie:hello } } object.sayWhat();
此处的this指向object对象,也就是函数所在的对象。segmentfault
当函数直接被调用时,此时函数中的this指向全局变量,也就是window对象:数组
function obj(){ console.log(this); } obj();//Window
在做为构造函数调用时,this指向的是新生成的实例对象:闭包
function Plugin(name,type){ this.name = name; this.type = type; } var plugin = new Plugin("core",1); console.log(plugin.name);//core
javascript中每一个函数都包含两个方法:apply()和call(),这两个方法很是强大,它们能够切换函数的上下文执行环境,也就是说能够修改this绑定的对象。简单来讲,这两个方法能够用来设置函数的this,两个方法都接收两个参数,第一个参数是运行函数的做用域,第二个参数是参数对象,惟一的区别是apply第二个参数为参数数组(Array或者arguments):app
function Plugin(name,type){ this.name = name; this.type = type; this.debugs = function(name,type){ console.log(this); //Object {name: "base", type: 3} } } var plugin1 = new Plugin("core",1); var plugin2 = {name:"base",type:3}; console.log(plugin1.debugs.call(plugin2));
经过上面的示例能够看出this值再也不指向Plugin对象了,而是指向了plugin2的对象。函数
一般咱们理解this对象是运行时基于函数绑定的,全局函数中this对象就是window对象,而当函数做为对象中的一个方法调用时,this等于这个对象。因为匿名函数的做用域是全局性的,所以闭包的this一般指向全局对象window:this
var scope = "global"; var object = { scope:"local", getScope:function(){ return function(){ return this.scope; } } }
调用object.getScope()()返回值为global而不是咱们预期的local,在闭包中函数做为某个对象的方法调用时,要特别注意,该方法内部匿名函数的this指向的是全局变量。参考上一篇闭包
这属于 JavaScript 的设计缺陷,正确的设计方式是内部函数的 this 应该绑定到其外层函数对应的对象上,为了规避这一设计缺陷,聪明的 JavaScript 程序员想出了变量替代的方法,只须要把外部函数做用域的this存放到一个闭包能访问的变量里面便可,约定俗成,该变量通常被命名为 that:debug
var scope = "global"; var object = { scope:"local", getScope:function(){ var that = this; return function(){ return that.scope; } } } object.getScope()()返回值为local。