我想在node.js中创建一个函数,它接受一个整数值并使用lodash / underscore' s _.partial
/ _.partialRight
将其转换为二进制字符串。
var _ = require('lodash');
var n = 123456789;
console.log(n.toString(2)); // works
console.log(Number.prototype.toString.call(n, 2)); // works
var toBin = _.partialRight(Number.prototype.toString.call, 2);
console.log(toBin(n)); // broken
console.log(toBin); // --> [Function: bound]
最后一个破坏的实现产生:
/media/data/Dropbox/game-of-spell/node_modules/lodash/dist/lodash.js:957
return func.apply(thisBinding, args);
^
TypeError: object is not a function
是否可以将.call
或.apply
分开?如果不是为什么?
答案 0 :(得分:0)
要了解发生了什么,您应该尝试这样做:
var call = Number.prototype.toString.call;
call(2);
您将获得TypeError: undefined is not a function
。您认为call
是一个函数,错误是错误的。是的,call
是一个函数,但是这个TypeError不是在谈论call
,而是在讨论它的上下文(this
)。这会让人感到困惑,但调用函数call
时,会调用它的上下文/这个对象。
你基本上可以这样做:
call.call(function (a) { console.log('wat? This: ', this, ' argument:', a); }, { thisObject: true }, 'im arguemnt');
这将产生以下结果:wat? This: Object {thisObject: true} argument: im arguemnt
但是,如果在没有任何上下文或此对象的情况下调用call
,则默认此对象将在严格模式下为window
或global
对象或null
。您可以像这样验证此对象的默认值:
function verify() { return this; }; console.log(verify());
将在浏览器中的节点和窗口对象中打印全局对象。
要解决您的问题,您必须将其绑定到它的父功能:
var toString = Number.prototype.toString;
var call = toString.call.bind(toString);
或者使用lodash bind:
var call = _.bind(toString.call, toString);
然后这将起作用:
var toBin = _.partialRight(call, 2);
您还可以将其缩短为var toBin = _.partialRight(toString.call.bind(toString), 2);
如果您想使用_.partial
,请直接使用bind:
var print1000 = _.bind(toString.call, toString, 1000);
console.log(print1000(), print1000(2), print1000(8), print1000(16));
您也可能想知道为什么Number.prototype.toString.call(n, 2)
。因为当你将一个函数作为一个对象的方法(实际上是这里的一个函数)时,它将把对象作为它的上下文。
您可以在此answer of mine中阅读更多内容。