1.构造函数创建对象
function Person(){}
let person = new Person()
let person1 = new Person()
person.name = 'lisa'
console.log(person.name)
console.log(person1.name)
Person 为构造函数,使用new 创建出来 person 、person1 实例对象
2.函数属性 prototype
每个函数都有prototype属性
函数的prototype属性指向一个对象,是通过构造函数new出来person 和 person1实例的原型
3.对象的__proto__属性
每个对象都有__proto__属性(除了null),该属性指向对象的原型
console.log(person.__proto__ === Person.prototype)
4.constructor 属性
结合第2点和第3点,构造函数的prototype属性 和对象的__proto__ 都指向对象的原型,
那原型是否有属性指向 构造函数 和 实例 呢?
原型的constructor 属性 指向 关联的构造函数; 无属性指向实例(因为构造函数可创建多个实例)
console.log(Person.prototype.constructor === Person)
到此构造函数、实例 、原型三者关系已经了解
5.原型链的理解
每个对象在读取属性时先检查其私有属性,如果存在则返回私有属性,不存在则向person.__proto__原型对象查找。
原型的原型(原型对象就是通过 Object 构造函数生成的),原型链最顶端为null。
6.原型继承
对象之间的关联性,如果每个对象都是独立的属性和方法,而且多个对象内属性和方式是公共相同的,那么会严重消耗资源,所以会使用到原型继承
实例1:构造函数继承(指向对应的原型对象)
function An(){}
An.prototype.name = 'lili'
An.prototype.run = function(){
console.log(this.name + 'run')
}
function Bn(){}
Bn.prototype = An.prototype
Bn.prototype.constructor = Bn
//注意:原型指向后,Bn的constructor也指向了An,这时候需要重新指向关联的构造函数
let b = new Bn()
console.log(b.name)
存在的问题:Bn的原型对象修改后会直接反应到An的原型对象
Bn.prototype.name ='lisa'
let a = new An()
console.log(a.name)
调整:Bn的原型对象直接指向An的实例
function An(){}
An.prototype.name = 'lili'
An.prototype.run = function(){
console.log(this.name + 'run')
}
function Bn(){}
Bn.prototype = new An()
Bn.prototype.constructor = Bn
//注意:原型指向后,Bn的constructor也指向了An,这时候需要重新指向关联的构造函数
Bn.prototype.name = 'lisa'
let b = new Bn()
let a = new An()
console.log(b.name,a.name)
实例2:对象继承
let old = {name:"old",age:18}
let one = {}
one.__proto__ = old //指向old,没找到则通过__proto__向上查找
console.log(one.name)
one.__proto__.name = 'new'
console.log(one.name,old.name)
问题:修改one的原型直接影响了old
方案:Object.create()可以通过指定的原型对象创建一个新的对象,新的对象不会影响原型
let old = {name:"old",age:18}
let one = {}
one.__proto__ = Object.create(old)
one.__proto__.name = 'new'
console.log(one.name,old.name)
7.原型的方法
设置原型对象方法
- obj.__proto__=prototypeObj
- Object.setPrototypeOf(obj, prototypeObj)
- Object.create(prototypeObj)
检测原型:使用 isPrototypeOf() 方法可以判断该对象是否为参数对象的原型