从构造函数调用成员函数

时间:2014-01-09 03:40:51

标签: javascript

我是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();

然后我做了这样的改变。

函数“initialize”在构造时执行,但是函数“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.";
}

3 个答案:

答案 0 :(得分:3)

在第一种情况下,您在定义之前调用initialize(在下一行)。

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

您可能希望进一步研究原型模式以制作类似于类的结构 - 道格拉斯·克罗克福德在此上写了很多有用的东西,它对于入门学习非常有用:http://javascript.crockford.com/prototypal.html是一个好的开始。

答案 1 :(得分:3)

我的回答内联(种类)

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

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

这种方式不同(不是OO,而是说明):

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

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

函数“initialize”在构造时执行,但是函数“hello”中this.initialize()的调用失败。

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

上述代码的问题在于,您没有将功能分配给this.initialize,而是指定执行结果,在这种情况下undefined (因为函数内没有return

例如,如果代码是:

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

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

希望这会有所帮助。干杯

答案 2 :(得分: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.

每个执行行都会发生此过程。