JavaScript实例函数与原型函数

可能重复:
在JavaScript中使用'原型'与'这个'?

我对各种JavaScript函数的理解如下:

function MyObj() { this.propOne = true; this.publicInstanceFunc = function() { if (propOne) return 'public instance function'; } function privateFunc() { return 'private function only visible inside this constructor'; } } MyObj.prototype.protoFunc = function() { if (this.propOne) return 'prototype function shared amongst all instances of MyObj'; } 
  1. 这些是正确的吗?
  2. 在什么情况下应该把函数放在原型上(比如protoFunc )和构造函数(比如publicInstanceFunc )?
  3. 正在使用this正确的方式来访问原型函数内的属性?

实际上你可以通过将整个事物包装在一个自动执行的函数中来添加另一个特权级别:

 var MyObj = (function() { // scoping var privateSharedVar = 'foo'; function privateSharedFunction() { // has access to privateSharedVar // may also access publicSharedVar via explicit MyObj.prototype // can't be called via this } function MyObj() { // constructor var privateInstanceVar = 'bar'; this.publicInstanceVar = 'baz'; function privateInstanceFunction() { // has access to all vars // can't be called via this }; this.publicInstanceMethod = function() { // has access to all vars // also known as a privileged method }; } MyObj.prototype.publicSharedVar = 'quux'; MyObj.prototype.publicSharedMethod = function() { // has access to shared and public vars // canonical way for method creation: // try to use this as much as possible }; return MyObj; })(); 

只有“公共”属性可以通过this从外部访问。

出于性能的原因,你应该避免我称之为“实例”的方法:对于每一个,必须为每个MyObject实例创build一个新的函数对象,而每个“共享”方法只有一个函数对象。

这些是正确的吗?

呃。 那么这取决于你想要做什么。 在JavaScript中没有人接受实现类/实例式inheritance的规范模型。

但是这个:

  if (propOne) 

可能是一个错误,因为this.propOne是所有者对象的属性,而propOne本身是一个尚未声明的variables(默认为全局variables,但通常是错误的)。

在什么情况下应该把函数放在原型上(比如protoFunc)和构造函数(比如publicInstanceFunc)?

原型上设置的函数是所有对象共享的相同函数。 确定它属于哪个实例的唯一方法是在调用它时读取“this”。

在构造函数中为this设置的函数是每个MyObj实例的新函数。 你可以使用这个替代方法来绑定基于闭包而不是“this”的所有者对象,这可以节省写出函数绑定的东西。 这是一种不同的面向对象的风格,通常你不会混合这种基于风格的风格。

1)是的,你的代码是正确的。

2)当我想要访问在构造函数本身范围内私人定义的其他成员时,例如当你想创build特权方法时,我使用构造函数中定义的函数。

在构造函数中定义的公共函数比在对象原型中添加一个简单的函数在计算上更昂贵,但是它们也给了你更多的灵活性。

3)是的,如果该属性是公开的,则可以通过在原型扩展函数中使用this关键字来访问它,因为this是指对象的实例。

关于第二点,您扩展了原型,以便所有已经创build的对象都得到新的方法。

此外,允许您将方法添加到内置对象(如添加trim()string )。