而Number原型扩展中的循环调用函数一次,然后出现未定义的错误

while loop in Number prototype extension calls function once, then errors undefined

本文关键字:然后 一次 错误 未定义 扩展 原型 Number 循环 函数 调用      更新时间:2023-09-26

我正在尝试扩展JS Number原型,以包括Ruby风格的".times"方法(这种追求的优点是另一个问题(。

这是我的代码:

Number.prototype.times = function(doThis) {
  val = +this;
  while (val > 0 ) {
    doThis();
    val--;
  }
}

如果我尝试

5..times(console.log(1));

我得到以下输出:

foo
TypeError: undefined is not a function (evaluating 'doThis()')

为什么循环在第一次迭代中有效,而在第二次迭代中失败?

(注意:目标是使Number原型扩展,以便调用它具有高度的表达性、直观性,并且读起来更像自然语言,比如Ruby的.times方法。(

您的Number.prototype.times函数被编写为将另一个函数作为参数(然后使用doThis()调用该函数(。

但是,在调用times函数时,您不是将另一个函数作为参数传递,而是返回console.log(1)的值,该值很可能是undefined(然后您试图将其作为函数调用,导致未定义不是函数错误(。

相反,传递一个调用console.log(1):的函数

5..times(function() {
    console.log(1);
});

您的函数让我想起了像下划线或lodash这样的库,它们提供了许多函数,可以让您生成非常简洁的代码。

以下是我如何使用lodash实现这一点,它提供了一个_.times((实用函数:

Number.prototype.times = function(cb) {
  return _.times(+this, cb);
}

您可以使用_.partial((使其比显式function() {}包装器更可读:

5..times(_.partial(console.log,"blah"));

或者,如果你想把分部放入times函数中,它可能更可读:

Number.prototype.times = function () {
    return _.times(+this, _.partial.apply(this,arguments));
};
5..times(console.log,"blah");
// can still be used with an arbitrary function block:
5..times(function() { console.log("some other block"); });

下面是一个jsfiddle示例。

更改为:

Number.prototype.times = function(doThis) {
  val = +this;
  while (val > 0 ) {
    doThis();
    val--;
  }
}
5..times(function () {console.log(1)});