首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaScript原型:单个原型对象还是非原型对象?

JavaScript原型:单个原型对象还是非原型对象?
EN

Stack Overflow用户
提问于 2010-08-26 11:57:35
回答 2查看 270关注 0票数 1

我真的不太理解JavaScript原型。以下面的代码为例:

代码语言:javascript
复制
function Class(asdf) {
 if(typeof(asdf) == 'undefined') {
 } else {
  this.asdf = asdf;
 }
}
Class.prototype.asdf = "default_asdf";
Class.prototype.asdf2 = [];
Class.prototype.change_asdf = function() {
 this.asdf = "changed_asdf";
 this.asdf2.push("changed_asdf2");
}

function SubClass() {
}
SubClass.prototype = new Class("proto_class");
SubClass.prototype.constructor = SubClass;

test1 = new SubClass();
alert("test1 asdf: " + test1.asdf + " " + test1.asdf2);
test1.change_asdf();
alert("test1 asdf: " + test1.asdf + " " + test1.asdf2);
test2 = new SubClass();
alert("test2 asdf: " + test2.asdf + " " + test2.asdf2);

正如预期的那样,第一个警报打印"proto_class []“。第二个警报打印"changed_asdf changed_asdf2",这也是预期的。但是为什么第三个警报打印"proto_class changed_asdf2"?!如果原始的原型对象(新的类(“proto_class”))正在被修改,那么为什么asdf变量不保持为"changed_asdf"?如果不是,为什么asdf2数组包含"changed_asdf2"?此外,如何确保每个新的SubClass()实例都包含一个新的类()实例,就像在C++和Java中一样?

EN

回答 2

Stack Overflow用户

发布于 2010-08-30 03:33:11

那是因为你写了

代码语言:javascript
复制
SubClass.prototype = new Class("proto_class");

您正在创建Classone instance的原型。您想要的是创建一个继承其父类原型的子类。正如David Flanagan在他的JavaScript: The Definitive Guide (§99.5)中所示,您必须使用辅助函数来创建具有指定原型的新对象:

代码语言:javascript
复制
function heir(p) {
    function f(){}         // dummy constructor function
    f.prototype = p;       // specify prototype object we want
    return new f();        // create and return new object
}

(Crockford在所谓的ES5 object constructor property之后调用这个函数Object.create,但请不要这样做,就像这个can be misleading一样。)

在SubClass构造函数中,您必须对类构造函数执行call操作,并将this设置为当前对象:

代码语言:javascript
复制
function SubClass() {
    // call the parent's constructor with
    // `this` set to the current scope
    Class.call(this, "proto_class");
}

最后但并非最不重要的一点是,您只能重置Class.asdf2一次,但不能在ClassSubClass的构造函数中重置。因此,将this.asdf2 = [];添加到其中一个构造函数。

完整的代码现在为:

代码语言:javascript
复制
function heir(p) {
    function f(){}         // dummy constructor function
    f.prototype = p;       // specify prototype object we want
    return new f();        // create and return new object
}

function Class(asdf) {
    if (typeof asdf != 'undefined')
        this.asdf = asdf;
}

Class.prototype.asdf = "default_asdf";
Class.prototype.asdf2 = [];
Class.prototype.change_asdf = function() {
    this.asdf = "changed_asdf";
    this.asdf2.push("changed_asdf2");
}

function SubClass() {
    // call the parent's constructor with
    // `this` set to the current scope
    Class.call(this, "proto_class");
    this.asdf2 = [];
}

SubClass.prototype = heir(Class.prototype);
SubClass.prototype.constructor = SubClass;

test1 = new SubClass();
alert("test1 asdf: " + test1.asdf + " " + test1.asdf2);
test1.change_asdf();
alert("test1 asdf: " + test1.asdf + " " + test1.asdf2);
test2 = new SubClass();
alert("test2 asdf: " + test2.asdf + " " + test2.asdf2);
票数 1
EN

Stack Overflow用户

发布于 2010-10-20 04:11:53

这是因为asdf2Class.prototype上的可变数组。该数组由委托给该原型的所有实例共享。如果您希望每个实例都有一个单独的asdf2,则必须以某种方法将其分配给this.asdf2

请注意,您分配了this.asdf,但您从未分配过this.asdf2,您只是将其推送到现有数组中。

代码语言:javascript
复制
var house = {nice: true};
var me = {home: house};
var roomie = {home: house};

// Now roomie has a party and trashes the place.
roomie.home.nice = false;

//and how's my house?
me.home.nice === false;
// because house is shared.

本例中的house共享与问题中的asdf2共享相同。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3571940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档