# 关于 this:
普通函数中的this: 1.this 总是代表它的直接调用者(js的this是执行上下文), 例如 obj.func ,那么func中的this就是obj 2.在默认情况(非严格模式下,未使用 ‘use strict’),没找到直接调用者,则this指的是 window (约定俗成) 3.在严格模式下,没有直接调用者的函数中的this是 undefined 4.使用call,apply,bind(ES5新增)绑定的,this指的是 绑定的对象
箭头函数中的this: 箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象),而不是执行时的对象, 定义它的时候,可能环境是window; 箭头函数可以方便地让我们在 setTimeout ,setInterval中方便的使用this
有点绕, 看不懂继续往下看
# 例子:
|
|
# 现象解释:
this 指的是函数运行时所在的环境(上下文 context)。对于 obj.foo() 来说,foo 运行在 obj 环境,所以 this 指向 obj;对于 foo() 来说,foo 运行在全局环境,所以 this 指向全局环境。
# 原理:
this 设计与 JavaScript 内存的数据结构有关系, 回忆 JavaScript 数据类型的知识以及各数据类型存储的方式, 上面的例子的变种:
|
|
引用型对象将对象内容存储在 堆内存中, 地址存储在变量的栈内存中. 也就是说 obj 存储在栈内存上, 内容为一个堆内存的地址, 而堆内存存储的才是对象的真正内容. 同理 JavaScript 中函数也是一个对象, foo 也是一个堆内存地址, 函数内容存储另外的内存上.
而在 JavaScript 中, 函数内可以引用当前运行环境的变量, 函数又可以在不同的环境中运行, 那么当函数在不同环境中运行时, 如何引用当前运行环境中的变量呢, this 就是起这样的作用的, 在函数体中指代当前的运行环境, 以引用 context 中的变量.
|
|
|
|
# bind, apply 和 call
apply 和 call 都是在指定的环境中调用函数, 本质是设置函数体内的 this 对象的值, bind 是直接设置函数的 this 值.
-
apply
apply(context, arguments) context 代表运行函数的作用域, arguments 参数数组
1 2 3 4 5 6 7 8 9 10
function sum(n1, n2) { return n1 + n2; } function callSum(n1, n2) { return sum.apply(this, arguments); // return sum.apply(this, [n1, n2]); } callSum(4, 5); // 9
-
call
call(context, … ) context 代表运行函数的作用域, 剩余参数全部列出来.
1 2 3 4 5 6 7 8 9 10
window.color = "red"; var o = { color: "blue" }; function getColor() { alert(this.color); } getColor.call(this); // red getColor.call(window); // red getColor.call(o); // blue
-
bind
创建一个函数实例, 该函数实例的 this 值会绑定到传给 bind() 函数的值.
1 2 3 4 5 6 7 8 9
window.color = "red"; var o = { color: "blue" }; function getColor() { alert(this.color); } var obj = getColor.bind(o); obj(); // blue