instanceof和typeof
loyalvi Lv7

instanceof和typeof

instanceof

在 JavaScript 中,instanceof 运算符用于检测一个对象是否是特定构造函数的实例。它的语法如下:

1
object instanceof constructor
  • object:需要检测的对象。
  • constructor:构造函数。
    如果 objectconstructor 的实例,则返回 true;否则返回 false

工作原理

instanceof 运算符通过检查对象的原型链来确定该对象是否是某个构造函数的实例。具体来说,它会检查对象的原型链中是否包含构造函数的 prototype 属性所引用的对象。

示例

示例 1:基本用法

1
2
3
4
5
6
7
function Person(name) {
this.name = name;
}
const person1 = new Person('Alice');
const person2 = { name: 'Bob' };
console.log(person1 instanceof Person); // true
console.log(person2 instanceof Person); // false

在这个示例中,person1 是通过 Person 构造函数创建的,所以 person1 instanceof Person 返回 true。而 person2 是一个普通的对象,不是通过 Person 构造函数创建的,所以 person2 instanceof Person 返回 false

示例 2:原型链

1
2
3
4
5
6
7
8
9
10
11
12
13
function Animal(name) {
this.name = name;
}
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const dog1 = new Dog('Buddy', 'Labrador');
console.log(dog1 instanceof Dog); // true
console.log(dog1 instanceof Animal); // true
console.log(dog1 instanceof Object); // true

在这个示例中,Dog 构造函数继承了 Animal 构造函数。dog1 是通过 Dog 构造函数创建的,所以 dog1 instanceof Dog 返回 true。因为 Dog 继承了 Animal,所以 dog1 instanceof Animal 也返回 true。所有 JavaScript 对象最终都继承自 Object,所以 dog1 instanceof Object 也返回 true

常见用途

  1. 类型检查:确定一个对象是否是某个特定构造函数的实例。
  2. 继承检测:检查一个对象是否在某个原型链上。
  3. 多态:在方法中根据对象的类型执行不同的操作。

限制

instanceof 运算符在跨 iframe 或跨窗口(window)的情况下可能会出现问题,因为不同窗口中的构造函数是不同的实例。例如:

1
2
3
4
5
6
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const iframeArray = iframe.contentWindow.Array;
const arr = new iframeArray(1, 2, 3);
console.log(arr instanceof Array); // false
console.log(arr instanceof iframeArray); // true

在这个示例中,arr 是在 iframe 中创建的 Array 实例,所以 arr instanceof Array 返回 false,因为 Array 在不同的窗口中是不同的构造函数。

替代方案

如果需要在跨窗口的情况下进行类型检查,可以使用 Object.prototype.toString.call(value) 方法:

1
2
const arr = new iframeArray(1, 2, 3);
console.log(Object.prototype.toString.call(arr)); // "[object Array]"

这个方法会返回一个表示对象类型的字符串,可以用来准确地判断对象的类型,即使在跨窗口的情况下也有效。

总结

instanceof 运算符是一个非常有用的工具,用于检测对象是否是某个构造函数的实例。它通过检查对象的原型链来工作,但在跨窗口的情况下可能会出现问题。在这种情况下,可以使用 Object.prototype.toString.call(value) 作为替代方案。

🎈instanceof 可以检测直接量吗

在 JavaScript 中,instanceof 运算符主要用于检测一个对象是否是特定构造函数的实例。对于基本数据类型的直接量(如数字、字符串、布尔值等),instanceof 运算符通常不会返回有意义的结果,因为这些直接量不是通过构造函数创建的。

基本数据类型的直接量

基本数据类型的直接量包括数字、字符串、布尔值、nullundefinedSymbolBigInt。这些直接量不是对象,因此不具有原型链,instanceof 运算符对它们无效。

1
2
3
4
5
6
7
console.log(5 instanceof Number); // false
console.log('hello' instanceof String); // false
console.log(true instanceof Boolean); // false
console.log(null instanceof Object); // false
console.log(undefined instanceof Object); // false
console.log(Symbol('foo') instanceof Symbol); // false
console.log(BigInt(123) instanceof BigInt); // false

包装对象

虽然基本数据类型的直接量不是对象,但 JavaScript 提供了包装对象(如 NumberStringBoolean),可以将基本数据类型转换为对象。对于这些包装对象,instanceof 运算符可以返回 true

1
2
3
console.log(new Number(5) instanceof Number); // true
console.log(new String('hello') instanceof String); // true
console.log(new Boolean(true) instanceof Boolean); // true

特殊情况:nullundefined

nullundefined 是特殊的值,它们不是任何构造函数的实例,因此 instanceof 运算符对它们总是返回 false

1
2
console.log(null instanceof Object); // false
console.log(undefined instanceof Object); // false

总结

  • 基本数据类型的直接量instanceof 运算符对它们无效,总是返回 false
  • 包装对象:可以使用 instanceof 运算符检测包装对象是否是特定构造函数的实例。
  • nullundefinedinstanceof 运算符对它们总是返回 false
    如果你需要检测一个值是否是基本数据类型,可以使用 typeof 运算符,它返回一个表示值的类型的字符串。
