This指代函数当前的运行环境。
JavaScript 中的 this,它可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript 中函数的调用有以下几种方式:
1.作为对象方法调用
2.作为函数直接调用
3.作为构造函数调用
4.使用 apply 或 call,bind 调用
我们将按照调用方式的不同,分别讨论 this 的含义。
作为对象方法调用
在 JavaScript 中,函数也是对象,因此函数可以作为一个对象的属性,此时该函数被称为该对象的方法,在使用这种调用方式时,this 被自然绑定到该对象
1 | var test = { |
由此可见this是动态作用域,this的指向关键是看函数怎么调用而不是怎么创建。
作为函数直接调用
函数也可以直接被调用,此时 this 绑定到全局对象(在严格模式下为undefined)。在浏览器中,window 就是该全局对象。
1 | function fn1 (){ |
作为构造函数调用
当函数作为构造函数调用时,this代表new出来的对象,并且对象的原型会指向构造器的prototype(构造器是Foo、foo.constructor=Foo )
如果没有使用new而是直接调用函数,this===window;
1 | function Foo (name){ |
使用 apply 或 call,bind 调用
apply 和 call允许切换函数执行的上下文环境(context),即 this 绑定的对象。this取得的是apply() 、call()、 bind()调用时传入的第一个参数(bind是ES5提供的方法,所以只有IE9及以上才支持)
apply()、call()
1 | function add(c,d){ |
直接调用func(),this会指向bind中的参数,所以返回值为1,由于执行this.b=100,所以this对象会有个b属性,最终this为{a: 1, b: 100}。用new的话return如果不是对象会把this作为返回值,并且this会被初始化为一个默认的空对象,对象的原型是构造器的prototype,所以这里虽然用了bind的方法,但是this仍然会指向没有bind的情况。this指向空对象,空对象的原型指向foo.prototype,空对象的b属性会设置为100,整个对象会作用返回值(return this.a 被忽视)所以结果为{b:100}.
bind与currying(函数柯里化:把一个函数拆成多个单元)
1 | function add(a,b,c){ |
有时候不需要一次性把函数都调用完,而是调用一次把前几个参数传完了以后得到了一个函数再去调用,并且每次都传入自己所需要传入的值。
add.bind不需要改变this,那么就传入undefined(null也可),但是我们提供了额外参数100,那么bind方法就会把100赋值给a,再调用的时候1会给b,2就会给c,所以最后答案是103。再func.bind一次a上次绑定了100,b就会绑定为200,再调用func2传入值为10,10赋值为c,所以func2调用结果为310。
1 | function getConfig(color,size,otherOptions){ |
不同环境this的取值
全局作用域中this(浏览器)
全局作用域中的this一般指向全局对象,在浏览器中全局对象就是window
console.log(window.document===document) //true
console.log(this===window) //true
this.a=37
console.log(window.a) //37
对象原型链上的this
1 | var o={ f:function(){ this.a + this.b } } |
p是空对象并且它的原型会指向o(p.proto===o),调用原型上的方法(对象本身没有此方法会沿着原型链向上查找,原型链上的this也可以指向Object.create创建的对象,此this的指向与new创建实例对象的指向类似)this.a和this.b仍然能取到对象p上的a和b。即原型链上的this可以指向所在的对象(p对象)
注:p的构造器不为o,为Object(p.constructor===Object),这是用Object.create创建对象与new实例创建对象的不同,如果是new创建的实例对象构造器就是o。
get/set方法与this
此时this的指向与原型链上的this的指向类似
1 | function modules(){ |
get、set方法中的this,一般情况下也是会指向get,set方法所在的对象(与一般对象属性作为函数对象类似)。
参考资料:
JavaScript 的 this 原理