我对this的理解(JavaScript)

注意:this是在函数被调用的时候发生的绑定,它指向什么完全取决于在哪里被调用。

在严格和非严格模式下,this的指向有所不同

function f1() {
  return this;
}

// In a browser:
f1() === window; // true 

// In Node:
f1() === global; // true

//严格模式如下:
function f2() {
  'use strict'; // see strict mode
  return this;
}

f2() === undefined; // true

那么在函数在执行过程中调用位置如何决定this的绑定对象?
有四条规则

默认绑定

就是,常用的函数调用。

如上f1、f2函数的调用,都采用【默认绑定】。绑定到全局对象window或者global上。

隐式绑定

就是,对象的方法调用。如果说函数的调用位置有上下文对象,或者说被某个对象拥有或者包
含,那就是隐式绑定。

function foo() {
	console.log( this.a );//this指向obj对象
}
var obj = {
	a: 2,
	foo: foo
};
obj.foo(); // 2

var obj1 = 

当含有this的方法赋值给变量,然后被调用时,会发生隐式丢失,即丢失了绑定的对象
例如:

function foo() {
	  console.log(this.a);
}
var obj = {
	  a: 2,
	  foo: foo
};
var bar = obj.foo; // 函数别名!
var a = "oops, global"; // a 是全局对象的属性
bar(); // "oops, global"

foo函数隐式绑定了obj对象,在赋值给变量bar后,被调用打印this.a结果是全局变量a的值。
隐式绑定丢失所绑定的对象后,采用默认的绑定方式,this执行全局环境

当含有this的方法应用于回调函数时,也会发生隐式丢失
没错,这种情况同样也发生在回调函数,类比“赋值给变量”。

function foo() {
	  console.log(this.a);
}
var obj = {
	  a: 2,
	  foo: foo
};
var a = "oops, global"; // a 是全局对象的属性
setTimeout( obj.foo, 100 );//oops,global

那么,上述遇到的隐式丢失该如何解决呢?这就需要说到下一个规则【显示绑定】

显示绑定

可以在某个对象上强制调用函数。或者说改变this的指向
不得不说callapplybind三个函数

这三个方法可以解决如上【隐式丢失】的问题。

new绑定

执行var o = new Foo();,new到底发生了什么?

var o = new Object();
o.[[Prototype]] = Foo.prototype;
Foo.call(o);

使用new来调用函数,或者说发生构造函数调用,则会自执行如下操作:

  1. 创建一个全新的对象
  2. 这个新对象会被执行[[原型]]连接
  3. 这个新对象会绑定到函数调用的this
  4. 如果函数没有返回其他对象,则会默认返回this,也就是这个新对象。

注意,第4点。默认返回this,也就是说可以返回其他对象。比如:

function Man(name) {
  	console.log('man', this);
 	this.name = name;
  	return {}; //函数有自己的返回对象
}
function Woman(name) {
  	console.log('woman:', this);
  	this.name = name;
}

var man = new Man('Davin');
console.log(man) // {}
var woman = new Woman('Lisa');
console.log(woman) //{name: "Lisa"}
箭头函数

在箭头函数中,this与封闭词法环境的this保持一致。在全局代码中,它将被设置为全局对象。

var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true

无论如何,foothis被设置为他被创建时的环境(在上面的例子中,就是全局对象)。这同样适用于在其他函数内创建的箭头函数:这些箭头函数的this被设置为封闭的词法环境的。如下:

// 作为对象的一个方法调用
var obj = {foo: foo};
console.log(obj.foo() === globalObject); // true

// 尝试使用call来设定this
console.log(foo.call(obj) === globalObject); // true

// 尝试使用bind来设定this
foo = foo.bind(obj);
console.log(foo() === globalObject); // true

箭头函数中this的指向并未发生变化。

参考阅读
《你不知道的JavaScript(上)》
MDN 之 this
透彻理解并掌握JavaScript的this

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青菜小王子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值