前面说了‘call'、’apply‘ 、’bind‘,它们的作用就是用来改变 this 指向的,但是有一些小伙伴还不是特别了解 this,那下面就详细的讲讲吧。
在绝大多数情况下,函数的调用决定了 this 的值(运行时绑定),this 不能在执行期间被赋值,并且在每次函数被调用时 this 的值也可能会不同。(来自 MDN)
对于 this 其实最重要的是记住,最后调用它的那个对象。
下面来看看 this 的 5 种绑定吧:
默认绑定(严格/非严格模式)
隐式绑定
显式绑定
箭头函数绑定
new 绑定
默认绑定(严格/非严格绑定)
// 严格格式'use strict';function fn() { console.log(this);}fn(); // undefined
// 非严格模式function fn() { console.log(this); }fn(); // window
// 不过严格模式中只是调用函数是不受影响的(function () {'use strict'; fn(); // window})();
复制代码
隐式绑定
var myName = ’jack';function fn() { console.log(this.myName);}fn(); // jack
var obj = { myName:'peter', objFn:fn}
obj.objFn(); // peter
复制代码
显式绑定
var myName = 'jack';function fn(){ console.log(this.myName);}fn(); // jack
var obj = { myName: 'peter'}
fn.call(obj); // 'peter'
复制代码
箭头函数绑定
先来看看使用箭头函数时的几个注意点:
箭头函数没有自己的 this 对象
不可以当作构造函数,也就是不可以对箭头函数使用 new 命令,不然会报错
不可以使用 arguments 对象,可以使用 rest 参数代替
不可以时用 yield 命令,所以箭头函数不能用作 Generator 函数
这里我们就重点关注箭头函数没有自己的 this 对象这个点
// 看看这里例子var myName = 'jack';var obj = { myName: 'peter', objFn1: function (){ console.log(this.myName); }, objFn2:() => console.log(this.myName)}
obj.objFn1(); // peterobj.objFn2(); // jack
复制代码
前面也说了 this 总是指向调用该函数的对象,但是箭头函数却是一个例外。因为箭头函数本身时没有 this 对象的,所以箭头函数的 this,是指向外层作用域的,上面例子既是全局作用域。
我们通过下面的例子来看看这个外层作用域怎么理解比较好
var myName = "jack";var obj1 = { myName: "peter", fn1: () => this.myName, fn2: function () { return this.myName; }, fn: function () { return () => this.myName; },};
console.log(obj1.fn1()); // jackconsole.log(obj1.fn2()); // peterconsole.log(obj1.fn()()); // peter
复制代码
首先箭头函数是没有 this 的,然后我们看看 obj.fn()此时的 this 是不是指向了 obj,接着返回一个箭头函数,再来看看这句话,箭头函数的 this 是指向外层作用域的。
new 绑定
当一个函数用作构造函数时(使用new关键字),它的this被绑定到正在构造的新对象。
// 看例子var myName = 'jack';function Fn(name) { this.myName = name;}
var o = new Fn('pater'); // o和Fn('peter')调用中的this进行绑定console.log(o.myName); // peter
复制代码
上面就是对 this 指向的讲解,有什么问题,希望各位大佬们指点指点。
评论