0

我正在尝试真正扎实地掌握 JavaScript,但我遇到了一个对我来说很大的问题。我习惯于使用 C 语言工作,我发现的障碍之一是处理 JavaScript 的原型功能以及何时声明函数,因为它与执行顺序有关。

例如,采用以下代码:

var construct = new Constructor(); //I can do this even if its above the declaration of the object.

construct.MyPrivilagedFunction(); //Can do this here too, even though it's above the function declaration.

construct.MyPublicFunction(); //Can't do this because it is above the function declaration.

function Constructor() {

    //Private member
    var m_Ding = "Ding!";

    //Accessible publicly and has access to private member.
    this.MyPrivilagedFunction = function() {
    console.log(m_Ding);
    }
}
Constuctor.prototype.MyPublicFunction = function() {
    //Doesn't have access to private members. This doesn't work.
    console.log(m_Ding);
}

我知道原型设计提供了更好的性能,因为函数的副本不会存储在对象的每个实例上,而是每个实例都引用同一个函数(我猜每个新实例都可以被认为是一个全新的对象类型?) . 但是,原型设计不允许我在定义函数之前使用它。此外,原型函数无法访问对象的私有成员。

这只是一个真正的问题,因为我正在处理一个项目,其中两个对象需要使用彼此的功能。如果我在代码的前面放置一个对象,它将无法访问第二个对象,因为原型函数遵循执行顺序(从上到下)。

旁注:我也知道我的对象可能应该是一个对象字面量(如 object={property:value}),但我仍在努力掌握范围和原型设计以尝试处理它现在。

4

2 回答 2

0

如果我让你好了,你的问题的根源是“两个对象需要使用彼此的功能”。

但实际上 Javascript 不是一种类型化语言:定义 TypeA,定义 TypeB,之后您可以毫无问题地使用实例:typeA 和 typeB 对象。

var Speaker = function(name) {
    this.name = name ;
};

Speaker.prototype.sayHi = function(aMate) {
   amate.listenTo(this, ' Hi ' + this.mate.name ); // no type checking performed here
                                                   // so no issue even if Listener 
                                                   // is not defined yet
};

var Listener = function(name) {
    this.name = name;
    this.knownMate = [];
};

Listener.prototype.listenTo = function (mate, words) {
    this.knownMate.push(mate);
};

var aSpeaker  = new Speaker('Joe');
var aListener = new Listener('Bobby');

aSpeaker.sayHi(aListener);

顺便说一句,您在 Javascript 中没有私有成员,只有闭包。所以是的,在“私有”成员范围之外定义的任何函数都将无法读取/写入它。
另请注意,如果性能是一个问题,则在性能较低的 js 引擎上关闭速度较慢。拥有“伪私有”成员的一个不错的解决方案是将这些成员定义为不可枚举 Object.defineProperty()
(在此处观看:
https ://developer.mozilla.org/en-US/docs/JavaScript /Reference/Global_Objects/Object/defineProperty )

于 2013-03-03T10:49:36.190 回答
0

执行顺序是你写的。“下面的一切都是无关紧要的”规则只有两个例外:变量和函数声明被提升,即您可以在上面使用(分配给,调用)它们。并注意函数声明和函数表达式之间的区别

var construct = new Constructor() //I can do this even if its above the declaration of the object.

你要说的构造函数的声明。

construct.MyPrivilagedFunction(); //Can do this here too, even though it's above the function declaration.

这里没有函数声明。特权方法是在构造函数执行期间创建的(将函数表达式分配给属性)(见上文)。

construct.MyPublicFunction(); //Can't do this because it is above the function declaration.

同样,它不是函数声明,而是函数表达式的赋值。它还没有发生,因为它在下面。

这只是一个真正的问题,因为我正在处理一个项目,其中两个对象需要使用彼此的功能。如果我在代码的前面放置一个对象,它将无法访问第二个对象,因为原型函数遵循执行顺序(从上到下)。

在调用任何内容之前,您通常不需要访问任何内容。首先“声明”所有内容(构造函数、原型属性),然后实例化。

于 2013-03-03T11:35:20.507 回答