现在我用你的完整代码清楚地看到了你的错误。
在 JavaScript 中,您编写代码的方式与解析器实际读取代码的方式不同。它按照一定的顺序阅读,归纳为三组:
- 变量声明
- 函数声明
所有其他,根据它们在范围中出现的顺序。这包括
- 操作(函数调用、条件、循环等)
- 变量赋值(变量、函数表达式、原型赋值)
- 我错过的一切
例如,这段代码:
new foo();
function foo(){...}
foo.prototype.bar = function(){...};
var bar = 'baz';
实际上对解析器来说是这样的:
var bar; //variable declaration
function foo(){...}; //function declaration
//operations and assignments
new foo(); //this is foo, but no bar yet
foo.prototype.bar = function(){}; //function expressions (prototype assignment)
bar = 'baz'; //variable assignment
您可以测试以下代码以查看变量的情况,undefined
而不是在console.log()
代码中,声明在它之后。这是因为声明被“提升”而不是赋值。所以它看到变量,但看不到值。与不存在的变量进行比较以查看差异:
console.log('ndefined is:',ndefined); //undefined, sees the variable
console.log('notDefined is:',notDefined); //not defined, non-existent variable
var ndefined = 'I should be defined!!!';
现在在您的代码中,此代码:
if (_object_id) {...new NewObject(_object_id)...}
function NewObject(params) {...return this.fetchConfig(params)...}
NewObject.prototype.fetchConfig = function (id) {}
由于解析的顺序,解析器看起来像这样:
//priority 2: function declarations
//function declarations are "hoisted up"
function NewObject(params) {...return this.fetchConfig(params)...}
//priority 3: assignments and operations
//at this point, fetchConfig is not yet in the prototype
//yet your constructor uses it, hence the error
if (_object_id) {...new NewObject(_object_id)...}
NewObject.prototype.fetchConfig = function (id) {}
简而言之,该if
语句看到了您的构造函数,因为它被提升了。但是那个时候构造函数从来没有fetchConfig
。要解决此问题,请更改顺序:
function NewObject(params) {...return this.fetchConfig(params)...}
if (_object_id) {...new NewObject(_object_id)...}
NewObject.prototype.fetchConfig = function (id) {}
最佳实践是按照解析器的方式声明或操作它们。这也意味着以这种方式格式化您的代码。这样,它将消除有关代码的一些混乱。