学习需要静下心来,认真的研究一个问题。

为什么要有this ?

var f = function () {
  console.log(x);
}

这里有个函数,内部使用了一个变量,这个变量由函数的运行环境提供。

现在问题就来了,由于函数可以在不同的运行环境执行,所以需要有一种机制,能够在函数体内部获得当前的运行环境(context)。所以,this就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。

例题:

var f = function () {
  console.log(this.x);
}

var x = 1;
var obj = {
  f: f,
  x: 2,
};

// window 环境执行
f() // 1

// obj 环境执行
obj.f() // 2

有哪些运行环境呢?

在实际应用中,this的运行环境(也就是指向)大致可以分为下面4种:

  1. 作为 window 的环境   a()
  2. 作为 对象 的环境 obj.a()
  3. 作为 构造函数 的环境  var b = new a();
  4. function.prototype.call或function.prototype.apply 环境下
  5. 作为 箭头函数 环境 (ES6)

下面是分别概括。

作为 window 的环境

在严格模式下绑定到 undefined,否则绑定到全局对象。

作为 对象 的环境

哪个函数调用就指向到那个对象上。

作为 构造函数 的环境

指向到新创建的对象,注意:显示return函数或对象,返回值不是新创建的对象,而是显式返回的函数或对象。

call 或者 apply( 或者 bind)

  1. 严格模式下,指向到指定的第一个参数。
  2. 非严格模式下,null和undefined,指向全局对象(浏览器中是window)
  3. 其余值指向被new Object()包装的对象。

ES6 中的箭头函数

箭头函数内没有this,箭头函数的this是父级函数的this

不会使用上文的四条标准的绑定规则, 而是根据当前的词法作用域来决定this, 具体来说, 箭头函数会继承外层函数,调用的 this 绑定( 无论 this 绑定到什么),没有外层函数,则是绑定到全局对象(浏览器中是window)。 这其实和 ES6 之前代码中的 self = this 机制一样。

其他环境

DOM事件函数:一般指向绑定事件的DOM元素,但有些情况绑定到全局对象(比如IE6~IE8的attachEvent)。

一定要注意,有些调用可能在无意中使用普通函数绑定规则。 如果想“ 更安全” 地忽略 this 绑
定, 你可以使用一个对象, 比如ø = Object.create(null), 以保护全局对象。

考点:

面试官考察this指向就可以考察new、call、apply、bind,箭头函数等用法。从而扩展到作用域、闭包、原型链、继承、严格模式等。这就是面试官乐此不疲的原因。

小小沧海:一道常被人轻视的前端JS面试题
从这两套题,重新认识JS的this、作用域、闭包、对象

扩展

文章出处 点击查看