【问题标题】:Why does Array().slice without "new" work?为什么没有“新”的 Array().slice 可以工作?
【发布时间】:2023-04-07 11:51:01
【问题描述】:

From here:

function highest(){ 
  return makeArray(arguments).sort(function(a,b){ 
    return b - a; 
  }); 
} 

function makeArray(array){ 
  return Array().slice.call( array ); 
} 

assert(highest(1, 1, 2, 3)[0] == 3, "Get the highest value."); 
assert(highest(3, 1, 2, 3, 4, 5)[1] == 4, "Verify the results.");

现在,为什么 Array() 甚至返回有意义的东西,没有 new 运算符?如果在没有 new 的情况下调用,我在 JS 中看到的大多数“类”定义都会返回 undefined

function User(name) {
  this.name = name;
  this.jump = function() {
    console.log(name + " is jumping!");
  }
}

assert(typeof(User("no New")) == 'undefined');

【问题讨论】:

  • 与其说是“为什么 .slice() 有效?”作为“为什么Array() 似乎和new Array() 做同样的事情?” - 答案可以概括为“因为规范是这样说的”。见What's the difference between Array(1) and new Array(1)?
  • @nnnnnn - 是的,投票决定关闭为 dup,谢谢。

标签: javascript


【解决方案1】:

specification 明确规定了这一点:

Array 作为函数而不是构造函数调用时,它会创建并初始化一个新的Array 对象。因此函数调用Array(…)等价于具有相同参数的对象创建表达式new Array(…)

如何在内部完成取决​​于实现,但对于自定义构造函数,您可以使用以下技巧:

if(!(this instanceof User)) return new User(name);

... 因为new User(...)this 设置为创建的User 实例,而User(...) 将其设置为全局对象。 (所以你实际上是在最后一个 sn-p 中设置全局变量。)

【讨论】:

    【解决方案2】:

    基于 Chrome 的调试面板,Array() 以与 new Array()[] 相同的方式返回一个新数组。我的猜测是它要么是为了语言的易用性,要么是与[] 语法有关(当然不需要新的)。

    实际上可以使用您自己的函数来选择性地要求一个新的:

    function User(name) {
        if (!(this instanceof User)) {
            return new User(name);
        }
        this.name = name;
        this.jump = function() {
            console.log(name + " is jumping!");
        };
    }
    
    ​
    

    然后 User('blah')new User('blah') 都可以工作。

    【讨论】:

      猜你喜欢
      • 2014-01-25
      • 2014-01-17
      • 2023-02-09
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-29
      • 2016-09-18
      相关资源
      最近更新 更多