我只想了解javascript
或具体node.js' require()
的一种行为。我已经读过这个:
Adding new properties to constructor function without .prototype
和此:
The difference between putting functions into an object and prototyping them?
但是,如果您使用require()
http://docs.nodejitsu.com/articles/getting-started/what-is-require来创建新对象,例如:
var Ftp = require("jsftp"),
ftp = new Ftp({
host: "ftp.mywebsite.com",
});
然后说如果你稍后ftp.getPutSocket()
,它实际上是在 jsftp.js 文件中调用原始的Ftp.getPutSocket = function() {}
。
现在怎么可能?我想如果你做new Something()
,你只能打电话给Ftp.prototype.getPutSocket
。 require()
在这里做了些什么?
更新1:
所以它与require()
无关,但基本上是function.call(Ftp.prototype)
行。但是为什么这给了我错误:
http://jsfiddle.net/qhoc/7j3Vp/
var Test = function() {
console.log('aa');
}
(function() {
this.anotherTest = function() {
console.log('bb');
}
}).call(Test.prototype);
错误:
Uncaught TypeError: Cannot read property 'prototype' of undefined
我尝试做与https://github.com/sergi/jsftp/blob/master/lib/jsftp.js
相同的事情答案 0 :(得分:1)
定义getPutSocket
(https://github.com/sergi/jsftp/blob/master/lib/jsftp.js#L620)后,this
实际上是Ftp.prototype
(请参阅https://github.com/sergi/jsftp/blob/master/lib/jsftp.js#L803)。
所以它看起来根本不像Ftp.getPutSocket。它仅在Ftp.prototype
上定义。
这是失败的,因为javascript会破坏事物的顺序。首先是函数,然后是变量赋值。
然而,这可行:
function Test() {
console.log('aa');
}
(function() {
this.anotherTest = function() {
console.log('bb');
}
}).call(Test.prototype);
答案 1 :(得分:1)
您收到该错误的原因是JavaScript的variable hoisting。如果您将代码更改为:
function Test() {
console.log('aa');
}
(function() {
this.anotherTest = function() {
console.log('bb');
}
}).call(Test.prototype);
它会起作用。
原因是声明像
这样的函数之间存在一些重要的区别function F() {} // Function declaration
并且喜欢
var F = function() {} // Function expression
在第一个例子中,由于它是一个声明,F
在任何其他表达式之前被解析和评估。这就是为什么你可以做的事情:
console.log(myFun());
function myFun() {
return 'Hi there!';
}
即使您在使用之后宣布功能,它也会起作用。另一方面,如果你想写它
console.log(myFun());
var myFun = function() { // expression
return 'Hi there!';
}
它不起作用,因为var
表达式在实际使用后正在执行,因为它是一个表达式(它是赋值表达式的一部分)。
在您的示例中,当call
评估Test.prototype
时尚未分配Test
函数,这就是您获得TypeError
的原因。
关于此的更多有用的信息和见解: