type of
typeof 操作符最适合用来判断一个变量是否为原始类型,更确切地说,它是判断一个变量是否为字符串、数值、布尔值或 undefined 的最好方式,如果值是对象或 null ,那么 typeof 返回 “object”
let s = "Nicholas";
let b = true;
let i = 22;
let u;
let n = null;
let o = new Object();
console.log(typeof s); // string
console.log(typeof i); // number
console.log(typeof b); // boolean
console.log(typeof u); // undefined
console.log(typeof n); // object
console.log(typeof o); // object
instanceof
instanceof 用来判断引用数据类型,,返回ture 或 false
instanceof 运算符可以用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
如果用 instanceof 检测原始值,则始终会返回 false ,因为原始值不是对象
// object 某个实例对象
// constructor 某个构造函数
result = variable instanceof constructor
那我们就可以理解为:instanceof 运算符用来检测 constructor.prototype 是否存在于参数 obejct 的原型链上
// 定义构造函数
function C(){}
function D(){}
var o = new C();
o instanceof C; // true
o instanceof D; // false
o instanceof Object; // true
具体判断
console.log(person instanceof Object); // 变量 person 是 Object 吗?
console.log(colors instanceof Array); // 变量 colors 是 Array 吗?
console.log(pattern instanceof RegExp); // 变量 pattern 是 RegExp 吗?
那么实现原理是什么呢?
instanceof 的内部实现机制是:通过判断参数对象的原型链上是否能找到构造函数的 prototype,来确定 instanceof 的返回值。
我们可以使用 Object.getPrototypeOf(obj) 来判断是否等于构造函数的 prototype;也可以使用 Object.prototype.isPrototypeOf(obj) 返回值来判断,比如上述例子:
o instanceof C; // true
// Object.getPrototypeOf(o) === C.prototype
o instanceof Object; // true
// Object.prototype.isPrototypeOf(o) 返回 true
当然我们也可以使用其他方法来实现:
function instance_of(obj, cons) {
var consPrototype = cons.prototype;
var objProrotype = obj.__proto__;
while(true) {
if (objProrotype === null) {
return false;
}
if (consPrototype === objProrotype) {
return true
}
// 原型链向上查找
objProrotype = objProrotype.__proto__;
}
}
怎么去实现一个 instanceof 的功能呢?
那根据上述所讲,我们自己去实现一个 instanceof 方法,有三种方式:
- Object.getPrototypeOf(obj)——返回指定对象的原型(内部 [[Prototype]] 属性的值)
- Object.prototype.isPrototypeOf(obj)——测试一个对象是否存在于另一个对象的原型上
- obj.proto——使用非标准的 proto 的伪属性
源码实现
1. 使用 Object.getPrototypeOf(obj)
function instance_of(o, c) {
let op = Object.getPrototypeOf(o);
const cp = c.prototype;
while(true) {
if (!op) {
return false
}
if (op === cp) {
return true
}
op = Object.getPrototypeOf(op);
}
}
- Object.prototype.isPrototypeOf(obj)
function instance_of(o, c) {
return c.prototype.isPrototypeOf(o);
}
obj.proto
function instance_of(o, c) {
let op = o.__proto__;
const cp = c.prototype;
while(true) {
if (op === null) {
return false
}
if (op === cp) {
return true
}
op = op.__proto__;
}
}