试图模拟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
方法绑定到它自己,并作为结果 – 将再次调用你的方法bind
。 console
模块将被视为已初始化,并且节点将尝试调用其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))); }; };