本文共 2271 字,大约阅读时间需要 7 分钟。
在JavaScript中,每个函数都有一个prototype属性,这个属性指向函数的原型对象。
function Person(age) { this.age = age }Person.prototype.name = 'jeck'var son1 = new Person()var son2 = new Person()console.log(son1.name) //jeckconsole.log(son2.name) //jeck
上述例子中,函数的prototype指向了一个对象,这个对象就是调用构造函数时创建的实例的原型,也就是son1和son2的隐式原型。 原型的概念
:每一个javascript对象(除null外)创建的时候
,就会与之关联于一个对象
,这个对象
就是我们所说的原型
,每一个对象
都会从原型中“继承”属性和方法
。 构造函数和实例原型之间的关系:
__proto__
JavaScript中每个对象(除null外)都会有的属性,叫做__proto__
,这个属性会指向该对象的构造函数
的原型
。
function Person() { }var person = new Person();console.log(person.__proto__ === Person.prototype); // true
关系图:
每个原型都有一个constructor属性,指向该关联的构造函数。
function Person() { }console.log(Person===Person.prototype.constructor) //true
进一步关系图为:
function Person() { }var person = new Person();console.log(person.__proto__ == Person.prototype) // trueconsole.log(Person.prototype.constructor == Person) // trueconsole.log(Object.getPrototypeOf(person) === Person.prototype) // true
补充说明:Object.getPrototypeOf(对象) 获取对象的隐式原型
function Person() { }var person = new Person();console.log(person.constructor === Person); // true
当获取 person.constructor 时,其实 person 中并没有 constructor 属性,当不能读取到constructor 属性时,会从 person 的原型也就是 Person.prototype 中读取,正好原型中有该属性,所以:
person.constructor === Person.prototype.constructor
读取实例的属性时,如果找不到
,就会顺着查找与对象关联的原型
中的属性,如果还是查不到
,就去找原型的原型
,一直找到最顶层
为止。
function Person() { }Person.prototype.name = 'jeck';var person = new Person();person.name = 'tom';console.log(person.name) // tomdelete person.name;console.log(person.name) // jeck
在这个例子中,我们给实例对象 person 添加了 name 属性,当我们打印 person.name 的时候,结果自然为 tom。
但是当我们删除了 person
的 name
属性时,读取 person.name
,从 person
对象中找不到 name
属性就会从 person
的原型也就是 person.__proto__
,也就是 Person.prototype
中查找,幸运的是我们找到了 name
属性,结果为 jeck
。
用最原始的方式创建对象,那就是:
var obj = new Object();obj.name = 'jeck'console.log(obj.name) // jeck
其实原型对象就是通过 Object 构造函数
生成的,所以实例的 __proto__
指向构造函数的 prototype
,所以我们再更新下关系图:
null 表示“没有对象”,即该处不应该有值。
所以查找属性的时候查到 Object.prototype 就可以停止查找了。 最后一张关系图也可以更新为:
1.Object.getPrototypeOf(对象) 获取对象的隐式原型
2.对象 instanceof 构造函数 判断对象是否是这个函数构造出来的
3.Object.prototype.isPrototypeOf(对象) 判断Object.prototype是否在指定对象的原型链上
4.Object.Create(对象) 创建一个新对象,将新对象的隐式原型指向对象
5.Object.hasOwnProperty(属性) 判断属性是否是对象自身的属性
转载地址:http://nwezi.baihongyu.com/