扒下JS的“底裤”之 instanceof 运算符详解

简介: 扒下JS的“底裤”之 instanceof 运算符详解

详解instanceof

基本概念

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

也就是说

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


语法

/*
 *2个参数
 *object 某个实例对象
 *constructor 某个构造函数
*/
object instanceof constructor 
复制代码


示例

1.简单应用

function C(){}
function D(){}
var o = new C();
o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof D; // false,因为 D.prototype 不在 o 的原型链上
o instanceof Object; // true,因为 Object.prototype.isPrototypeOf(o) 返回 true
C.prototype instanceof Object // true,同上
复制代码


  1. 改变constructor.prototype的值

如果表达式 obj instanceof Foo 返回 true,则并不意味着该表达式会永远返回 true,因为 Foo.prototype 属性的值有可能会改变,改变之后的值很有可能不存在于 obj 的原型链上,这时原表达式的值就会成为 false。

// 接上前面的例子
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 因为 C.prototype 现在在 o3 的原型链上
复制代码


  1. 改变原型链

改变对象 obj 的原型链的情况,虽然在目前的 ES 规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的 proto 伪属性,是可以实现的。比如执行 obj.proto = {} 之后,obj instanceof Foo 就会返回 false 了。

function C() {}
let c = new C()
console.log(c instanceof C); // true
c.__proto__ = {}
console.log(c instanceof C); // false 这里c的原型链已经被修改
复制代码


  1. 演示 String 对象和 Date 对象都属于 Object 类型和一些特殊情况
  • String 和 Date 对象同时也属于Object 类型(他们是由 Object 类派生出来的)。
  • 使用对象文字符号创建的对象在这里是一个例外:虽然原型未定义,但 instanceof Object 返回 true。
var simpleStr = "This is a simple string";
var myString  = new String();
var newStr    = new String("String created with constructor");
var myDate    = new Date();
var myObj     = {};
var myNonObj  = Object.create(null);
simpleStr instanceof String; // 返回 false,非对象实例,因此返回 false
myString  instanceof String; // 返回 true
newStr    instanceof String; // 返回 true
myString  instanceof Object; // 返回 true
myObj instanceof Object;    // 返回 true,尽管原型没有定义
({})  instanceof Object;    // 返回 true,同上
myNonObj instanceof Object; // 返回 false,一种创建非 Object 实例的对象的方法
myString instanceof Date; //返回 false
myDate instanceof Date;     // 返回 true
myDate instanceof Object;   // 返回 true
myDate instanceof String;   // 返回 false
复制代码


不是...的实例

直接使用if条件,记得加括号!!! 因为!的运算优先级比instanceof高

详情见

运算符优先级表

要检测对象不是某个构造函数的实例时,你可以这样做

if (!(mycar instanceof Car)) {
  // Do something, like mycar = new Car(mycar)
}
复制代码


这和以下代码完全不同

if (!mycar instanceof Car)
复制代码


instanceof 和多全局对象 (例如:多个 frame 或多个 window 之间的交互) 待补


涉及原型链,待补



目录
相关文章
|
3月前
|
JavaScript 前端开发 Java
JavaScript基础语法(运算符)
JavaScript基础语法(运算符)
32 0
|
4月前
|
JavaScript 前端开发 开发者
从0开始学习JavaScript--JavaScript 表达式与运算符
JavaScript中的表达式和运算符是构建逻辑、进行计算的基础。本文将深入研究JavaScript中各类表达式,包括算术表达式、关系表达式、逻辑表达式,以及运算符的使用方法,并通过丰富的示例代码来帮助读者更全面地了解和运用这些概念。
|
26天前
|
JavaScript 前端开发
JavaScript中Object.prototype.toString.call()、instanceOf和Array.isArray()的区别
JavaScript中Object.prototype.toString.call()、instanceOf和Array.isArray()的区别
25 1
|
1月前
|
JavaScript
js开发:请解释什么是ES6的扩展运算符(spread operator),并给出一个示例。
ES6的扩展运算符(...)用于可迭代对象展开,如数组和对象。在数组中,它能将一个数组的元素合并到另一个数组。例如:`[1, 2, 3, 4, 5]`。在对象中,它用于复制并合并属性,如`{a: 1, b: 2, c: 3}`。
12 3
|
1月前
|
JavaScript 前端开发 程序员
编程笔记 html5&css&js 074 Javascript 运算符
编程笔记 html5&css&js 074 Javascript 运算符
|
3月前
|
JavaScript 前端开发 测试技术
探究 JavaScript 类型检查的利器:typeof 和 instanceof
探究 JavaScript 类型检查的利器:typeof 和 instanceof
|
3月前
|
JavaScript 前端开发
什么是 JavaScript 中的 Spread 运算符
什么是 JavaScript 中的 Spread 运算符
28 0
|
3月前
|
JavaScript 前端开发
JS-基础:JavaScript运算符 个人总结
JS-基础:JavaScript运算符 个人总结
20 0
|
3月前
|
前端开发 JavaScript 算法
JavaScript不常见但好用的运算符
JavaScript不常见但好用的运算符
|
3月前
|
存储 前端开发 JavaScript
【面试题】Javascript的这些运算符,你都都掌握哪些?
【面试题】Javascript的这些运算符,你都都掌握哪些?