试图模拟node.js上的function.bind()

我正在使用节点v0.10.28

我一直在试图模拟函数的bind()方法作为函数的原型,我遇到了一个奇怪的问题。

 Function.prototype.bind = function() { var obj = arguments[0], argumentsArray = [], self = this; // since arguments is an object and we can't call .splice() on it for(var i in arguments) { argumentsArray.push(arguments[i]); } argumentsArray.splice(0,1); // The following throws error when running via node, works fine on browser //console.log(argumentsArray); return function() { return self.apply(obj,argumentsArray); } }; function sum(y,z) { return this.x + y + z; } var obj = { x : 8}, f, value; f = sum.bind(obj,1,2); value = f(); console.log(value); 

请参考这个小提琴 ,当我通过节点( node demo.js )运行它有一些奇怪的行为。 请参阅小提琴中的注释console.log(argumentsArray) ,取消注释,将其保存在文件中并通过节点运行将会出现以下错误:

 TypeError: Object #<Object> has no method 'log' 

另外最后的console.log(value)在通过节点运行时不会在控制台上打印任何内容。 在浏览器上似乎也完美地工作。

有什么我丢失,或节点不允许在原型函数定义或任何其他内部console.log()

我在这里先向您的帮助表示感谢。

这是因为console模块将其所有方法绑定到它自己(请参阅源代码 )。 这是为了你可以做的事情,如:

 var log = console.log; log('something'); 

console模块将在第一次使用时初始化。 所以在线

 // The following throws error when running via node, works fine on browser console.log(argumentsArray); 

node将尝试初始化console模块,然后调用log方法。 在模块初始化过程中,它会尝试将log方法绑定到它自己,并作为结果 – 将再次调用你的方法bindconsole模块将被视为已初始化,并且节点将尝试调用其log方法。 但实际上当时console没有初始化。 所以错误将被抛出。

PS

更简单的实现你正在做的事情:

 Function.prototype.bind = function(context) { var args = [].slice.call(arguments, 1); var self = this; return function() { return self.apply(context, args.concat([].slice.call(arguments))); }; };