search
HomeWeb Front-endJS Tutorialjavascript instanceof 内部机制探析_javascript技巧

比如:

复制代码 代码如下:

// 代码 1
function Pig() {}
var pig = new Pig();
alert(pig instanceof Pig); // => true

function FlyPig() {}
FlyPig.prototype = new Pig();
var flyPig = new FlyPig();
alert(flyPig instanceof Pig); // => true

来看另一段代码:
复制代码 代码如下:

// 代码 2
function Pig() { Pig.prototype = {/* some code */} }
var pig = new Pig();
alert(pig instanceof Pig); // => false

为何上面的猪 pig 不再是猪 Pig 了呢?
当一个对象是某个类的实例时,意味着这个对象具有该类的方法和属性。在 JavaScript 中,一个猪类的特性体现在原型中:
复制代码 代码如下:

// 代码 3
function Pig() {}
Pig.prototype = {
"吃猪食": function() {},
"睡觉": function() {},
"长膘": function() {}
};
var pig = new Pig();
alert(pig instanceof Pig); //=> true

如果动态改变了猪的特性,让猪变成了牛:
复制代码 代码如下:

// 代码 4
Pig.prototype = {
"吃草": function() {},
"犁田": function() {}
};
var niu= new Pig();
alert(pig instanceof Pig); //=> false
alert(niu instanceof Pig); //=> true

当未改变 Pig 的 prototype 时,猪还是猪,因此代码 3 中 pig 是 Pig 的实例。当改变 prototype 后,猪已经不是猪,而是披着猪皮的牛了。因此代码 4 中 pig 不再是 Pig 的实例,niu 反而是 Pig 的实例。

进一步分析前,先回顾一下 new 的内部机制。代码 2 中的 new Pig() 实际上等价为:
复制代码 代码如下:

// var pig = new Pig() 的等价伪代码:
var pig = (function() {
var o = {};
o.__proto__ = Pig.prototype; // line 2
Pig.call(o);
Pig.prototype = {/* some code */}; // line 4
return o; // line 5
})();

可以看出,在 line 2 时,o.__proto__ 指向了 Pig.prototype 指向的值。但在 line 4 时,Pig.prototype 指向了新值。也就是说,在 line 5 返回时,pig.__proto__ !== Pig.prototype. 正是这个变化,导致了代码 2 中的 pig 不是 Pig.

已经可以大胆推论出:instanceof 判断 pig 是不是 Pig 的依据是:看隐藏的 pig.__proto__ 属性是否等于 Pig.prototype !

为了进一步确认,我们可以在 Firefox 下模拟 instanceof 的内部实现代码:
复制代码 代码如下:

/**
* Gecko 引擎下,模拟 instanceof
*/
function _instanceof(obj, cls) {
// instanceof 的左操作数必须是非null对象或函数对象
if((typeof obj !== "object" || obj === null)
&& typeof obj !== "function") {
return false;
}

// instanceof 的右操作数必须是函数对象
if(typeof cls !== "function") {
throw new Error("invalid instanceof operand (" + cls + ")");
}

// 向上回溯判断
var p = obj.__proto__, cp = cls.prototype;
while(p) {
if(p === cp) return true;
p = p.__proto__;
}
return false;
}

测试页面:simulate-intanceof.html

最后考考大家:
复制代码 代码如下:

function Bird() {}
var bird = new Bird();
var o = {};
bird.__proto__ = o;
Bird.prototype = o;
alert(bird instanceof Bird); // true or false?
Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
instanceof有什么作用instanceof有什么作用Nov 14, 2023 pm 03:50 PM

instanceof的作用是判断一个对象是否是某个类的实例,或者是否实现了某个接口。instanceof是一个用于检查对象是否是指定类型的运算符。instanceof运算符使用场景:1、类型检查:可以用来判断一个对象的具体类型,以便根据不同类型执行不同的逻辑;2、接口判断:可以用来判断一个对象是否实现了某个接口,以便根据接口的定义调用相应的方法;3、向下转型等等。

java中instanceof运算符怎么使用java中instanceof运算符怎么使用May 19, 2023 am 08:16 AM

概念1、该运算符用于操作对象的例子,检查对象是否为特定类型(类型或接口类型)。格式2、如果计算器左侧变量所指的对象是操作器右侧类或接口的对象,则结果是真实的。(Objectreferencevariable)instanceof(class/interfacetype)实例packagecom.verify_instanceof;publicclassTestInstanceOf{publicstaticvoidmain(String[]args){//下面四行代码用来证明:instanceof

java中instanceof是什么意思java中instanceof是什么意思Nov 13, 2023 pm 01:52 PM

在Java中,instanceof是一个二元运算符,用于检查一个对象是否是一个类的实例,或者是一个类的子类的实例,其语法形式为“object instanceof class”,其中,object是一个对象引用,class是一个类名或者接口名。

instanceof后为什么要强转instanceof后为什么要强转Nov 14, 2023 pm 03:43 PM

在使用instanceof运算符检查对象的类型时,如果结果为true,表示对象是指定类型的实例。但是,编译器并不会自动将对象转换为指定类型,因此需要进行强制类型转换。强制类型转换是将一个对象从一种类型转换为另一种类型的操作。在使用instanceof运算符后,如果确定对象是指定类型的实例,并且希望以该类型进行操作,就需要进行强制类型转换。

在Java中的instanceof运算符在Java中的instanceof运算符Sep 01, 2023 pm 08:01 PM

该运算符仅用于对象引用变量。该运算符检查对象是否属于特定类型(类类型或接口类型)。instanceof运算符写为-(Objectreferencevariable)instanceof(class/interfacetype)如果运算符左侧变量引用的对象通过了右侧类/接口类型的IS-A检查,则结果将为true。以下是一个示例-示例 现场演示publicclassTest{  publicstaticvoidmain(Stringargs[]){&nbs

为什么不加instanceof会报错为什么不加instanceof会报错Nov 13, 2023 pm 03:05 PM

原因是: instanceof运算符用于检查一个对象是否是某个特定类(或其派生类)的实例。如果对象不是一个类的实例,那么就无法进行类型判断,因此会抛出错误。为了避免这种错误,在使用instanceof运算符时,需要确保对象是一个类的实例。如果不确定对象的类型,可以使用其他方式进行类型判断。

为什么不用instanceof为什么不用instanceofNov 14, 2023 pm 04:05 PM

不用instanceof的原因有:1、正在使用的编程语言可能不支持 instanceof运算符,;2、认为使用其他方法可以更好地实现需求,在某些情况下,使用其他方法来检查对象类型可能更有效或更适合你的需求;3、不熟悉 instanceof运算符的使用方式或不确定它的行为;4、在某些情况下,使用 "instanceof" 可能不是最佳的选择。

instanceof为什么可以接口instanceof为什么可以接口Nov 13, 2023 pm 03:09 PM

instanceof不可以接口。原因是:instanceof关键字用于检查一个对象是否是特定类的实例,不能直接用于检查一个对象是否是接口的实例,因为接口不能被实例化。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version