关于EcmaScript-5 Function.prototype.bind实现,我有一个非常有趣的问题.通常在使用bind时,您可以这样做:
var myFunction = function() {
alert(this);
}.bind(123);
// will alert 123
myFunction();
Run Code Online (Sandbox Code Playgroud)
好的,这很酷,但是当我们这样做时会发生什么?
// rebind binded function
myFunction = myFunction.bind('foobar');
// will alert... 123!
myFunction();
Run Code Online (Sandbox Code Playgroud)
我理解,就Function.prototype.bind的实现方式而言,这是完全合乎逻辑的行为(https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind).但在现实生活中,这种行为完全没用,不是吗?问题是:是bug还是功能?如果它是一个错误,为什么它没有提到?如果它是一个功能,为什么那么具有原生"绑定"实现的谷歌浏览器的行为完全相同?
为了更清楚,我认为更有意义,这里是实现Function.prototype.bind的代码片段有点不同:
if (!Function.prototype.bind) {
Function.prototype.bind = function() {
var funcObj = this;
var original = funcObj;
var extraArgs = Array.prototype.slice.call(arguments);
var thisObj = extraArgs.shift();
var func = function() {
var thatObj = thisObj;
return original.apply(thatObj, extraArgs.concat(
Array.prototype.slice.call(
arguments, extraArgs.length
)
));
};
func.bind = function() {
var args = Array.prototype.slice.call(arguments); …Run Code Online (Sandbox Code Playgroud) 我感兴趣的是我们有一些函数f的场景,它是递归的,我们没有提供源代码.
我想要一个函数memoizer:Function - > Function,它接受说f并返回一个函数g,使得g = f(在某种意义上它们返回给定相同参数的相同值),当调用时首先检查被调用的参数是否为在它的'缓存'(它之前已经计算过的结果的内存)中,如果这样返回结果,否则它应该计算f,如果f用一些参数调用自己,这无异于用这些参数调用g,我想首先检查g的缓存是否包含这些参数,如果是,则返回结果,否则......
这很容易(在Javascript中)给出f的源代码,我只是以明显的方式定义memoize并做类似的事情
let f = memoize((...args) => {/* source code of f */});
Run Code Online (Sandbox Code Playgroud)
但这根本不吸引我(主要是因为我可能想要一个相同功能的memoized和非memoized版本然后我必须写两次相同的功能)如果我不知道将无法工作如何实施f.
如果我不清楚我在问什么,
我想要一个函数memoize,它具有如下函数
fact = n => n === 0 ? 1 : n * fact(n - 1);
Run Code Online (Sandbox Code Playgroud)
并且返回一些新函数g,使得所有n的fact(n)= g(n)并且例如当计算g(10)时存储fact(0),...,fact(10)的值,这是计算g(10)时计算,然后如果我要求说g(7)它在缓存中找到结果并将其返回给我.
我认为概念上可以检测f何时被调用,因为我有它的地址,也许我可以用一个新函数替换所有对f的调用,我计算f并存储结果,然后将值传递到它所在的位置通常去.但我不知道该怎么做(这听起来很不愉快).
我想在node.js应用程序中添加或覆盖Object,Function和Array的一些标准方法(例如,如本答案中建议的那样).我应该如何在一个模块中执行所有"补丁",以便影响我的所有其他模块?
这将是不够的,如果我在一个模块中做到这一点,这只是require"d,否则将无法工作,因为两个模块有不同的全局名称空间,使他们有不同的对象?......或者我应该运行一些初始化功能之后require,使所有这些"补丁"也在这个模块中工作?
我知道如何使用这些方法来改变函数/方法调用的上下文:apply,bind,call.我的问题是,有没有办法检查一个函数/方法是否已经设置了它的上下文?
// given
var beta;
function alpha () {
return this;
}
function isContextSet (fn) {
/* check for context binding on fn */
}
beta = alpha.bind("hello");
isContextSet(alpha); // returns false
isContextSet(beta); // returns true
Run Code Online (Sandbox Code Playgroud)
我想我已经知道了答案,但我想无论如何我会问,如果没有其他原因:1.确认我的假设,或2.学到一些东西.我确信我不是第一个提出这个问题的人,但我不知道如何找到答案,因为我得到的是对如何使用的回应:.apply(),. call()或.绑定().
javascript ×4
algorithm ×1
bind ×1
ecmascript-5 ×1
function ×1
module ×1
node.js ×1
prototype ×1