Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
试图理解JavaScript中原型的意义_Javascript_Oop_Class_Prototype - Fatal编程技术网

试图理解JavaScript中原型的意义

试图理解JavaScript中原型的意义,javascript,oop,class,prototype,Javascript,Oop,Class,Prototype,我意识到这已经被问了几百次了,然而,我似乎无法理解JavaScript中的“为什么”原型的概念,就像模仿类一样(是的,我知道JavaScript是一种基于原型的语言——我收集了很多) 像许多其他努力使JavaScript成为我日常使用的语言的人一样,我习惯了常规的OOP类风格,就像我在Java中玩过的那样(在ActionScript和PHP中使用类)。然而,虽然我认为我理解原型是如何工作的,但我似乎无法理解为什么需要它们 下面是我目前如何理解JavaScript原型的示例脚本: var Appl

我意识到这已经被问了几百次了,然而,我似乎无法理解JavaScript中的“为什么”原型的概念,就像模仿类一样(是的,我知道JavaScript是一种基于原型的语言——我收集了很多)

像许多其他努力使JavaScript成为我日常使用的语言的人一样,我习惯了常规的OOP类风格,就像我在Java中玩过的那样(在ActionScript和PHP中使用类)。然而,虽然我认为我理解原型是如何工作的,但我似乎无法理解为什么需要它们

下面是我目前如何理解JavaScript原型的示例脚本:

var Apple = function() {
    // An apple?
};

Apple.prototype.color = "red";

Apple.prototype.changeColor = function(new_color) {
    this.color = new_color;
};
Apple.prototype.getColor = function() {
    alert('color: '+this.color);
};

var apple1 = new Apple();
var apple2 = new Apple();
apple2.changeColor("green");
apple1.getColor();
apple2.getColor();
…我假设原型可能意味着它共享同一个对象,而不是每次只创建一个新对象-但是,显然不是这样,因为apple1和apple2都有不同的颜色(在运行上述脚本之后)

然后我写了一个更像是面向对象的脚本:

var Apple = function() {
    this.color = "red";

    this.changeColor = function(new_color) {
        this.color = new_color;
    };
    this.getColor = function() {
        alert('color: '+this.color);
    };
};

var apple1 = new Apple();
var apple2 = new Apple();
apple2.changeColor("green");
apple1.getColor();
apple2.getColor();
与预期的结果完全相同。。。为什么不推荐后一种代码?我使用原型没有问题(假设我正确使用了原型),但我需要理解“为什么”的概念


…有什么帮助吗?

prototype允许您向类添加方法和属性,它不仅会将其应用于类,还会应用于该类的任何当前对象实例

…我假设原型可能意味着它共享同一个对象,而不是每次都创建一个新对象

是的。有一个原型对象在从构造函数创建的所有实例中共享

…然而,情况显然不是这样,因为apple1和apple2都有不同的颜色(在运行上述脚本之后)

对于某些类型(例如number、boolean、null、undefined或string),当您通过
this.color
更改原型对象上存在的属性时,它将在实例上创建
color
属性。原型不受影响,因此新实例将具有原型中定义的默认颜色

如果您已更新了原型对象的属性所引用的数组或对象的成员,则会在所有实例中看到更改

…为什么不建议使用后一种代码

因为您通过创建每个新实例来构造新的相同函数,而不是通过prototype对象共享函数的一个实例


为了进一步扩展,我要指出,当使用
new
关键字以构造函数的形式调用函数时,构造函数中的
this
就是新实例。因此,您添加到此中的任何属性都将添加到实例中

var Apple = function() {
      // Here "this" is the object being constructed. As such, we're adding
      //   a property "rotten" to every instance created
    this.rotten = false;
};

   // adding a "color" property to the prototype object
Apple.prototype.color = "red";

   // set the property "color" on the instance to the value of "new_color"
Apple.prototype.changeColor = function(new_color) {
    this.color = new_color;
};
   // first check to see if this instance has its own "color" property. If so,
   //    use it. If not, look at the prototype object to see if it exists.
Apple.prototype.getColor = function() {
    alert('color: '+this.color);
};

// two new instances each have their own "rotten" property, and don't have a
//    "color" property. Both share the prototype object, so if "color" is 
//    requested, it will come from there
var apple1 = new Apple(); 
var apple2 = new Apple();

// This will add an "color" property to the "apple2" instance
apple2.changeColor("green");

// Doesn't have a "color" property, so it looks to the prototype object
apple1.getColor();

// Has a "color" property, so it uses that instead of the "color" on the prototype
apple2.getColor();

这实际上帮了大忙;非常感谢。在引用苹果.prototype.color时,我可以看到它仍然是“红色”,这再次证实了我最初关于原型引用单个对象的想法。这仍然有点令人困惑,因为我想直接将我的方法指定到。。。嗯,功能,但我想我可能已经掌握了窍门。再次感谢。@clicheName:不客气。我更新了一些信息,但听起来你已经掌握了。我理解正确吗?我觉得,它们有点像java中的静态变量和方法,在对象之间共享…@vishwanath:很抱歉耽搁了。原型对象当然是共享的。如果有人试图访问实例上不存在的属性,它将查看原型上是否存在该属性。我对Java不太熟悉,但在阅读了静态变量之后,我想说它们肯定不一样。相反,prototype是javascript的继承机制,prototype对象实际上可以是另一个类的实例,导致实例的原型链,到它的原型,到那个实例的原型,直到你到达最后。