【问题标题】:Javascript: Added function does not appear on parent objectJavascript:添加的功能不会出现在父对象上
【发布时间】:2014-10-21 12:26:14
【问题描述】:

我正在尝试理解 Javascript 中的原型继承。对此已经提出了几个问题,但它们似乎并没有解决我的困惑。

How does JavaScript .prototype work?

What is the 'new' keyword in JavaScript?

互联网上也有一些很棒的资源。

http://www.webdeveasy.com/javascript-prototype/

http://javascriptissexy.com/javascript-objects-in-detail/

当我阅读这些资源时,我认为我理解了原型继承,但是当我在浏览器控制台中尝试一些测试时,我意识到我遗漏了一些东西。

基于以下代码示例:
(1) 为什么添加的原型函数description()在父对象animal上不可见?
(2) 为什么添加了description()函数后创建的对象现在缺少原来的对象属性:namecolor? p>

例子:

创建一个简单的对象。

function animal(){
    var name;
    var colour;
 }

根据原型动物

创建两个新对象
> cat = new animal();
< animal {}
> cat.name = 'cat';
> cat.color = 'black';

> cat
< animal {name: "cat", color: "black"}

只为一个对象添加属性

> dog = new animal();
> dog.name = 'dog';
> dog.color = 'brown';
> dog.bite = 'hurts';

> dog
< animal {name: "dog", color: "brown", bite: "hurts"}


> animal.prototype.description = function(){
  console.log('A ' + this.name + ' is ' + this.color); }
< function (){
  console.log('A ' + this.name + ' is ' + this.color); }

添加一个新函数作为原型。这一切都按我的预期工作。

> animal
< function animal(){
   var name;
   var colour;
}


> dog
< animal {name: "dog", color: "brown", bite: "hurts", description: function}
> cat
< animal {name: "cat", color: "black", description: function}

这就是混乱。新功能 description 出现在现有的 dogcat 对象上,但不会出现在父对象 animal

> cat.description;
< function (){
  console.log('A ' + this.name + ' is ' + this.color); }

> cat.description();
< A cat is black 

从父 animal 创建的新对象 cow 现在只有 description 功能,但没有 name > 或 颜色

> cow = new animal();
< animal {description: function}

> cow
< animal {description: function}

编辑

根据@Quince 的回答,我又回到了浏览器,但还是一头雾水:

>animal = function(){
   this.name;
}
<function (){
   this.name;
}
>animal
<function (){
   this.name;
}
>cat = new animal();
<animal {}
>cat
<animal {}

在这种情况下,新对象 cat 似乎没有从父对象继承 name 属性。

【问题讨论】:

  • 啊,如果您将它们设置为未定义或初始值,您会看到它们function Animal(name, colour){ this.name = name; this.colour = colour; }

标签: javascript prototype


【解决方案1】:

在这个例子中

function animal(){
    var name;
    var colour;
 }

名称和颜色对动物来说是私有的,因此无法访问。

现在当你运行它时

 cat = new animal();
< animal {}
> cat.name = 'cat';
> cat.color = 'black';

您实际上并没有在动物内部设置那些私有名称和颜色属性,而是为其赋予了称为名称和颜色的新属性

当你运行以下命令时

animal.prototype.description = function(){
  console.log('A ' + this.name + ' is ' + this.color); 
}

animal 被赋予了一个名为 description 的可公开访问的函数,这就是为什么您在创建牛时可以看到它的原因,但实际上该函数不会打印任何内容,因为动物类没有名称或颜色属性。

您可以在此处选择将动物更改为

function animal(){
    this.name;
    this.colour;
 }

虽然这没有其他好处,但让您知道您可以设置动物的此属性,但您仍然需要设置它们以便描述打印任何内容。

如果想要保持私有和公开的另一个选项是使用类似于显示模块模式的方法,它允许 js 通过在返回的对象之外声明属性来保持对象的私有属性。

function Animal() {
    //private artibutes
    var name;
    var colour;
    //return publically avaliable functions/attibutes
    return {
        description: function () {
            console.log('A ' + name + ' is ' + colour);
        },

        setName: function (nameIn) {
            name = nameIn;
        },

        setColour: function (colourIn) {
            colour = colourIn;
        },
        getName: function () {
            return name;
        },

        getColour: function () {
            return colour
        }
    }
};

现在访问私有名称和颜色的唯一方法是使用这里返回的公开可用函数,这是一个在行动中展示它的小提琴http://jsfiddle.net/leighking2/fxrLpj9v/

哦,刚刚意识到我从来没有真正回答过标题中的问题,所以当你打印动物时,你看不到添加的描述函数,因为这个函数附加到原型上,打印原始的动物只是一个构造函数。使用 new Animal 创建的任何东西都将继承自 animal 的原型,这就是为什么它可以在狗和牛身上看到

【讨论】:

  • 我明白了。那么如果要继承属性,是否应该将它们定义为 this.name; 例如?
  • 是的,抱歉只是更新了答案,还会再举一个例子
  • 谢谢...我正在努力解决这个问题。我还在这里问了一个细化:stackoverflow.com/questions/26487480/…
  • 好吧,意识到我没有回答真正的问题,所以在底部做了最后一次更新,讨论为什么你在动物身上看不到添加的功能
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-21
  • 2021-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多