我使用节点 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);
请参考this fiddle,当我在via节点(node demo.js
)中运行时,它有一些奇怪的行为。请参阅小提琴中注释的console.log(argumentsArray)
,取消注释,将其保存在文件中并通过节点运行会出现以下错误:
TypeError: Object #<Object> has no method 'log'
最后console.log(value)
在通过节点运行时,在控制台上不打印任何内容。这似乎在浏览器上完美运行。
我是否遗漏了某些内容,或者节点在原型函数定义或其他任何内容中是否允许console.log()
?
感谢您的帮助。
答案 0 :(得分:1)
因为console
模块将其所有方法绑定到自身(请参阅source here)。这是为了你可以做的事情:
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
方法绑定到自身here,因此会再次调用您的方法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)));
};
};