【问题标题】:Accessing to $this in a inherited function在继承的函数中访问 $this
【发布时间】:2018-02-23 16:22:40
【问题描述】:

我无法弄清楚这里发生了什么。 我知道你必须时不时地将“this”显式绑定到一个函数才能访问它

myclass: {
    test: function(){
        console.log(this.property);
    }.bind(this);
}

我有两个对象fatherchild,我将它们扩展为合并所有属性。我将 $.extend 与“true”一起使用,以获得深层副本并使用全新的对象,以免修改原始对象。

var father = {

    mydata: {
        age: 49
    },

    mymethods: {
        showMyAge: function() {
            console.log(this.mydata.age);
        }
    }
};

var child = {
};

var obj = $.extend(true, {}, father, child);

obj.mymethods.showMyAge();

输出是

Uncaught TypeError: Cannot read property 'age' of undefined

好的,我说。这是绑定(这个)的东西。非常简单。 所以,我尝试添加 bind(this)

var father = {

     /*...*/

    mymethods: {
        showMyAge: function() {
            console.log(this.mydata.age);
        }.bind(this)
    }
};

再次

Uncaught TypeError: Cannot read property 'age' of undefined

我试过了

obj.mymethods.showMyAge().bind(obj);

同样的错误。 然后我发现,如果我把父亲的方法平了一层就行了!

var father = {

    /*...*/

    mymethods: {
        /* moved showMyAge method from here ... */
    }

    /* to here */
    showMyAge: function() {
        console.log(this.mydata.age);
    }
};

输出正确

49

为什么会这样?当然,这对我来说不是解决方案,因为我有一个非常复杂的对象,其中包含子对象,包含方法。

提前谢谢你。

【问题讨论】:

  • 因为如果你调用obj.mymethods.showMyAge(),那么this === obj.mymethodsobj.mymethods.mydata.age就不存在了。
  • “我知道你必须不时将“this”显式绑定到一个函数才能访问它”虽然这句话在技术上是正确的,但声明是感觉太不对了拜托,那里有大约一万亿篇文章在 JS 中解释 this。请去阅读其中的一些

标签: javascript object inheritance


【解决方案1】:

这样使用: obj.mymethods.showMyAge.call(obj);obj.mymethods.showMyAge.apply(obj);

apply 使用参数作为数组:yourFunction.apply(valueForThis, arrayOfArgs);

call 要求列出参数:yourFunction.call(valueForThis, arg1, arg2, ...,argN);

【讨论】:

  • 感谢您的回答。这是正确的,不幸的是不适合我,因为(除了示例) showMyAge 函数不是从外部调用的,而是从 granpa 类内部调用的!所以在那一点上我没有最终的对象来使用“调用”或“应用”。无论如何,这在示例中并不清楚。所以你的答案是正确的。
【解决方案2】:

将您的对象包装在 IIFE(立即调用函数表达式)中。这会在闭包中创建一个私有变量 (that)。然后你可以引用that 作为你的父对象。

var father = (function() {
  var that = {
    mydata: {
        age: 49
    },

    mymethods: {
        showMyAge: function() {
            console.log(that.mydata.age);
        }
    }
  };
  return that;
})();

【讨论】:

  • 感谢您的回答。这是正确的,但它不处理与 $.extend 合并的属性的层次结构。例如,只需将 add mydata: {age: 20} 添加到“child”类。它将打印“49”(父亲的年龄),因为在我看来,使用 IIFE 解决方案的对象仍然是分开的,并且属性没有合并以实现我需要的正确层次结构和正确的覆盖。
猜你喜欢
  • 2019-03-18
  • 1970-01-01
  • 2017-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多