了解javascript原型

时间:2012-06-26 19:23:55

标签: javascript prototype-programming

我正在学习JS Prototype。

如果我从某个其他构造函数(B)的实例设置构造函数(A)的原型,那么该实例(B)是否会在A中引入共享属性?

示例1

function A(){ 
    var private = '';

    this.getPrivate = function(){ 
        return private
    }; 

    this.setPrivate = function(_private){ 
        private = _private; 
    }; 
}

function B(){};

B.prototype = new A();

b1 = new B();
b2 = new B();

b1.setPrivate(new Date());
b2.getPrivate(); // Here `private` is behaving as singleton property. Why?

示例2

function A(){ 
    var private = '';
}

A.prototype.getPrivate = function(){ 
    return this.private
}; 

A.prototype.setPrivate = function(_private){ 
    this.private = _private; 
}; 

function B(){};

B.prototype = new A();

b1 = new B();
b2 = new B();

b1.setPrivate(new Date());
b2.getPrivate(); // This time private is not singleton property.

我在玩它时发现了原型的这个新方面。

  • 在示例1中,为什么在private的不同实例之间共享B属性?
  • 在示例2中,为什么private属性在两个实例中都具有独立存在性?但是原始属性没有变化,但getter / setter是通过原型定义的。
  • 可以将示例1视为单例属性的实现吗?
  • 通过实例进行原型设计并通过原型进行原型设计,有什么区别?例如
    B.prototype = new A();
    B.prototype = (new A()).constructor.prototype
  • 原型制作的完整秘诀是什么?

4 个答案:

答案 0 :(得分:1)

原型设计的秘诀(解释了所有这些)是 B的每个实例共享相同的原型,即原型复制到新的B的实例。当您激活任何 B实例的原型函数时,您实际上一直在运行相同的函数。这就是为什么"私人"变量被复制(实际上它没有复制,你只是一直引用相同的变量)。 "非专用"变量的行为相同,但关键字this指的是当前的"持有者"功能。这就是为什么在原型中调用this给我们一种幻觉,原型方法实际上是一个对象的方法。事实并非如此。

通过实例进行原型设计被认为是不好的做法,因为实例可能具有更多或更少的属性,具体取决于它们何时被调用以及何时进行原型设计。原型主要通过文字对象创建扩展其他对象的原型来定义。

最后:在某些情况下,原型设计可能会被解释为单身。

答案 1 :(得分:1)

  1. 因为您继承了锁定到特定闭包的特定实例。数据归 闭包而不是对象。对象的变量和属性之间存在巨大差异。

  2. 此处根本不使用var private。当setPrivate()在此时创建属性时。

  3. 由于闭包和对象模型之间存在误解,这不是偶然的。你也可以做到的 以更加谨慎和清晰的方式:使用简单的对象文字。

  4. 不同之处在于,在第一个中您获得了一个新对象,而在第二个中您获得了A.prototype === B.prototype所以如此修改 一个人会修改另一个,因为他们引用同一个对象。

  5. 对象继承自其他对象

  6. 这是一个很好的资源https://developer.mozilla.org/en/JavaScript/Guide/Details_of_the_Object_Model

答案 2 :(得分:1)

  

在示例1中,为什么私有属性在不同实例之间共享   B?

是的,他们

  

在示例2中,为什么私有财产在两者中都有独立存在   实例?然而,原始财产没有变化但是   getter / setter是通过原型定义的。

因为每个实例都独立于其他实例。如果这不是您想要的,请使用 object literal 表示法来创建您的课程。

  

可以将示例1视为单例属性的实现吗?

否,因为singleton总是返回相同的对象实例。这与您的第二个问题有关,其中每个实例都是独立的。可以从第一个示例中创建该类的许多实例。要创建单例,存在单例或模块模式,它使用自动调用函数和分组运算符,例如在()中包装函数。

  

通过实例进行原型设计并通过原型进行原型设计,具体是什么   区别? e.g。

使用constructor,可以确保子类构造函数和父类之间没有混淆。扩展父类时的概念是相同的,在子类中,您在子类的构造函数中构造父类。

  

原型制作的完整秘诀是什么?

浏览各种JS Ninja博客的好文章。我喜欢:

这是一篇好文章:

答案 3 :(得分:1)

在示例1中,您使用闭包范围来引用私有。由于A仅被实例化一次,因此定义了它的一个实例。

在示例2中,this.private不引用函数A中的private实例。事实上,由于您使用单词“this”,它指的是对象的“this”。因此,this.private或者意味着b1.private或b2.private,具体取决于函数。在示例2中,函数A中定义的私有对于闭包范围丢失,就像从未定义过一样。