require()将构造函数的函数转换为原型?

时间:2013-02-28 09:14:06

标签: javascript node.js prototype

我只想了解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.getPutSocketrequire()在这里做了些什么?

更新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

相同的事情

2 个答案:

答案 0 :(得分:1)

定义getPutSockethttps://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上定义。

更新1:

这是失败的,因为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的原因。

关于此的更多有用的信息和见解: