JavaScript的instanceof运算符学习教程

作者:韩子迟 时间:2024-04-17 10:09:59 

语法


object instanceof constructor

参数
object:
要检测的对象.
constructor:
某个构造函数

描述:
instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。


// 定义构造函数
function C(){}
function D(){}

var o = new C();

// true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof C;

// false,因为 D.prototype不在o的原型链上
o instanceof D;

o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
C.prototype instanceof Object // true,同上

C.prototype = {};
var o2 = new C();

o2 instanceof C; // true

o instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.

D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true

需要注意的是,如果表达式 obj instanceof Foo 返回true,则并不意味着该表达式会永远返回ture,因为Foo.prototype属性的值有可能会改变,改变之后的值很有可能不存在于obj的原型链上,这时原表达式的值就会成为false。另外一种情况下,原表达式的值也会改变,就是改变对象obj的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的__proto__魔法属性,是可以实现的。比如执行obj.__proto__ = {}之后,obj instanceof Foo就会返回false了。

instanceof和多全局对象(多个frame或多个window之间的交互)

在浏览器中,我们的脚本可能需要在多个窗口之间进行交互。多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。这可能会引发一些问题。比如,表达式 [] instanceof window.frames[0].Array 会返回false,因为 Array.prototype !== window.frames[0].Array.prototype,因此你必须使用 Array.isArray(myObj) 或者 Object.prototype.toString.call(myObj) === "[object Array]"来判断myObj是否是数组。

示例
instanceof的常规用法是判断a是否是b类型:


console.log(true instanceof Boolean); // false
console.log(new Number(1) instanceof Number); // true

instanceof还能判断父类型:


function Father() {}
function Child() {}
Child.prototype = new Father();
var a = new Child();
console.log(a instanceof Child); // true
console.log(a instanceof Father); // true

Child构造函数继承自Father,实例a是Child构造的无疑,但是为何也是Father的实例呢?其实instanceof运算符的内核可以简单地用以下代码描述:


function check(a, b) {
while(a.__proto__) {
 if(a.__proto__ === b.prototype)
  return true;
 a = a.__proto__;
}
return false;
}

function Foo() {}
console.log(Object instanceof Object === check(Object, Object)); // true
console.log(Function instanceof Function === check(Function, Function)); // true
console.log(Number instanceof Number === check(Number, Number)); // true
console.log(String instanceof String === check(String, String)); // true
console.log(Function instanceof Object === check(Function, Object)); // true
console.log(Foo instanceof Function === check(Foo, Function)); // true
console.log(Foo instanceof Foo === check(Foo, Foo)); // true

简单地说,a如果是b的实例,那么a肯定能使用b的prototype中定义的方法和属性,那么用代码表示就是a的原型链中有b.prototype取值相同的对象,于是顺着a的原型链一层层找就行了。

另外值得注意的是,String Number Boolean 以及Function等都是函数,而函数则是统一由Function构造而来的,so它们和任何单纯的函数一样,能用Function上的原型属性:


Function.prototype.a = 10;
console.log(String.a); // 10

最后来简单讲讲最开始的两道题吧。


// 为了方便表述,首先区分左侧表达式和右侧表达式
FunctionL = Function, FunctionR = Function;
// 下面根据规范逐步推演
O = FunctionR.prototype = Function.prototype
L = FunctionL.__proto__ = Function.prototype
// 第一次判断
O == L
// 返回 true

// 为了方便表述,首先区分左侧表达式和右侧表达式
StringL = String, StringR = String;
// 下面根据规范逐步推演
O = StringR.prototype = String.prototype
L = StringL.__proto__ = Function.prototype
// 第一次判断
O != L
// 循环再次查找 L 是否还有 __proto__
L = String.prototype.__proto__ = Object.prototype
// 第二次判断
O != L
// 再次循环查找 L 是否还有 __proto__
L = String.prototype.__proto__ = null
// 第三次判断
L == null
// 返回 false
标签:JavaScript,instanceof
0
投稿

猜你喜欢

  • python爬虫之pyppeteer库简单使用

    2023-05-29 14:07:20
  • Python计算点到直线距离、直线间交点夹角

    2022-09-05 10:27:04
  • PHP缓存集成库phpFastCache用法

    2023-11-14 02:35:19
  • MySQL如何查询Binlog 生成时间

    2024-01-19 23:34:57
  • JavaScript延时效果比较不错的

    2024-04-22 13:22:48
  • 基于javascript实现全国省市二级联动下拉选择菜单

    2023-09-14 06:08:52
  • python监测当前联网状态并连接的实例

    2023-04-19 03:33:19
  • python自动化测试selenium操作下拉列表实现

    2023-09-06 00:26:50
  • Oracle字段根据逗号分割查询数据的方法

    2024-01-14 01:34:19
  • Python中的Classes和Metaclasses详解

    2022-07-08 09:28:47
  • Python根据字典值对字典进行排序的三种方法实例

    2022-07-29 16:24:21
  • Oracle PL/SQL入门案例实践

    2010-07-18 13:13:00
  • [组图]手把手教你制作ASP留言本

    2007-09-22 09:32:00
  • 数据库分页大全(mssql,mysql,oracle)

    2010-10-25 20:02:00
  • 总结SQL执行进展优化方法

    2024-01-13 22:38:44
  • javascript replace方法与正则表达式

    2024-04-19 10:03:37
  • PHP延迟静态绑定示例分享

    2024-06-05 15:42:24
  • Python实现统计文章阅读量的方法详解

    2023-11-02 23:28:46
  • 提高网页加载显示速度的方法

    2007-08-10 13:17:00
  • Python如何将装饰器定义为类

    2021-10-21 09:27:56
  • asp之家 网络编程 m.aspxhome.com