2014-01-09 45 views
1

我是JavaScript的面向对象编程(来自C++领域)的新手。调用构造函数的成员函数

我想知道从构造函数调用成员函数的最佳做法。

以下是一段代码: 很明显,“initialize”是在调用“this.initialize();”之前声明的。

function Foo() { 
    this.initialize = function() { 
     alert("initialize");  
    }; 

    this.hello = function() { 
     alert("helloWorld"); 
     this.initialize(); 
    }; 

    this.initialize(); 
}; 
var f = new Foo(); 
f.hello(); 

如果我更改了以下代码,它将在“this.initialize();”时失败。

问题1这是为什么? JavaScript引擎不会首先读取对象的所有成员函数声明吗?

function Foo() { 
    this.initialize();    //failed here 
    this.initialize = function() { 
     alert("initialize");  
    }; 

    this.hello = function() { 
     alert("helloWorld"); 
     this.initialize(); 
    }; 
}; 
var f = new Foo(); 
f.hello(); 

然后我做了这样的改变。

函数“初始化”在构造上执行,但函数“hello”中调用“this.initialize()”失败。

function Foo() { 
    this.initialize = function() { 
     alert("initialize");  
    }(); 

    this.hello = function() { 
     alert("helloWorld"); 
     this.initialize();  //failed here 
    }; 
}; 

var f = new Foo(); 
f.hello(); 

问题2:是的代码的第一块从构造主叫成员函数的必由之路?

更新:

,如果我必须在使用之前定义的函数,问题3:为什么下面的代码工作?

function Foo() { 
    this.hello = function() { 
     alert("helloWorld"); 
     this.initialize(); 
    }; 
    this.initialize(); 
}; 

Foo.prototype.initialize = function() { 
    alert("initialize"); 
}; 

var f = new Foo(); 
f.hello(); 

问题4: 为什么下面的代码成功了吗? (考虑 “未来” 函数被调用后所定义)

alert("The future says: " + future()); 

function future() { 
    return "We STILL have no flying cars."; 
} 
+2

您必须在调用它之前定义函数,因此您的第二个代码将不起作用。此外,第三个(最后一个)将不起作用,因为**初始化**不是函数,因为你在末尾有'()',这是一个返回值 – Cilan

回答

1

调用从构造的方法:

var f = new Foo(); 

function Foo() { 
    this.initialize();    //failed here 

}; 
Foo.prototype.initialize = function() { 
    alert("initialize");  
}; 

执行处理:

1) All functions are created (that are defined at the root) 
2) Code is executed in order 
3) When Foo is created/constructed it executes the code. 
    It try's to run Initialize() but it doesn't find it, 
    it throws an internal exception that is caught and 
    then creates the Prototype method and executes it. 
4) If the Foo.Prototype.initialize line came BEFORE the, 
    "var f = new Foo()" then the initialize function would have existed. 

此过程发生执行的每一行。

+0

我知道这个是有效的,为什么?从字面上看,它不是在被调用的地方之后定义的函数吗? – milesma

+0

将编辑我的答案。 –

+0

执行顺序很重要,这就是为什么当你在Foo中定义Initialize()方法然后调用this.Initialize()时它就起作用了。 –

3

在第一种情况下,您在定义之前(在下一行)呼叫initialize

在第二种情况下,您将函数的返回值(在这种情况下为undefined)分配给this.initialize,因此当您稍后尝试将其作为函数调用时,会出现错误。

您可能想要进一步研究制作类结构的原型模式 - 道格拉斯克罗克福德在这方面写了很多有用的东西,对介绍性学习很有用:http://javascript.crockford.com/prototypal.html是一个好的开始。

+0

** + 1 **我有这种总是评论答案的愚蠢情况,而不是发布答案 – Cilan

+0

我通常会做同样的事情;特别是因为在没有花费更多时间的情况下在移动设备上编写好的答案就困难得多了...... – Krease

3

我的回答直列(种)

问题1,这是为什么?JavaScript引擎不会首先读取对象的所有成员函数声明吗?

不,如果它们在您的示例中定义,它们将按顺序执行,因为该方法尚不存在,它将抛出。

这种方式将是一个不同的情况下(不是OO,但是ilustrate):

function Foo(){ 
    initialize(); //This would work 
    function initialize(){ ... } //Parser defines its function first 
} 

在这种情况下,解析器不先定义函数声明,这是一个不同的情况。

函数“初始化”在构造上执行,但函数“hello”中调用this.initialize()失败。

this.initialize = function() { 
    alert("initialize");  
}(); //This executes the function! 

与上面的代码的问题是,你并没有使用该功能this.initialize,你要指定其执行的结果,在这种情况下undefined(因为里面的没有return功能)

例如,如果代码是:

this.initialize = function() { 
    return 2; 
}(); 

然后this.initialize会... 2 !! (不是功能)。

希望这会有所帮助。欢呼声

相关问题