【问题标题】:call() not working for object created from function contructorcall() 不适用于从函数构造函数创建的对象
【发布时间】:2019-11-30 15:04:38
【问题描述】:

我在 JS 中创建了一个名为 House 的构造函数。

function House(color, floor, location){
    this.color = color;
    this.floor = floor;
    this.location = location;    
}

使用这个原型,我又创建了两个名为myHousemyOldHouse 的对象。

var myHouse = new House('brick red', '1st floor', 'saltlake');
var myOldHouse = new House('Yellow', '2st floor', 'Koikhali');

然后我在myHouse 对象中添加了一个名为address 的新方法。

myHouse.address = function(address){
   this.address = address;
   console.log('My address is '+this.address); 
}

现在我想将此方法添加到myOldHouse 对象以及使用调用函数。

myHouse.address.call(myOldHouse, '2G');

但是当我打电话给myOldHouse.address() 时,它显示错误。

【问题讨论】:

  • 因为在您的地址函数中,您将地址设置为参数,然后您运行调用,但地址值不再是函数。

标签: javascript object constructor prototype call


【解决方案1】:

Call 在方法中调用时(在您的情况下为address)只是告诉方法应该运行的范围。当传递 myOldHouse 时,在地址方法中,this 关键字指的是 myOldHouse 对象。所以现在 myOldHouse.address 必须打印出“2G”。在您的情况下,您正在访问此处的对象无法访问的方法。根本原因是方法address没有在两个对象之间共享,即myHouse和myOldHouse。您已经从 House 函数创建了这些对象,这意味着这两个将有权访问与 House 关联的所有属性。在您的示例中,您已将 address 方法与 myHouse 相关联,这限制了它对创建的对象的访问来自myHouse 函数。

例如:

var myHouseChild = new myHouse(...);

现在,myHouseChild 对象将可以访问HousemyHouse 函数的属性。

为了使 address 方法适用于 myOldHouse,您必须在 House 函数的原型中设置它,以便在它的对象之间共享它。

比如,House.prototype.address = () => {};

请参阅this 答案以了解new 关键字的内部工作原理。

【讨论】:

  • 谢谢。我只是想知道这个原因。
【解决方案2】:

我喜欢你的方法,这是传统的方法。请使用 setAddress 或类似的东西。

错误: - 您不能在同一级别上拥有同名的方法和变量。 调用你的 setter 函数 setAddress。 - 不要在对象(类的实例)上附加新方法,直接在类上执行。 试试这个:

function House(color, floor, location) {
   
    this.color = color;
    this.floor = floor;
    this.location = location;    
    this.address = "";
}

Address = function( color, floor, location , address) {
   House.call(this, color, floor, location);
   this.address = address;
   console.log('My address is '+this.address + " color is: ", this.color); 
};

var myHouse = new Address('brick red', '1st floor', 'saltlake', "country1");
var myOldHouse = new Address('Yellow', '2st floor', 'Koikhali', "country2");

// myHouse.setAddress ('new address');

这种类定义方式并不奇怪或愚蠢。你总是可以把你的类放在一个文件中,以确保一切都清楚。

传统的类定义将防止旧版本浏览器出现任何错误,并且仍然适用于所有现代网络导航器。

【讨论】:

  • 我尝试了你的解决方案,但得到了 Uncaught TypeError: Cannot set property 'setAddress' of undefined at script.js:27
  • 我更新了答案。我必须说大错误是将方法附加到您需要在课堂上执行的对象(类的实例)。
  • 我知道,我写代码的方式并不常见。但在这里我试图用调用方法来从另一个对象借用方法。我的目标是应用 call()。不要使用原型创建方法。
猜你喜欢
  • 1970-01-01
  • 2013-09-24
  • 2013-09-27
  • 2013-10-30
  • 2012-02-05
  • 1970-01-01
  • 1970-01-01
  • 2019-07-25
相关资源
最近更新 更多