2011-11-18 64 views
0

我知道使用原型的一个结果是所有添加的属性和方法都将公开。这不是一个太大的问题,因为我使用命名约定来区分内部和公共接口。所以是的,一切仍然是在技术上公众。我应该在原型中添加* internal *属性吗?

难道是最好只加所有方法和属性的原型 - 甚至打算是内部的 - 而不是只增加公共方法/属性的原型,并动态地创建内部使用this.property = value构造函数内的属性。

看起来,因为无论如何一切都将公开,所以我们不妨也为原型添加内部属性。

我知道使用闭包创建私人范围。我的问题不是关于如何创建真正的私有属性(这意味着抛弃原型,因为任何这些方法都不具有内部访问权限),而是关于使用原型时的最佳实践。

function MyObjectA() { 
    this.myInternalProp_ = 5; 
    // ... 
} 

MyObjectA.prototype.myPublicProp = "Hello"; 

function MyObjectA() { 
    // ... 
} 

MyObjectA.prototype.myPublicProp = "Hello"; 
MyObjectA.prototype.myInternalProp_ = 5; 
+0

你能提供一个代码示例? –

+0

我没有看到问题是什么。你只是问你是否应该使用可用于信息隐藏的语言结构,或者如果你不应该? –

+0

@RichardJPLeGuen问题是这样的。我们是否应该避免在构造函数中动态创建新属性。我应该把所有东西都放在原型上。这种方式不会动态创建属性;也就是在原型成型之后。例如,做这个。myNewProp = value'调用我的对象的引擎模型,并且它必须重建它的隐藏类。这不是我主要关心的问题,因为我很好奇人们对一致性和维护角度的看法。 – Peter

回答

1

在原型上放置属性意味着属性不仅是公共的,而且共享。这将成为一个问题,当你的财产是一个可变类型,如Date

function MyObjectA() { } 
MyObjectA.prototype.date = new Date(2011, 10, 18); 
var obj1 = new MyObjectA(); 
var obj2 = new MyObjectA(); 
obj1.date.setDate(24); 
console.log(obj2.date); // Thanksgiving, not today 

参见Using "prototype" for variables

+0

谢谢;但不是它只是共享的初始值。在创建对象的新实例时,原型上的所有属性都将被克隆;所以当我在一个实例中设置来自原型的属性时,它不会影响其他实例,除非我设置了实际的原型对象。 – Peter

+0

@彼得 - 试试看。在您的浏览器中点击F12并将我的代码粘贴到JavaScript控制台中。你会看到这些属性确实是共享的。这是使用'prototype'的关键。如果所有东西都被克隆了,那么与定义构造函数中的所有东西没有任何区别。 – gilly3

+0

谢谢,我陷入了困境。我们只是误解对方。初始值/参考值是共享的。当我说克隆时,我的意思是浅拷贝,它是一个新变量,但它仍然指向最初在属性第一次添加到原型时创建的同一个“Date”对象。我的观点是,对实例的后续设置不会影响其他实体。 – Peter

1

您可以将它们添加到contrustor为VAR的而不是做this.something使 “私人” 瓦尔;像这样:

function MyObject() 
{ 
    this.readableVar = "yes this is readable"; 
    var notReadable = "nope, not readable"; 
}; 

var ob = new MyObject(); 
document.body.innerHTML = ob.readableVar + "<br />" + ob.notReadable; 

这些不会被共享,因此是特定于您使用new创建的实例。

使用原型继承时要记住的一件事是,每次访问不在实例内部但在原型内部的变量时,在链的每个步骤中都会执行查找操作,直到找到匹配或在未定义链的顶部返回。 重复完成后,这可能会变成开销。

希望它有助于PM5544。

+0

感谢您的快速响应。不过,我确实希望采用原型方法。我只想知道我是否应该将所有*属性放在原型上,或者只有那些旨在公开的属性。使用原型时更多的最佳实践问题。 – Peter

+0

这些概念可以一起使用,例如,您可以创建一个具有原型的构造函数,其中包含所有共享公共资源和实例中的私有资源。 但试图回答你的问题: 你放置你的变量的地方都依赖于数据模型,所以它总是一个var访问性,易用性,可维护性和性能的问题。 所以我想每个情况都不一样,需要一种不同的方法。 也许有些例子可以说明一些... – PM5544

+0

谢谢。我知道解决方案之间的关系。虽然它不是那么有用,因为原型上的方法将无法访问private * closed over *实例变量。他们将是没有特权的公共方法。我真的很喜欢你所建议的解决方案。我们试图避免的内存开销很小,这就是为什么我们要使用所有原型。说实话,我不确定这是否值得,因为我们可以使用更多的方法来根据需要分割范围。不过谢谢。 – Peter

1

我喜欢下面的模式:

function Rectangle(x,y) { 
    var _x = x, 
     _y = y; 
    this.area = function() { 
    return _x * _y; 
    } 
} 

_x和_y将是私人和面积()将被公开。

+0

谢谢,我也很喜欢!虽然我在使用原型时询问最佳实践。我们希望使用原型尽可能减少内存。 – Peter

+0

你的例子并不相同。原型属性的所有值将被所有实例共享(考虑一个类的静态值)。在第一种情况下,myInternalProp_是实例的属性(每个实例都有自己的值),在第二种情况下将被共享。 – 12000

+0

是的,这是事实。在这种情况下,构造函数不会更改初始值,但在更复杂的示例中,构造函数会设置新的* instance *特定值。我的问题更多的是一致性/最佳实践的东西;基本上,为什么只在原型上设置一些,为什么不让引擎知道所有的事情,因为无论如何它们都是公开的。如果需要的话,我仍然可以在构造函数中设置实例值。 – Peter

相关问题