instanceof在JavaScript中是如何工作的?

instanceof在JavaScript中是如何工作的?,javascript,Javascript,在下面的代码示例中,在instanceof结束时对obj2和obj3的检查都返回true,即使它们的构造方式不同,并且返回name属性的结果也不同 var Obj1 = function() { this.name = "foo1"; }; Obj1.prototype.name = "foo1onProt"; var obj1 = new Obj1(); var Obj2 = function() {}; Obj2.prototype = new Obj1(); Obj2.proto

在下面的代码示例中,在instanceof结束时对obj2和obj3的检查都返回true,即使它们的构造方式不同,并且返回name属性的结果也不同

var Obj1 = function() {
    this.name = "foo1";
};
Obj1.prototype.name = "foo1onProt";
var obj1 = new Obj1();

var Obj2 = function() {};
Obj2.prototype = new Obj1();
Obj2.prototype.constructor = Obj2;
var obj2 = new Obj2();

var Obj3 = function() {};
Obj3.prototype = Object.create(Obj1.prototype);
Obj3.prototype.constructor = Obj3;
var obj3 = new Obj3();

console.dir(obj1);
console.log("obj1.name: " + obj1.name);

console.dir(obj2);
console.log("obj2.name: " + obj2.name);

console.dir(obj3);
console.log("obj3.name: " + obj3.name);

console.log("obj2 instanceof Obj1: " + (obj2 instanceof Obj1));
console.log("obj3 instanceof Obj1: " + (obj3 instanceof Obj1));
铬合金试运行结果:

Obj1
  name: "foo1"
  __proto__: Object
    constructor: function () {
    name: "foo1onProt"
    __proto__: Object
obj1.name: foo1
Obj2
  __proto__: Obj1
    constructor: function () {}
    name: "foo1"
    __proto__: Object
      constructor: function () {
      name: "foo1onProt"
      __proto__: Object
obj2.name: foo1
Obj3
   __proto__: Object
   constructor: function () {}
   __proto__: Object
     constructor: function () {
     name: "foo1onProt"
     __proto__: Object
obj3.name: foo1onProt

obj2 instanceof Obj1: true
obj3 instanceof Obj1: true
识别obj2和obj3不同的最佳方法是什么?
instanceof实际上是如何工作的?

最简单的是:
obj instanceof constructor
obj
的构造函数/原型链中有
构造函数的原型时,会产生
true
。换句话说,您询问引擎是否可以将
obj
视为
constructor
/的实例
obj
的行为是否类似于
constructor
对象

有一小部分语法允许您将
构造函数的原型放入
obj
的原型链中。它们中的任何一个都将导致构造函数的
obj实例
true
。在您的示例中,
obj2
obj3
在其原型链中都有
Obj1

因此,当您询问javascript引擎
obj2
obj3
的行为是否类似于
Obj1
的实例时,javascript假定
true
——唯一一种情况是,如果您已经重写了
Obj1
的行为,它们不会这样做

识别obj2和obj3不同的最佳方法是什么

这在很大程度上取决于你对他们做了什么。一种方法是使用Obj2的
实例
和Obj3的
实例
。由于这两个对象都是在它们的原型链中使用
Obj1.prototype
创建的,因此它们被标识为基于类的OOP中我们称之为超类型的实例是有意义的

instanceof实际上是如何工作的

简本
obj instanceof
查看
F.prototype
引用的对象是否在
obj
的原型链中的任何位置。它根本不使用
构造函数

更多细节 这在spec by中有介绍,它说(间接地,通过)调用函数对象的
[[HasInstance]]
内部方法,传递我们正在测试的对象
Function
[[HasInstance]]
(in)表示它从函数的
prototype
属性获取对象引用,然后返回
true
如果该对象在目标对象的prototype链中的任何位置,则返回
false

它不使用
构造函数
(事实上JavaScript本身没有任何功能)-如果你仔细想想,它也不能,因为对象的
构造函数
属性只能指向一个函数,但对象可以是多个函数的
实例-例如,在伪经典继承的情况下:

函数F1(){}
函数F2(){
F1.呼叫(本机);
}
F2.prototype=Object.create(F1.prototype);
F2.prototype.constructor=F2;
var obj=新的F2();
console.log(F1的obj实例);//真的

console.log(F2的obj实例);//true
创建两个不同的对象,都以Obj1为基础,然后询问它们是否为Obj1的实例。嗯,是的,他们都是。如果您想知道它们是否不同,那么只需使用
=
运算符。@AHM我知道您的回答是多年前的,但是我从未见过使用严格相等直接比较JavaScript对象的方法。您是否介意进一步阐述您对“objA==objB”的上述评论的含义?对于对象,仅当比较的两个对象是同一对象时,===运算符才返回true。虽然您通常不会将一个对象与自身进行比较,但如果您想找出已知集合中的哪个对象引用了@FrédéricHamidi,这会很有用。这是一个错误的答案。T.J.克劳德的答案是正确的。@VLAZ-谢谢,我不知道我的任何答案仍然使用这个。我得去打猎了……哦,对了……我还想写一篇评论来通知你。我在编辑时忘记了这一点。:)另外,我试图找到回购协议,但它似乎已经不存在了,我想是因为它不再需要了。@VLAZ-无需留下评论,所以在编辑您的答案时会通知您。:-)我不记得取消了回购协议,但似乎是我取消了,而不是github失去了它-呃,data explorer说我有349个要修复-(每天两分钟,差不多是12小时的工作。我会在一两个月内每天做5-10次……也许你可以:)我也可以偶尔帮忙。我最近更新了一些旧文章,主要是让代码片段可以运行。我仍在探索更新哪些帖子的方法,我主要是浏览和回顾吸引我眼球的整个问答。所以,现在它是无指导和零星的-你的帖子给了我一个更直接的目标,我可以朝着这个目标努力。@VLAZ-太好了!我可以一点一滴地做,但如果你想加入,只要改变你所做的任何删除文本(请不要删除它们)。如果你看到任何与我的旧式ASCII艺术使用-而不是−, 你能加个便条吗?我去把它们修好。:-)但再说一次,只有你真的想,否则我会去找他们。(我已经做了一些不在名单上的,所以不再是349了…)