新手讲解this

115 阅读2分钟

这是我参与更文挑战的第3天,活动详情查看: 更文挑战

前面说了‘call'、’apply‘ 、’bind‘,它们的作用就是用来改变this指向的,但是有一些小伙伴还不是特别了解this,那下面就详细的讲讲吧。

在绝大多数情况下,函数的调用决定了this的值(运行时绑定),this不能在执行期间被赋值,并且在每次函数被调用时this的值也可能会不同。(来自MDN)

对于this其实最重要的是记住,最后调用它的那个对象。

下面来看看this的5种绑定吧:

  1. 默认绑定(严格/非严格模式)
  2. 隐式绑定
  3. 显式绑定
  4. 箭头函数绑定
  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'

箭头函数绑定

先来看看使用箭头函数时的几个注意点:

  1. 箭头函数没有自己的this对象
  2. 不可以当作构造函数,也就是不可以对箭头函数使用new命令,不然会报错
  3. 不可以使用arguments对象,可以使用rest参数代替
  4. 不可以时用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指向的讲解,有什么问题,希望各位大佬们指点指点。