今天对于在原型链或者对象上存在的相关属性判断,我们对这几个方法单独抽离出来,分析一下各个方法,为以后在使用和阅读代码时更方便。
- typeof
- isPrototypeOf()
- instanceOf()
- hasOwnProperty()
- in
typeof()
typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
eg1:
typeof 42 // "number"
typeof 'chencc' // "string"
typeof true // "boolean"
typeof chenhh // "undefined"
typeof null // "object"
typeof {a: 1} // "object"
typeof [1, 2, 3] // "object"
typeof new Date() // "object"
typeof function(){} // "function"
typeof new Function() // "function"
typeof new Object() // "object"
typeof new Array() // "object"
typeof Array // "function"
typeof Object // "function"
Object.prototype.isPrototypeOf()
在 MDN 中对于该方法的解释是 isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上。
eg1:
function Fun1 (){}
function Fun2 (){}
function Fun3 (){}
Fun2.prototype = Object.create(Fun1.prototype)
// Fun2.prototype.__proto__ === Fun1.prototype
Fun3.prototype = Object.create(Fun2.prototype)
// Fun3.prototype.__proto__ === Fun2.prototype
var fun = new Fun3()
// fun.__proto__ === Fun3.prototype
Fun3.prototype.isPrototypeOf(fun) // true
// 由上面可以看到,fun.__proto__上面是 Fun3.prototype
fun.__proto__.__proto__ === Fun2.prototype
Fun2.prototype.isPrototypeOf(fun) // true
fun.__proto__.__proto__.__proto__ === Fun1.prototype // true
Fun1.prototype.isPrototypeOf(fun) // true
Fun1.__proto__ === Function.prototype // true
Function.prototype === Function.__proto__
Function.prototype.__proto__ === Object.prototype
Function.__proto__.__proto__ === Object.prototype
Fun1.__proto__.__proto__ === Object.prototype // true
Object.prototype.isPrototypeOf(fun)
上面这个例子是基于 MDN 上的demo 做了个整个流程的分析。我们可以从上面明确的是 isPrototypeOf 是用来判断一个对象是否存在于另一个对象的原型上的。我们通常会用来判断对象是否继承自某个对象下。
hasOwnProperty
再 MDN 中解释是,hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)(非继承)
eg1:
var obj = new Object()
obj.name = 'chencc'
obj.hasOwnProperty('name') // true
delete obj.name // true
obj.hasOwnProperty('name') // false
Object.hasOwnProperty('toString') // false
Object.prototype.hasOwnProperty('toString') // true
从上面例子,我们知道 hasOwnProperty 判断的是当前对象自身属性中是否存在,而不是再原型链上可以找到的属性,或者说是继承来的属性。
instanceof ()
在 MDN 中对于该方法的解释是 instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
上面这个理解来说就是用来检测是不是对象的实例。
eg1:
function Foo () {}
let foo = new Foo()
foo.__proto__ === Foo.prototype
Foo.prototype.__proto__ === Object.prototype
foo.__proto__.__proto__ === Object.prototype
foo instanceof Foo // true
foo instanceof Object // true
从上面我们就可以知道 instanceof 的实现原理了
eg2:
function _instanceof (L, R) {
var O = R.prototype // 获取R的prototype属性
L= L.__proto__ // 找到 L 的 __proto__
while (true) {
if (L ===null)
return false
if (O === L)
return true
L = L.__proto__ // 只要没有找到顶部,就一直找
}
}
in
in 操作符用来判断某个属性属于某个对象,可以是对象的直接属性,也可以是通过 prototype 继承的属性
eg1:
// 对象的 in 操作
var obj = {
name: 'chencc'
}
'name' in obj // true
'toString' in obj // true
obj.__proto__ === Object.prototype
Object.prototype.toString
总结
- typeof 是用来判断数据的类型
- isPrototypeOf() 是用来判断一个对象是否存在于另一个对象的原型链上
- instanceof用于检测构造函数的 prototype 是否在实例的原型链上
- in 判断属性是否在对象中,包括对象的自己属性和继承的属性