Javascript:添加的功能不会出现在父对象上 [英] Javascript: Added function does not appear on parent object

查看:51
本文介绍了Javascript:添加的功能不会出现在父对象上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

JavaScript .prototype 是如何工作的?

JavaScript 中的new"关键字是什么?

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

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

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

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

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

示例:

创建一个简单的对象.

function Animal(){变量名;可变颜色;}

基于原型动物

创建两个新对象

<代码>>猫 = 新动物();<动物 {}>cat.name = '猫';>cat.color = '黑色';>猫<动物{名称:猫",颜色:黑色"}

只为一个对象添加一个属性

<代码>>狗 = 新动物();>dog.name = '狗';>dog.color = '棕色';>dog.bite = '疼';>狗<动物{名称:狗",颜色:棕色",咬伤:疼"}>Animal.prototype.description = function(){console.log('A' + this.name + ' is ' + this.color);}<功能 (){console.log('A' + this.name + ' is ' + this.color);}

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

<代码>>动物<功能动物(){变量名;可变颜色;}>狗<动物{名称:狗",颜色:棕色",咬伤:疼",描述:功能}>猫<动物{名称:猫",颜色:黑色",描述:功能}

这是混乱.新函数描述出现在现有的对象上,但没有出现在父对象动物

<代码>>猫.描述;<功能 (){console.log('A' + this.name + ' is ' + this.color);}>猫描述();<猫是黑色的

从父动物创建的新对象cow现在只有描述函数,但没有名称> 或 颜色

<代码>>牛 = 新动物();<动物 {描述:功能}>牛<动物 {描述:功能}

编辑

根据@Quince 的回答,我回到浏览器,但还是很困惑:

>animal = function(){这个.name;}<函数(){这个.name;}>动物<函数(){这个.name;}>猫 = 新动物();<动物{}>猫<动物{}

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

解决方案

在这个例子中

function Animal(){变量名;可变颜色;}

名称和颜色是动物私有的,因此无法访问.

现在当你运行这个

 cat = new Animal();<动物 {}>cat.name = '猫';>cat.color = '黑色';

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

当您运行以下内容时

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

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

您在这里的选项是将动物更改为

function Animal(){这个.name;这个颜色;}

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

如果想让事物保持私有和公开,另一种选择是使用类似于揭示模块模式的东西,该模式允许 js 通过在返回的对象之外声明属性来保持对象的私有属性.

function Animal() {//私有协议变量名;可变颜色;//返回公开可用的函数/属性返回 {描述:函数(){console.log('A' + name + ' is ' + colour);},setName: 函数 (nameIn) {名称 = 名称输入;},设置颜色:函数(颜色输入){颜色 = colorIn;},获取名称:函数(){返回名称;},获取颜色:函数(){返回颜色}}};

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

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

I am trying to understand the prototype inheritance in Javascript. There have been several questions already asked on this, but they do not seem to address the confusion I am having.

How does JavaScript .prototype work?

What is the 'new' keyword in JavaScript?

There are also some great resources on the internet.

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

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

When I read those resources, I think I understand prototypical inheritance, but when I try some tests in the browser console I realise I am missing something.

Based on the code example below:
(1) why is the added prototype function description() not visible on the parent object animal ?
(2) why is an object created after the description() function is added now missing the original object attributes: name and color?

Example:

Create a simple object.

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

Create two new objects based on the prototype animal

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

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

Add an attribute to one object only

> 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); }

Add a new function as a prototype. This all works as I expected it to.

> 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}

Here is the confusion. the new function description appears on both of the existing dog and cat objects, but it does not appear on the parent object animal

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

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

A new object cow created from the parent animal now has only the description function, but not the name or color

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

> cow
< animal {description: function}

EDIT

Based on @Quince's answer, I went back to the browser, but am still confused:

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

In this case the new object cat doesn't seem to inherit the name property from the parent.

解决方案

in this example here

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

name and colour are private to animal and as such can not be accessed.

now when you run this

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

you are actually not setting those private name and colour attributes inside animal you are giving it new attributes called name and colour

when you run the following

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

animal is being given a publicly accessible function called description which is why you can see it when you create a cow, but actually this function will not print anything yet as the animal class does not have a name or color attribute.

options you have here are to change animal to

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

although this gives no advantages other letting you know you can set this attributes of the animal, you will still need to set them in order for description to print anything.

Another option if wanting to keep things private and public is to use something along the lines of the revealing module pattern which allows js to keep attributes private to an object by declaring them outside of the object you return.

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
        }
    }
};

now the only way to access the private name and color is to use the publicly available functions returned here is a fiddle showing it in action http://jsfiddle.net/leighking2/fxrLpj9v/

Oh and just realized i never actually answered the question in the title, so when you print animal you do not see the added description function as this function is attached to the prototype, animal when printed raw is just a constructor. Anything created using new Animal will inherit from animal's prototype which is why it can be seen in dog and cow

这篇关于Javascript:添加的功能不会出现在父对象上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