我正在学习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.
我在玩它时发现了原型的这个新方面。
private
的不同实例之间共享B
属性?private
属性在两个实例中都具有独立存在性?但是原始属性没有变化,但getter / setter是通过原型定义的。B.prototype = new A();
B.prototype = (new A()).constructor.prototype
答案 0 :(得分:1)
原型设计的秘诀(解释了所有这些)是 B
的每个实例共享相同的原型,即原型不复制到新的B
的实例。当您激活任何 B
实例的原型函数时,您实际上一直在运行相同的函数。这就是为什么"私人"变量被复制(实际上它没有复制,你只是一直引用相同的变量)。 "非专用"变量的行为相同,但关键字this
指的是当前的"持有者"功能。这就是为什么在原型中调用this
给我们一种幻觉,原型方法实际上是一个对象的方法。事实并非如此。
通过实例进行原型设计被认为是不好的做法,因为实例可能具有更多或更少的属性,具体取决于它们何时被调用以及何时进行原型设计。原型主要通过文字对象创建或扩展其他对象的原型来定义。
最后:在某些情况下,原型设计可能会被解释为单身。
答案 1 :(得分:1)
因为您继承了锁定到特定闭包的特定实例。数据归 闭包而不是对象。对象的变量和属性之间存在巨大差异。
此处根本不使用var private
。当setPrivate()
在此时创建属性时。
由于闭包和对象模型之间存在误解,这不是偶然的。你也可以做到的 以更加谨慎和清晰的方式:使用简单的对象文字。
不同之处在于,在第一个中您获得了一个新对象,而在第二个中您获得了A.prototype === B.prototype
所以如此修改
一个人会修改另一个,因为他们引用同一个对象。
对象继承自其他对象
这是一个很好的资源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中定义的私有对于闭包范围丢失,就像从未定义过一样。