什么是this?
this关键字是一个非常重要的语法点。this可以用在构造函数之中,表示实例对象。除此之外,this还可以用在别的场合。但不管是什么场合,this都有一个共同点:它总是返回一个对象。简单说,this就是属性或方法“当前”所在的对象。
this.name
上面代码中,this就代表name属性当前所在的对象。
由于对象的属性可以赋给另一个对象,所以属性所在的当前对象是可变的,即this的指向是可变的。
只要函数被赋给另一个变量,this的指向就会变。
为什么要有this?
JavaScript 语言之所以有 this 的设计,跟内存里面的数据结构有关系。
var obj = { a: 5 };
上面的代码将一个对象赋值给变量obj。JavaScript 引擎会先在内存里面,生成一个对象{ a: 5 },然后把这个对象的内存地址赋值给变量obj。也就是说,变量obj是一个地址(reference)。后面如果要读取obj.a,引擎先从obj拿到内存地址,然后再从该地址读出原始的对象,返回它的a属性。
原始的对象以字典结构保存,每一个属性名都对应一个属性描述对象
绑定this的方法
Function.prototype.call()
函数实例的call方法,可以指定函数内部this的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数。
var obj = {};
var f = function () {
return this;
};
f() === window // true
f.call(obj) === obj // true
Function.prototype.apply()
apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数,使用格式如下。
func.apply(thisValue, [arg1, arg2, ...])
apply方法的第一个参数也是this所要指向的那个对象,如果设为null或undefined,则等同于指定全局对象。第二个参数则是一个数组,该数组的所有成员依次作为参数,传入原函数。原函数的参数,在call方法中必须一个个添加,但是在apply方法中,必须以数组形式添加。
Function.prototype.bind()
bind()方法用于将函数体内的this绑定到某个对象,然后返回一个新函数。
var a = new Date();
a.getTime() // 1481869925657
var x = a.getTime;
x() // Uncaught TypeError: this is not a Date object.
上面代码中,我们将a.getTime()方法赋给变量x,然后调用x()就报错了。这是因为getTime()方法内部的this,绑定Date对象的实例,赋给变量x以后,内部的this已经不指向Date对象的实例了。