【问题标题】:What's the difference between using instanceof and checking the constructor?使用 instanceof 和检查构造函数有什么区别?
【发布时间】:2013-08-06 00:45:06
【问题描述】:

为什么下面两行会返回不同的结果?

("test" instanceof String) // returns false
("test".constructor == String) // returns true

在 chrome 版本 28.0.1500.95 m 的控制台中测试

对于原生类型,它的工作方式是否略有不同?

【问题讨论】:

  • 我不认为它是重复的。这实际上是一个更普遍的问题。
  • @basilikum 我同意。此外,我认为可能重复的问题本身的答案描述性不足。我投票重新提出这个问题。
  • 值得阅读以下答案:stackoverflow.com/a/18057157/783743
  • 您的回答很有趣,谢谢,native types have a constructor wrapper 是对上述内容的解释。知道您可以使用第一个参数作为原始值初始化这些包装器类型也很有用。
  • @Ally 我认为解释是当你写"test" 它实际上是String("test"); 并且你得到一个原语(所以 instanceof 不会工作,因为它不是一个对象)。但是当您尝试将文字用作对象时,浏览器会将其转换为 String 对象,这就是出现 .constructor 属性的原因。

标签: javascript


【解决方案1】:

constructor 只是内部[[prototype]] 属性的一个属性,很容易被操纵:

function A(){}
function B(){}
A.prototype.constructor = B;

var a = new A();

console.log(a.constructor); //B

instanceof 操作符会检查内部原型链,即使您更改了构造函数的完整 prototype 属性,也不会那么容易上当:

function A(){}
function B(){}
A.prototype = B.prototype;

var a = new A();

console.log(a instanceof A); //true
console.log(a instanceof B); //false

那么,为什么是"test" instanceof String === false 而是("test".constructor == String) === true

首先,"test" 是一个原语,而原语永远不是任何事物的实例。当您使用instanceof 时,实际发生的情况是构造函数的内部[[HasInstance]] 方法以可能的实例作为参数被调用。所以a instanceof A 大致翻译为:

`A.[[HasInstance]](a)`

ECMA 规范有这句话要告诉[[HasInstance]]http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5.3

[[HasInstance]] (V)

假设 F 是一个 Function 对象。

当 F 的 [[HasInstance]] 内部方法以值 V 被调用时, 采取以下步骤:

  1. 如果 V 不是对象,则返回 false。
  2. ....

也就是说:如果instanceof的左边不是一个对象,那么操作符会返回false。

("test".constructor == String) === true 工作的原因不同:如果您尝试访问原语的属性,原语将被临时转换为对象。所以"test".constructor大致等于:

(new String("test")).constructor

在这种情况下,您实际上是在使用构造函数创建一个对象,然后请求constructor 属性。所以毫不奇怪,它会返回String

【讨论】:

    【解决方案2】:

    主要区别在于instanceof 检查对象的原型链,而检查构造函数只检查它是否是从同一个构造函数创建的。

    例子:

    function MyObject() {
        this.sayHi = function() { alert('Hi!'); }   
    }
    
    var x = new MyObject();
    alert(x.constructor === Object);
    alert(x instanceof Object);
    

    【讨论】:

      猜你喜欢
      • 2013-08-12
      • 1970-01-01
      • 2019-08-30
      • 1970-01-01
      • 1970-01-01
      • 2011-10-17
      • 2018-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多