侧边栏壁纸
  • 累计撰写 225 篇文章
  • 累计创建 275 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

JavaScript中this的指向

DGF
DGF
2017-05-22 / 0 评论 / 0 点赞 / 16 阅读 / 0 字

this 的指向规则

this 的指向取决于函数的调用方式,总结如下:

  1. 有所属对象时:指向所属对象
  2. 无所属对象时:严格模式下指向 undefined,非严格模式下指向全局对象(浏览器中是 window,Node.js 中是 global
  3. new 实例化后:指向新对象
  4. 通过 applycallbind:指向绑定的对象

1. 函数有所属对象时:指向所属对象

var myObject = { value: 100 };

myObject.getValue = function () { 
    console.log(this.value); // 输出 100
    console.log(this);       // 输出 { value: 100, getValue: [Function] }
    return this.value;
};

console.log(myObject.getValue()); // => 100

分析
getValue 函数属于 myObject 对象,并由 myObject 调用,因此 this 指向 myObject

2. 函数没有所属对象:严格模式与非严格模式行为不同

"use strict";
var foo = function () {
    console.log(this); // 严格模式下输出 undefined
};
foo();

var fooNonStrict = function () {
    console.log(this); // 非严格模式下输出全局对象 window
};
fooNonStrict();

分析

  • 在严格模式下,独立调用函数时,this 指向 undefined
  • 在非严格模式下,this 指向全局对象。
var myObject = { value: 100 };

myObject.getValue = function () { 
    var foo = function () {  
        console.log(this.value); // 严格模式下报错,非严格模式下为 undefined
        console.log(this);       // 严格模式下为 undefined,非严格模式下为全局对象
    };  
    foo();  
    return this.value;
};

console.log(myObject.getValue()); // => 100

补充
可以通过使用箭头函数将内部函数的 this 固定为外部函数的 this

myObject.getValue = function () { 
    var foo = () => {  
        console.log(this.value); // 输出 100
    };  
    foo();  
    return this.value;
};
console.log(myObject.getValue()); // => 100

箭头函数不绑定自己的 this,而是继承自外部作用域。

3. new 实例化后:指向新对象

var SomeClass = function() { 
    this.value = 100;
};

var myCreate = new SomeClass(); 
console.log(myCreate.value); // 输出 100

补充
如果构造函数显式返回一个对象,this 会指向返回的对象;否则仍指向实例化对象。

function SomeClass() {
    this.value = 100;
    return { anotherValue: 200 };
}
var instance = new SomeClass();
console.log(instance.value);       // undefined
console.log(instance.anotherValue); // 200

4. 通过 applycallbind:指向绑定的对象

var myObject = { value: 100 };

var foo = function() { 
    console.log(this);
};

foo();                  // 非严格模式下输出全局对象 window,严格模式下输出 undefined
foo.apply(myObject);    // 输出 { value: 100 }
foo.call(myObject);     // 输出 { value: 100 }

foo.apply();            // 参数为空时,非严格模式下指向全局对象,严格模式下为 undefined
foo.call();             // 同上

var newFoo = foo.bind(myObject);
newFoo();               // 输出 { value: 100 }

补充
applycall 允许传入多个参数:

var sum = function (a, b) {
    console.log(this); 
    return a + b;
};
console.log(sum.apply(myObject, [10, 20])); // => 30
console.log(sum.call(myObject, 10, 20));    // => 30

补充:方法调用中的 this 丢失问题

当对象方法赋值给其他变量或作为回调函数时,this 的指向可能会丢失:

var myObject = {
    value: 100,
    getValue: function () {
        console.log(this.value);
    }
};

var fn = myObject.getValue;
fn(); // 非严格模式下输出 undefined(严格模式下报错)

可以使用 bind 修复:

var boundFn = myObject.getValue.bind(myObject);
boundFn(); // 输出 100

总结

  • this 的指向依赖调用方式,非定义方式。
  • 严格模式与非严格模式会导致 this 行为不同。
  • 使用箭头函数、bindapplycall 可以显式修改 this 的指向。
0

评论区