使用原型和处理执行顺序

Using prototype and dealing with execution order

本文关键字:执行 顺序 处理 原型      更新时间:2023-09-26

我正试图真正掌握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}),但我仍在努力掌握范围和原型,以尝试处理这个问题。

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

但事实上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中没有私有成员,只有闭包。所以,是的,在'private'成员作用域之外定义的任何函数都会不能读/写它。
还需要注意的是,如果性能是一个问题,闭包在性能较差的js引擎。拥有"伪私有"成员的一个不太坏的解决方案是定义这些成员不能用Object.defineProperty()枚举
(看这里:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty)

执行顺序是你写的。"下面的一切都不相关"规则只有两个例外:变量和函数声明被提升,即你可以在上面使用(赋值,调用)它们。注意函数声明和函数表达式之间的区别。

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.

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

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

在调用任何东西之前,通常不需要访问任何东西。首先"声明"一切(构造函数、原型属性),然后实例化。