6. 原型、原型链
- 每一个函数都有一个天生自带的属性 prototype[显示原型], 称为该函数的原型对象
- 每一个prototype原型对象上,都有一个天生自带的属性 constructor[构造器],指向当前函数本身
- 每一个对象都有一个天生自带的属性 proto[隐式原型],指向所属类[构造函数]的原型对象
6-1. 原型图示
function Person(name,age){
this.name = name;
this.age = age;
}
var p1 = new Person('张三', 19);
console.log(p1.__proto__ === Person.prototype);
console.log(Person === Person.prototype.constructor);
// dir dictionary 目录
console.dir(Person);
console.log(p1);
6-2.原型链
什么是原型链?
沿着对象的__proto__在上级原型对象上查找属性或方法的过程叫做原型链
function Person(name,age){
this.name = name;
this.age = age;
// say方法会在每一个实例对象上都有一个,浪费内存空间
this.say = function(){
console.log('我的名字是: ' + this.name + ', 我的年龄是: ' + this.age);
}
}
// 希望每一个实例对象能共用同一个方法,该方法或属性需要定义在类[构造函数的]原型对象上
Person.prototype.eat = function(){
console.log(this.name + '正在吃饭');
}
var p1 = new Person('张三',19);
var p2 = new Person('李四',20);
p1.say();//
p2.say();
p1.eat();// 张三正在吃饭
p2.eat();// 李四正在吃饭
console.log('p1.eat === p2.eat: ',p1.eat === p2.eat);
console.log(p1.say === p2.say); // false
console.log('Person.prototype: ',Person.prototype)
console.log(Person.prototype.__proto__ === Object.prototype)
console.log(p1.toString());
console.log(p1.toString === p2.toString);
6-3.原型链重讲绘图
/**
* 原型
* 1. 每一个函数都有一个天生自带的属性prototype,他是函数的显示原型对象
* 2. 每一个prototype显示原型对象,都有一个天生自带的属性 constructor,值是当前函数
* 3. 每一个实例化出来的对象,都有一个天生自带的属性__proto__,指向所属类的原型对象
*
* 原型链:
* 当使用一个对象的属性或方法时,如果自身私有属性没有,沿着__proto__向上查找,如果还没有,继续沿着__proto__向上查找,直到找到Object.prototye为止,称为原型链
*/
function Person(name, age){
// 私有属性和方法
this.name = name;
this.age = age;
this.say = function(){}
}
var p1 = new Person('赵敏',20);// p1 有自己的name age say
var p2 = new Person('张无忌',21);// p2 也有自己的name age say
console.log(p1.say === p2.say);// false;
// 定义所有实例对象都可以访问的公有属性和方法,需要定义在该对象的构造函数的原型对象上
Person.prototype.eat = function(){// 公有的方法,p1,p2等所有实例对象共用
console.log('eat')
}
Person.prototype.className = '230222'; // 公有属性 p1,p2等所有Person实例对象都可以共用