JS的this问题说明

1,460 阅读2分钟

什么是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所要指向的那个对象,如果设为nullundefined,则等同于指定全局对象。第二个参数则是一个数组,该数组的所有成员依次作为参数,传入原函数。原函数的参数,在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对象的实例了。