1
2
3
4
5
6
7
console.log(typeof 5); // "number"
console.log(typeof 'hello'); // "string"
console.log(typeof true); // "boolean"
console.log(typeof null); // "object"(这是一个历史遗留问题)
console.log(typeof undefined); // "undefined"
console.log(typeof Symbol('foo')); // "symbol"
console.log(typeof BigInt(123)); // "bigint"

通过 typeof 运算符,你可以准确地检测一个值是否是基本数据类型。

💎instanceof 语句 (书)

instanceof 语句比 typeof 语句更进了一步,可以判断一个对象是不是某种类型的实例。 就好像周围的东西可以分为动物、植物、空气、水、金属等大的类型,而动物、植物以及金属还可以再进行更细的分类 。 可 peof 的作用就是查 看一样东西属于 什么大的 类型,例 如 是动 物还是植物,而 instanceof 可以判断东西的具体类型,例如,如果是动物的话,可以判断是不是人,如果是人还可以判断是黄种人还是白种人 、黑种人等。 instanceof 语句的结构如下。

1
obj instanceof TypeObject

instanceof 语句的返回值为布尔类型,表示判断是否正确。例如,下面的例子使用 instanceof 来判断 m 变量是否为数组类型。

1
2
var arr = [1, 2 , 3]; 
console .log(arr instanceof Array); //true

02 function类型对象 会介绍 function 类型的对象,可以使用 new 关键字来创建 object 类型的对象,那时就可以使用 instanceof 来判断一个变量是否为指定类型的 function 对象创建的。
在 JavaScript 中,instanceof 运算符用于检测一个对象是否是特定构造函数的实例。它返回一个布尔值,表示对象是否在构造函数的原型链上。以下是关于 instanceof 语句的详细解释:

语法

1
object instanceof constructor
  • object:要检测的对象。
  • constructor:构造函数。

示例

基本用法

1
2
3
4
5
6
7
function Person(name) {
this.name = name;
}
let person1 = new Person("John");
console.log(person1 instanceof Person); // true
console.log(person1 instanceof Object); // true
console.log(person1 instanceof Array); // false

检测内置对象类型

1
2
3
4
5
6
7
8
9
10
11
12
let arr = [1, 2, 3];
console.log(arr instanceof Array); // true
console.log(arr instanceof Object); // true
let str = "Hello";
console.log(str instanceof String); // false
console.log(str instanceof Object); // false
let num = 123;
console.log(num instanceof Number); // false
console.log(num instanceof Object); // false
let obj = new String("Hello");
console.log(obj instanceof String); // true
console.log(obj instanceof Object); // true

工作原理

instanceof 运算符的工作原理是检查对象的原型链是否包含构造函数的 prototype 属性所引用的原型对象。具体步骤如下:
4. 获取构造函数的 prototype 属性。
5. 检查对象的原型链是否包含该原型对象。
6. 如果包含,返回 true;否则,返回 false

示例

1
2
3
4
5
6
7
8
function Person(name) {
this.name = name;
}
let person1 = new Person("John");
console.log(Person.prototype); // Person {}
console.log(person1.__proto__); // Person {}
console.log(Person.prototype === person1.__proto__); // true
console.log(person1 instanceof Person); // true

注意事项

  1. 原型链的影响
    • 如果对象的原型链被修改,instanceof 的结果可能会受到影响。
    • 例如:
      1
      2
      3
      4
      5
      6
      7
      function Person(name) {
      this.name = name;
      }
      let person1 = new Person("John");
      // 修改原型链
      person1.__proto__ = {};
      console.log(person1 instanceof Person); // false
  2. 跨iframe或window的情况
    • 在不同的 iframe 或 window 中,即使构造函数相同,instanceof 也可能返回 false,因为每个 iframe 或 window 都有自己的全局对象和原型链。
    • 例如:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      // 在主页面中
      function Person(name) {
      this.name = name;
      }
      // 在 iframe 中
      let iframe = document.createElement('iframe');
      document.body.appendChild(iframe);
      let iframeContent = iframe.contentWindow;
      let person1 = new Person("John");
      let person2 = new iframeContent.Person("Jane");
      console.log(person1 instanceof Person); // true
      console.log(person2 instanceof Person); // false
  3. 检测 null 和 undefined
    • nullundefined 没有原型链,因此 instanceof 会返回 false
    • 例如:
      1
      2
      console.log(null instanceof Object); // false
      console.log(undefined instanceof Object); // false

总结

  • instanceof 用于检测一个对象是否是特定构造函数的实例。
  • 它通过检查对象的原型链是否包含构造函数的 prototype 属性所引用的原型对象来工作。
  • 原型链的修改和跨 iframe 或 window 的情况会影响 instanceof 的结果。
  • nullundefined 没有原型链,因此 instanceof 会返回 false
    理解 instanceof 的这些特性可以帮助你更准确地检测对象的类型和来源。

