何时将成员添加到原型?

时间:2016-04-14 04:57:12

标签: javascript prototypal-inheritance

在下面的代码中,

function Stack() {
    this.stac = new Array();
    this.pop = function () {
        return this.stac.pop();
    }
    this.push = function (item) {
        this.stac.push(item);
    }
}

如何确定pushpopStack类的实例成员(如上所示)还是Stack.prototype的成员?

4 个答案:

答案 0 :(得分:2)

如果你在一个类中写它,那个类的每个实例都有自己的 push pop 方法,所以你为每个实例重新定义这些方法。 如果为原型定义这些方法,则所有实例都将共享这些方法。 因此,如果需要,您可以在每个实例的运行中轻松更改这些方法。否则,您必须为每个先前创建的实例重写这些方法。 通过原型定义方法被视为一种良好做法。它更快,更好,它使继承更容易!

检查Addy Osmany - Learning JavaScript Design Patterns

如果要检查属性是来自原型还是来自实例,可以使用: instanceName.hasOwnProperty(propertyName)

在你的例子中:

function Stack() {
    this.stac = new Array();
    this.pop = function () {
        return this.stac.pop();
    }
    this.push = function (item) {
        this.stac.push(item);
    }
}

Stack.prototype.notAnOwnProperty = 12;

var stack = new Stack();

console.log(stack.hasOwnProperty('pop'));
console.log(stack.hasOwnProperty('notAnOwnProperty'));

你会得到:

true
false

JSFiddle

答案 1 :(得分:2)

构造函数内定义的属性和方法是该对象的属性。这些不在实例之间共享。

简单的规则是

构造函数内的this实例上添加的任何内容都是该实例的私有

您可以使用Object.is()来比较不同的实例是否指向相同的方法。

您的代码:

function Stack() {
    this.stac = new Array();
    this.pop = function () {
        return this.stac.pop();
    }
    this.push = function (item) {
        console.log('In push');
        this.stac.push(item);
    }
}

var stack = new Stack(),
    stack2 = new Stack();
console.log(Object.is(stack.push, stack2.push)); // false

推荐方式:

建议在原型上添加常用的共享属性和方法。这些属性和方法在对象实例之间共享。

function Stack2() {
    this.stack = new Array();
}
Stack2.prototype.pop = function () {
    return this.stack.pop();
};
Stack2.prototype.push = function (item) {
    console.log('In push');
    this.stack.push(item);
}
var stack = new Stack2(),
    stack2 = new Stack2();

console.log(Object.is(stack.push, stack2.push)); // true

答案 2 :(得分:0)

要添加@Lends答案,当您想要在另一个对象中继承该对象并在子对象中使用它们时,您还希望向该原型添加属性和方法。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Inheritance

答案 3 :(得分:0)

继承意味着可重用性,如果需要,可以通过隐藏已经编写的方法来自由覆盖功能。在上面的示例中,如果您想进一步继承(Make Parrent Object)Stack并希望为其继承的对象提供默认的pushpop功能,那么您应该放置{{在push中有1}}和pop函数。这将使继承的对象(子对象)自由使用默认的Stack.prototypepop方法或覆盖这些方法(通过声明具有相同名称的新方法)。

如需进一步参考Portotype Pattern,请关注 Prototype Pattern

以复数形式的例子解释 Using the JavaScript Prototype Pattern