JS Array.isArray

在MDN看到 Array.isArray(Array.prototype) // true
但是在Node下测试发现 Array.prototype instanceof Array // false
没明白怎么回事,求大神解答。

MDN链接:MDN Array.prototype

阅读 3.9k
1 个回答

因为判断的方法不一样

1. instanceof

  • 首先说 instanceof 的判断方法是:左侧的原型链中的各个 [[prototype]] 指针是否指向 Array.prototype(即右侧对象的原型),如果有则返回 true。

  • 然而我们知道 Array.prototype 的 [[prototype]] 是指向 object.prototype 的。

    Array.prototype.__proto__ === Object.prototype; // true
    
  • 所以当然使用 instanceof 来判断就是 false 啦╮(╯_╰)╭

2. Array.isArray

  • 根据标准

  • 一共分三步(开冰箱门...大雾)

    • 如果传入的参数不是 Object,返回 false

    • 如果内部属性 [[Class]] 是 Array,返回 true

    • 其他情况都返回 false

  • 我们都知道一般情况我们获取 [[Class]] 属性是通过 toString 方法。(其实在没有 isArray 方法,而需要进行模拟时也是这么判断的)

  • 那么如果我们将这个方法改写会怎么样呢?

    Object.prototype.toString = function() { 
      return "[object Array]"; 
    };
    
    Array.isArray({}); // false
  • 可以看出 isArray 方法不受影响。

  • 所以这里我猜测 js 引擎在比较的时候是直接获取 [[Class]] 的值,而不是通过 toString 方法获取。(猜错了请指出_(:зゝ∠)_)


ps 补充一点儿 instanceof 的内容~= ̄ω ̄=~来自这里

function instance_of(L, R) {
  //L 表示左表达式,R 表示右表达式

  var O = R.prototype;// 取 R 的显示原型
  L = L.__proto__;// 取 L 的隐式原型

  while (true) { 
    if (L === null) 
      return false; 
      
    if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true 
      return true; 
      
    L = L.__proto__; 
  } 
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题