💎typeof 语句

typeof 语句的作用是获取变量的类型,调用语法如下 。
typeof 在 ES2015 中的返回值一共有 7 种: undefined 、 function 、 object 、 boolean 、 number 、 string 和 symbol ,请看下面的例子。es2020 新增bigint

  • typeof
    • number
      • Number
      • NaN
    • string
      • string
    • object
      • Object
      • null
      • Array
    • function
      • Function
    • undefined
      • Undefined
    • boolean
      • Boolean
    • symbol
      • Symbol
    • bigint
      • Bigint

需要特别注意的是 ,null 和数组的类型都是 object ,因为 null 本身也是一个对象,而数组中可以包含其他任何类型的元素,它并不是底层对象,所以它们没有自己独有的类型 。
undefined 是一种特殊的类型,它所代表的是这么一种类型:它们有名字,但是不知道自己是什么类型。即只要有名字但是没有赋值的变量都是 undefined 类型。如果用之前学习过的内存模型来说, undefined 类型的对象就是只占用一块内存空间(用来保存变量名字)的对象。
另外, symbol 类型是 ES2015 中新增的内容,可以查看 Symbol

instanceof 和 typeof 有什么区别?

instanceoftypeof 是 JavaScript 中用于检测变量类型的两种不同的运算符,它们在功能和用途上有显著的区别。以下是对这两个运算符的详细对比:

1. typeof 运算符

  • 用途
    • typeof 用于检测变量的基本数据类型。它返回一个字符串,表示变量的类型。
  • 返回值
    • typeof 返回的字符串有以下几种:
      • "undefined":变量未定义
      • "boolean":布尔值
      • "number":数字
      • "string":字符串
      • "symbol":符号(ES6 新增)
      • "bigint":大整数(ES2020 新增)
      • "object":对象、数组、null
      • "function":函数
  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    console.log(typeof undefined); // "undefined"
    console.log(typeof true); // "boolean"
    console.log(typeof 42); // "number"
    console.log(typeof "Hello"); // "string"
    console.log(typeof Symbol()); // "symbol"
    console.log(typeof BigInt(1)); // "bigint"
    console.log(typeof {}); // "object"
    console.log(typeof []); // "object"
    console.log(typeof null); // "object"(这是一个历史遗留问题)
    console.log(typeof function() {}); // "function"

2. instanceof 运算符

  • 用途
    • instanceof 用于检测一个对象是否是特定构造函数的实例。它返回一个布尔值,表示对象是否在构造函数的原型链上。
  • 返回值
    • instanceof 返回 truefalse
  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function Person(name) {
    this.name = name;
    }
    let person1 = new Person("John");
    let person2 = { name: "Jane" };
    console.log(person1 instanceof Person); // true
    console.log(person2 instanceof Person); // false
    console.log(person1 instanceof Object); // true
    console.log([] instanceof Array); // true
    console.log([] instanceof Object); // true
    console.log({} instanceof Object); // true

3. 主要区别

  • 检测对象类型
    • typeof 用于检测基本数据类型,返回字符串。
    • instanceof 用于检测对象是否是特定构造函数的实例,返回布尔值。
  • nullundefined 的处理
    • typeof null 返回 "object",这是一个历史遗留问题。
    • typeof undefined 返回 "undefined"
    • nullundefined 没有原型链,因此 instanceof 会返回 false
  • 跨 iframe 或 window 的情况
    • typeof 不受跨 iframe 或 window 的影响。
    • instanceof 在不同的 iframe 或 window 中,即使构造函数相同,也可能返回 false,因为每个 iframe 或 window 都有自己的全局对象和原型链。
  • 检测数组和对象
    • typeof 对数组和对象都返回 "object"
    • instanceof 可以区分数组和对象,[] instanceof Array 返回 true{} instanceof Object 返回 true

4. 总结

  • typeof:用于检测基本数据类型,返回字符串。对 nullundefined 有特殊处理,对数组和对象都返回 "object"
  • instanceof:用于检测对象是否是特定构造函数的实例,返回布尔值。对 nullundefined 返回 false,可以区分数组和对象,受跨 iframe 或 window 的影响。

5. 实际应用

  • 检测基本数据类型
    • 使用 typeof
    • 例如:
      1
      2
      3
      if (typeof value === "string") {
      // 处理字符串
      }
  • 检测对象类型
    • 使用 instanceof
    • 例如:
      1
      2
      3
      if (value instanceof Array) {
      // 处理数组
      }
  • 综合检测
    • 有时需要结合使用 typeofinstanceof
    • 例如:
      1
      2
      3
      if (typeof value === "object" && value !== null && value instanceof Array) {
      // 处理非 null 对象且是数组
      }
      理解 typeofinstanceof 的区别和用途,可以帮助你更准确地进行类型检测和对象管理。
由 Hexo 驱动 & 主题 Keep
访客数 访问量