【6期】彻底搞懂JS原型继承之——typeof与instanceof

本文结合代码讲解,争取一次理解透,前提是需要掌握__proto__ 和prototype。__proto__ 和prototype关系转换可以参考上一片文章《__proto__、prototype、constructor》


typeof

用途:typeof operand || typeof(operand),返回一个字符串,表示未经计算的操作数的类型。

区分范围number、undefined、symbol、string、function、boolean、object 这七种数据类型

无法区分:判断不出object 属于哪一种 object;将null 判断为 object。

使用 new 操作符

除 Function 外的所有构造函数的类型都是 'object'

typeof new String('String'); // 返回 'object'
typeof new Number(100); // 返回 'object'
typeof new Function(); // 返回 'function'

语法中的括号

typeof是单元运算符,运算优先级高于双元运算符,因此不加括号,会优先计算类型值==>括号有无将决定表达式的类型

var iData = 99;

typeof iData + ' Wisen'; // 'number Wisen'
typeof (iData + ' Wisen'); // 'string'

错误

被声明之前对块中的 let 和 const 变量使用 typeof 会抛出一个 ReferenceError

注意一些易错的场景

// 数值
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number';

// 字符串
typeof (typeof 1) === 'string'; // typeof 总是返回一个字符串
typeof String(1) === 'string';

// 布尔值
typeof Boolean(1) === 'boolean'; // Boolean() 会基于参数是真值还是虚值进行转换
typeof !!(1) === 'boolean'; // 两次调用 ! (逻辑非) 操作符相当于 Boolean()


// Symbols
typeof Symbol.iterator === 'symbol';


// 对象
// 使用 Array.isArray 或者 Object.prototype.toString.call区分数组和普通对象
typeof [1, 2, 4] === 'object';
typeof new Date() === 'object';
typeof /regex/ === 'object'; // 历史结果请参阅正则表达式部分

// 下面的例子令人迷惑,非常危险,没有用处。避免使用它们。
typeof new Boolean(true) === 'object';
typeof new Number(1) === 'object';
typeof new String('abc') === 'object';
typeof null;//"object"

// 函数
typeof function() {} === 'function';
typeof class C {} === 'function'
typeof Math.sin === 'function';

注意:JS的7种基本数据类型别混淆了:null,undefined,Number, String,Boolean,Object,Symbol

typeof null === "object"原理

JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 "object"。


instanceof

object instanceof constructor

用途:检测 constructor.prototype 是否存在于参数 object 的原型链上,明确地确认对象为某特定类型。

结合原型链典例

function C() {}
function D() {}
let o = new C()

o instanceof C
// true, o.__proto__  === C.prototype

o instanceof D // false, D.prototype is nowhere in o's prototype chain

o instanceof Object
// true, o.__proto__===C.prototype; C.prototype.__proto__ === Object.prototype

C.prototype instanceof Object 
// true, C.prototype.__proto__ === Object.prototype

C.prototype = {} 
let o2 = new C() 
o2 instanceof C  
// true, o2.__proto__ ===C.prototype

o instanceof C  
// false, because C.prototype is nowhere in o's prototype chain anymore
  
D.prototype = new C()  // add C to [[Prototype]] linkage of D
let o3 = new D() 
o3 instanceof D        
// true , o3.__proto__ === D.prototype
o3 instanceof C        
// true o3.__proto__ === D.prototype, D.prototype.__proto__ = C.prototype
console.log(Object instanceof Object);
//true Object.__proto__ === Function.prototype;Function.prototype__proto__ === Object.prototype

console.log(Function instanceof Function);
//true ,Function.__proto__ === Function.prototype

console.log(Number instanceof Number);
//false ,Number.__proto__ === Function.prototype

console.log(String instanceof String);//false ,理由同7

console.log(Function instanceof Object);
//true ,Function.__proto__ === Function.prototype,Function.prototype__proto__ === Object.prototype

console.log(Foo instanceof Function);//true ,理由同7
console.log(Foo instanceof Foo);//false,理由同7
let simpleStr = 'This is a simple string'
let myString  = new String()
let newStr    = new String('String created with constructor')
let myDate    = new Date()
let myObj     = {}
let myNonObj  = Object.create(null)

simpleStr instanceof String  // false, simpleStr is not an object
myString  instanceof String  // true,myString.__proto__ === myString.prototype
newStr    instanceof String  // true,myString.__proto__ === myString.prototype
myString  instanceof Object  // true,myString.prototype.__proto__===Object.prototype

myObj    instanceof Object   // rtrue, myObj.__proto__===Object.prototype
({})     instanceof Object   // true,理由同13
myNonObj instanceof Object   // false, prototype is end of prototype chain (null)

myString instanceof Date     // returns false

myDate instanceof Date      // returns true
myDate instanceof Object    // returns true
myDate instanceof String    // returns false

instanceof 原理实现

function instance_of(obj, constructor) {
 var constructor = constructor.prototype;
 obj = obj.__proto__;
 while (true) { 
   if (obj === null) 
     return false; 
   if (obj === constructor)
     return true; 
   obj = obj.__proto__;  // 逐级查找原型链
 } 
}

 

猜你喜欢

转载自blog.csdn.net/m0_38073011/article/details/108511266
今日推荐