instanceof如何在JavaScript中运行?

在下面的代码示例中,最后使用instanceof检查obj2和obj3,即使构造的方式不同并且返回name属性的结果不同,也会返回true.
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));

在Chrome中运行的结果:

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不同的最佳方法是什么?
实际上如何工作?

解决方法

What is the best way to recognize that obj2 and obj3 are different?

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

How does actually instanceof work?

简短的版本

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

更多细节

§11.8.5 – The instanceof Operator中的规范涵盖了这一点,它说(间接地,通过§8.6.2)它调用函数对象的[[HasInstance]]内部方法,传入我们正在测试的对象.函数[[HasInstance]](在§15.3.5.3中)表示它从函数的prototype属性获取对象引用,如果该对象在目标对象的原型链中的任何位置,则返回true,否则返回false.

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

function F1() {}

function F2() {
  F1.call(this);
}
F2.prototype = Object.create(F1.prototype);
F2.prototype.constructor = F2;

var obj = new F2();
snippet.log(obj instanceof F1); // true
snippet.log(obj instanceof F2); // true
<!-- Script provides the `snippet` object,see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

两者都是正确的,因为F1.prototype和F2.prototype引用的两个对象都在obj的原型链中.

instanceof为true并不一定意味着obj是通过直接或间接调用F创建的;它只是表明它们之间存在模糊的联系(F.prototype指的是同样在obj的原型链中的对象).它通常意味着F参与创建对象,但不能保证.

例如:

function F() {}
var obj = Object.create(F.prototype);
snippet.log(obj instanceof F); // true
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

请注意,根本没有调用F来创建对象.

或者可能更清楚和/或更显着:

function F() {}
var p = {};
var obj = Object.create(p);
snippet.log(obj instanceof F); // false
F.prototype = p;
snippet.log(obj instanceof F); // true
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

还有这个不寻常但完全可能的版本:

function F1() {}
function F2() {}
F1.prototype = F2.prototype = {};
var obj = new F1();
snippet.log(obj instanceof F2); // true
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

或者这一个:

function F1() {}
function F2() {}
var obj = new F2();
snippet.log(obj instanceof F1); // false
F1.prototype = F2.prototype;
snippet.log(obj instanceof F1); // true
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


kindeditor4.x代码高亮功能默认使用的是prettify插件,prettify是Google提供的一款源代码语法高亮着色器,它提供一种简单的形式来着色HTML页面上的程序代码,实现方式如下: 首先在编辑器里面插入javascript代码: 确定后会在编辑器插入这样的代码: <pre
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换为SyntaxHighlighter代码高亮插件 上一篇“让kindeditor显示高亮代码”中已经
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)
原生JS实现别踩白块小游戏(一)