Javascript在引用函数到变量时等于这个

Javascript that equal this when referencing function to variable

本文关键字:于这个 变量 引用 函数 Javascript      更新时间:2023-09-26

是的,这是另一个关于将this存储在变量中的问题(that(,但我对此感到困惑:

function Constructor(){
    this.key = 'my key'
};

Constructor.prototype.start = function(){
    var that = this;
    return (function (){
        console.log(that.key)
    }());
};
foo = new Constructor;
foo.start()
bar = new Constructor;
newFoo = bar.start
newFoo()

我想既然this存储为变量,我可以在不丢失范围的情况下传递start()方法?我知道这已经经常被讨论过,但我找不到适合这种特定情况的答案。

如何在不使用Constructor.apply(this)的情况下恢复newFoo()的范围?

谢谢

我想既然它存储为变量,我可以在不丢失范围的情况下传递 start(( 方法?

否,因为您仍在使用 this 的值,就像调用 start 时一样,只是间接使用。您可以在Constructor执行此操作:

function Constructor() {
    // ...other stuff...
    var that = this;
    this.start = function(){
         console.log(that.key)
    };
    // ...other stuff...
}

(...并删除您放在原型上的那个(。

现在,您可以随心所欲地传递start; that将是调用构造函数时this具有的值。 start从调用构造函数到that变量具有持久引用

当然,代价是每个通过Constructor创建的实例都有自己的start函数副本。大多数现代JavaScript引擎都足够聪明,可以重用函数的代码(但它们需要为每个start创建单独的函数实例,这只是它们可以重用的幕后实际代码(。

您的另一种选择不是在 Constructorstart 内处理此问题,而是在其他地方提供start的副本时处理它,使用 Function#bind . Function#bind是 ECMAScript5 (ES5( 的一个特性,但它可以在较旧的引擎上填充。

例:

// Nice boring constructor with `start` on the prototype
// Note I've made the key an argument; in your code, all of them had the same key
function Constructor(key) {
    this.key = key;
}
Constructor.prototype.start = function() {
    console.log(this.key);
};
// **********
// Using it
var c1 = new Constructor("c1");
// Use it normally
c1.start();                       // "c1" as you'd expect
// Use it forgetting that `this` will change
setTimeout(c1.start, 0);          // "undefined" - doh!
// Use it via Function#bind
setTimeout(c1.start.bind(c1), 0); // "c1"

更多(在我的博客上(

  • 闭合并不复杂