Skip to content

第 57 期(W3C 标准-ECMAScript-语法):setTimeout的其他参数 #60

@wingmeng

Description

@wingmeng

看到一道今日头条的面试题:

修改以下 print 函数,使之输出 0 到 99 或 99 到 0

要求:
1. 只能修改 setTimeout 到 Math.floor(Math.random() * 1000 的代码
2. 不能修改 Math.floor(Math.random() * 1000
3. 不能使用全局变量
function print(n) {
  setTimeout(() => {
    console.log(n);
  }, Math.floor(Math.random() * 1000));
}
for (var i = 0; i < 100; i++) {
  print(i);
}

有位老弟的回答亮了:

function print(n) {
  setTimeout(() => {
    console.log(n);
  }, 1, Math.floor(Math.random() * 1000));
}
for (var i = 0; i < 100; i++) {
  print(i);
}

这个回答巧妙地“钻了” setTimeout 参数次序的空子。原来 setTimeout 除了常见的前 2 个参数外,还有后续参数,这些后续参数会传递给执行函数(IE9及更早浏览不支持后续参数)。这个特性在某些情况下很有用,例如不使用箭头函数的情况下,如何将 this 指向传递到 setTimeout 的 function 中,伪代码如下:

function Fn() {
  this.foo = 1;
}

Fn.prototype.do = function() {
  // 传统实现方式是将 this 保存到一个变量
  var that = this;
  setTimeout(function() {
    that.foo = 2;
  }, 1000);

  // 其实可以将 this 作为 setTimeout 第 3 个参数传进去
  setTimeout(function(that) {
    that.foo = 2;
  }, 1000, this);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions