在JavaScript建立对象(二)——构造函数模式中,咱们说过可使用对象的constructor
属性判断对象的类型:p1.constructor === Person
,可能当时就有细心的读者会想,咱们并无给这个对象添加过constructor
,这个属性是从哪儿来的呢?讲过原型以后,咱们知道这个属性是原型中的,因此通常重写原型时也都会把constructor
补上。javascript
咱们能够经过像下面的代码同样,切断实例与原型的关系:java
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; } Person.prototype = { constructor: Person, sayName: function(){ console.log(this.name); } } var p1 = new Person('张三', 18, 'JavaScript'); var p2 = new Person('李四', 20, 'Java'); //切断p1与Person原型的关系 p1.__proto__ = null; console.log(p1.constructor === Person);//false console.log(p2.constructor === Person);//true
如代码所示,切断p1
与Person
原型的关系后,p1.constructor === Person
的结果为false
,constructor
属性失效了。函数
工厂模式没办法使用这种方法判读对象的类型,为何呢?由于使用工厂模式建立的对象本质上只是一个Object
类型,它们的constructor
属性都是Object
,因此没办法经过constructor
区分对象的类型。this
以前咱们还使用过instanceof
判断对象的类型,该方法不只能够判断对象自己的类型,还能判断出父类型,其实这个关键字也是依赖原型的。仍是以上述p1
为例,看下面代码:prototype
console.log(p1 instanceof Person);//false console.log(p1 instanceof Object);//false
如代码所示,p1
的原型被置为null
后,instanceof
也失效了。设计
这是原型对象上的一个方法,用于判断对象的原型。那么问题又来了,咱们明明重写了Person
的原型,而且也没有声明isPrototypeOf()
方法,这个方法是从哪来的呢?这就涉及到原型链的知识了,之后再讲。仍然以上述p1
、p2
为例,看下面代码:code
console.log(Person.prototype.isPrototypeOf(p1));//false console.log(Person.prototype.isPrototypeOf(p2));//true
如代码所示,p1
切断了与原型的关系,结果为false
。p2
的原型就是Person.prototype
,结果为true。对象
这是Object
上的一个方法,能够直接获取到实例的原型对象,看下面代码:ip
console.log(Object.getPrototypeOf(p1) === Person.prototype);//false console.log(Object.getPrototypeOf(p1));//null console.log(Object.getPrototypeOf(p2) === Person.prototype);//true console.log(Object.getPrototypeOf(p2));//{constructor: ƒ, sayName: ƒ}
p1
的原型被设置为了null
,获取的结果也就是null
。p2
正常获取到了原型。原型链
本文参考《JavaScript高级程序设计(第三版)》