Javascript:添加的功能不会出现在父对象上

时间:2014-10-21 12:26:14

标签: javascript prototype

我试图理解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()函数后创建的对象现在缺少原始对象属性:名称颜色

示例:

创建一个简单的对象。

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}

这是混乱。新功能描述出现在现有的 dog cat 对象上,但它不出现在父对象 animal < /强>

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

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

从父动物创建的新对象 cow 现在只有描述功能,但不包含名称颜色

> 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 属性。

1 个答案:

答案 0 :(得分:4)

这个例子中的

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

名称和颜色是动物专用的,因此无法访问。

现在运行此

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

你实际上并没有在动物中设置这些私人名称和颜色属性,而是给它提供了名为name和color的新属性

运行以下内容时

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

动物被赋予一个名为描述的可公开访问的功能,这就是为什么你可以在创建一个母牛时看到它,但实际上这个功能不会打印任何东西,因为动物类没有名称或颜色属性。

你在这里的选择是将动物改为

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/

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