原型对象及原型链
- 一、原型
- 1、原型定义
- 1.1案例
- 二、原型链
- 1、构造函数、原型和实例的关系
- 2、prototype与_proto_的关系
- 2.1案例
- 3、原型链定义
- 3.1案例1
- 案例1解析图解(重点、重点、重点,重要的事说3遍)
- 3.2案例2
- 3.3案例3
- 3.4案例4
- 4、对象的成员操作和原型对象的操作
- 4.1案例1
一、原型
1、原型定义
- 所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象
- 所有函数都有一个prototype(原型)属性,属性值是一个普通的对象
- 所有引用类型的__proto__属性指向它构造函数的prototype
1.1案例
function fn() {}
var f1 = new fn()
console.log(f1.__proto__ == fn.prototype);
var arr1 = [1, 3, 4, 5] //new Array()
console.log(arr1.__proto__ === Array.prototype)
案例1结果
二、原型链
1、构造函数、原型和实例的关系
- 构造函数、原型和实例的关系
a、构造函数都有一个属性prototype,这个属性是一个对象,是Object的实例;
b、原型对象prototype里有一个constructor属性,该属性指向原型对象所属的构造函数;
c、实例对象都有一个__proto__属性,该属性指向构造函数的原型对象;
obj.proto__===Object.prototype
2、prototype与_proto_的关系
- prototype与_proto_的关系
a、prototype是构造函数的属性;
b、__proto__是实例对象的属性;
c、两者都指向同一个对象;
2.1案例
function fn() {}
var f1 = new fn()
console.log(f1.__proto__ == fn.prototype);
var arr1 = [1, 3, 4, 5] //new Array()
console.log(arr1.__proto__ === Array.prototype)
结果:
3、原型链定义
当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。
3.1案例1
function Qingwa(leg) {
//var leg=4
this.leg = leg
}
var kedou = new Qingwa(4)
console.log(kedou.leg);
console.log(kedou.name);
案例1结果:
案例1解析图解(重点、重点、重点,重要的事说3遍)
3.2案例2
Object.prototype.life = 1//所有对象的原型对象都具有life=1
Function.prototype.life = 2//所有函数的原型对象都具有life=2
Object.prototype.life = 1
Function.prototype.life = 2
var fn = new Function('this.name="karen";')
var f1 = new fn()
console.log(f1.name, f1.life);
console.log(fn.life, fn.name);
案例2结果:
3.3案例3
Object.prototype.life = 1//所有对象的原型对象都具有life=1
Function.prototype.life = 2//所有函数的原型对象都具有life=2
Object.prototype.life = 1
var fn = new Function('this.name="karen";')
var f1 = new fn()
console.log(f1.life);
console.log(fn.life);
案例3结果
3.4案例4
Object.prototype.life = 1//所有对象的原型对象都具有life=1
Function.prototype.life = 2//所有函数的原型对象都具有life=2
Function.prototype.life = 1
function fn() {
this.name = "karen"
}
var f1 = new fn()
console.log(f1.life);
console.log(fn.life);
案例4结果:
4、对象的成员操作和原型对象的操作
4.1案例1
function Parent() {
this.a = 1;
this.b = [1, 2, this.a];
this.c = {
demo: 5
};
this.show = function () {
console.log(this.a, this.b, this.c.demo);
}
}
function Child() {
this.a = 2;
this.change = function () {
this.b.push(this.a);
this.a = this.b.length;
this.c.demo = this.a++;
}
}
Child.prototype = new Parent(); //{a:1,b:[1,2,1],c:{demo:5},show:f,__proto__:{}}
var parent = new Parent(); //{a:1,b:[1,2,1],c:{demo:5},show:f,__proto__:{}}
var child1 = new Child(); //111 {a:2,change:f,__proto__:{a:1,b:[1,2,1],c:5,show:f}}
var child2 = new Child(); //222 {a:2,change:f,__proto__:{a:1,b:[1,2,1],c:5,show:f}}
child1.a = 11; //111 {a:11,change:f,__proto__:{a:1,b:[1,2,1],c:5,show:f}}
child2.a = 12; //222 {a:12,change:f,__proto__:{{a:1,b:[1,2,1],c:5,show:f}}}
parent.show(); //1 [1,2,1] 5 {a:1,b:[1,2,1],c:5,show:f,__proto__:{}}
child1.show(); //11 [1,2,1] 5 {a:11,change:f,__proto__:{{a:1,b:[1,2,1],c:{5},show:f}}}
child2.show(); //12 [1,2,1] 5 {a:12,change:f,__proto__:{{a:1,b:[1,2,1],c:{5},show:f}}}
child1.change(); //{a:4,change:f,__proto__:{{a:1,b:[1,2,1,11],c:{4},show:f}}} //完了a再加1 a=5
console.log(child1); //{a:5,change:f,__proto__:{{a:1,b:[1,2,1,11],c:{demo:4},show:f}}}
child2.change(); //{a:5,change:f,__proto__:{{a:1,b:[1,2,1,11,12],c:{demo:5},show:f}}} //完了a再加1 a=6
console.log(child2); //{a:6,change:f,__proto__:{{a:1,b:[1,2,1,11,12],c:{demo:5},show:f}}}
parent.show(); //1 [1,2,1] 5
child1.show(); //5 [1 2 1 11 12] 5
console.log(child1); //{a:5,change:f,__proto__:{{a:1,b:[1,2,1,11,12],c:{demo:5},show:f}}
child2.show(); //6 [1,2,1,11,12] 5
console.log(child2); //{a:6,change:f,__proto__:{{a:1,b:[1,2,1,11,12,],c:{demo:5},show:f}}}
案例1结果: