JS中各this的指向
全局环境
无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this
都指向全局对象window。
console.log(this === window); // true
可以使用 globalThis
获取全局对象,无论你的代码是否在当前上下文运行。
函数(运行内)环境
在函数内部,this
的值取决于函数被调用的方式。
简单调用
下面的代码不在严格模式下,且 this
的值不是由该调用设置的,所以 this
的值默认指向全局对象。
function f1(){
return this;
}
f1() === window; // true
严格模式
在严格模式下,this
将保持他进入执行环境时的值,所以下面的this
将会默认为undefined
。
function f2(){
"use strict"; // 这里是严格模式
return this;
}
f2() === undefined; // true
所以,在严格模式下,如果 this
没有被执行环境(execution context)定义,那它将保持为 undefined
。
如果想在严格模式下返回 window
对象,需要通过作为对象的属性或方法调用该函数,即 window.f2()
改变 this 指向
改变 this
的值,用 call
或者apply
方法。
// 将一个对象作为call和apply的第一个参数,this会被绑定到这个对象。
var obj = {a: 'Custom'};
// 这个属性是在global对象定义的。
var a = 'Global';
function whatsThis(arg) {
return this.a; // this的值取决于函数的调用方式
}
whatsThis(); // 'Global'
whatsThis.call(obj); // 'Custom'
whatsThis.apply(obj); // 'Custom'
call
apply
区别 :后面传的参数形式不同
-
call
需要把实参按照形参的个数传进去 -
apply
需要传一个 argument (数组)Person.call(this, name, age); person.apply(this, [name, age]);
对象的方法
当函数作为对象里的方法被调用时,它们的 this
是调用该函数的对象。
var obj1 = {
name : "obj1",
fn1: function() {
return this;
}
};
console.log(obj1.fn1()); // obj1
this
指向与方法定义的位置无关,只与最靠近的引用有关
var obj = {};
function independent() {
return this;
}
obj.fn = independent;
console.log( obj.fn() ); // obj
构造函数
当一个函数用作构造函数时(使用new
关键字),它的this
被绑定到正在构造的新对象。
function Fn(){
this.a = 100;
}
var obj1 = new Fn();
console.log(obj1.a); // 100
构造函数里有 return
function Fn1() {
this.user = 'gg';
return {}; // return 一个空对象
}
var obj1 = new Fn1;
console.log(obj1.user); // undefined
//-------------------------------------------------------------
function Fn2() {
this.user = 'gg';
return 1; // return 一个数值
}
var obj2 = new Fn2;
console.log(obj2.user); //gg
//-------------------------------------------------------------
function Fn3() {
this.user = 'gg';
return {user: 'mm'}; // return 一个对象
}
var obj3 = new Fn3;
console.log(obj3.user); //mm
如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
作为一个DOM事件处理函数
当函数被用作事件处理函数时,它的this
指向触发事件的元素
箭头函数
阮一峰es6 : 函数体内的this
对象,就是定义时所在的对象,而不是使用时所在的对象。
var foo = ()=>this; // 全局定义箭头函数
console.log(foo()); // window
// 对象中箭头函数--------------------------------------------- this 定义的环境
var obj1 = {foo};
console.log(obj1.foo()); // window
// 对象中普通函数--------------------------------------------- this 执行的环境
var obj2 = {
name : "obj2",
foo : function(){
return this;
}
}
console.log(obj2.foo()); // obj2
如果理解成箭头函数的 this
指向定义时所处的对象,那么下面的例子就会理解错误
var obj3 = {
name : "obj3",
foo : ()=>this,
obj4 : {
name : "obj4",
foo : ()=>this
}
}
console.log(obj3.foo()); // window
console.log(obj3.obj4.foo()); // window
箭头函数里面根本没有自己的this
,而是引用外层的this
。
Nicholas C.Zakes的深入理解es6 :
如果箭头函数被非箭头函数包含,则
this
绑定指向的是最近一层非箭头函数的this
;否则,this
的值会被设置为全局对象
箭头函数的this
等同于上一层非箭头函数的this
值或者全局对象
var obj5 = {
name : "obj5",
fn1 : function(){
console.log(this);
var fn2 = ()=>this;
return fn2();
}
}
console.log(obj5.fn1()); // obj5 obj5
function foo() {
console.log(this);
return () => {
console.log(this);
return () => {
console.log(this);
return () => {
console.log(this);
};
};
};
}
var obj6 = {
name :"obj6",
foo
}
obj6.foo()()()(); // obj6 obj6 obj6 obj6
call()
apply()
bind()
方法对于箭头函数来说只是传入参数,对它的 this 毫无影响。
作者:掘金- JS中各this的指向