前面说了‘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(); // peter
obj.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()); // jack
console.log(obj1.fn2()); // peter
console.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 指向的讲解,有什么问题,希望各位大佬们指点指点。
评论