原型原型链记住这三点就够了
p.__proto__ === Person.prototype
p.constructor === Person.prototype.constructor
Person.prototype.constructor === Person
原型对象 protoype
- prototype:叫原型对象,是每一个构造函数都有的一个属性,该属性是以对象的形式存在的(原型对象)
function Person(uname) {
this.uname = uname;
this.sing = function () { }
}
// Person的实例化对象
const obj1 = new Person("zs");
const obj2 = new Person("ls");
// 两个实例化对象的sing方法不是同一内存地址
console.log(obj1.sing == obj2.sing);//false
function Person(uname) {
this.uname = uname;
}
// Person的原型添加eat方法
Person.prototype.eat = function () { }
// Person的实例化对象
const obj1 = new Person("zs");
const obj2 = new Person("ls");
// 两个实例化对象的方法来自同一内存地址
console.log(obj1.eat == obj2.eat);//true
- 作用:通过原型对象设置构造函数的公共方法,解决内存浪费问题
- 语法:构造函数名.prototype.方法名=function () { }
对象原型__proto__
实例化对象身上有一个属性__proto__,属性值是一个对象,该对象的地址指向其构造函数的原型对象prototype
console.log(person.__proto__ == Person.prototype)//true
constructor构造函数
- constructor:每一个原型对象和对象原型身上都有constructor属性
- 作用:通过constructor构造函数可以知道该对象属于哪个构造函数
console.log( person.__proto__.constructor == Person )//true
原型链
- 1. 原型链的形成:
每一个对象都有一个__proto__属性,地址指向其构造函数的原型对象prototype,即为同一个对象,构造函数的原型对象也是一个对象,也有__proto__属性,这样一层一层的就形成了原型链
- 2. __proto__的意义:
就在于给对象寻找属性和方法提供了一个方向,但是他是一个非标准属性,我们在实际开发过程中,不能直接使用,只需要知道它的指向和该对象的构造函数的原型对象是同一个地址
- 3. 对象的属性/方法查找机制:
- 如果访问一个对象的属性/方法时,先在其自身上找
- 如果没有,就访问它的原型对象(就是__proto__指向的构造函数的原型对象prototype)
- 如果还没有,就查找原型对象的原型(Person.prototype.__proto__ == Objecr.prototype)
- 依次类推,一直找到Object为止(null)
- 如果还没有,那么属性值为undefined,方法报错为XXX.a is not a function