JS的属性判断方法

717 阅读2分钟

今天对于在原型链或者对象上存在的相关属性判断,我们对这几个方法单独抽离出来,分析一下各个方法,为以后在使用和阅读代码时更方便。

  • 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 判断属性是否在对象中,包括对象的自己属性和继承的属性