《JS高程第八章 第二部分》
继承
继承是面向对象oop编程中讨论最多的。许多oop语言都支持两种继承方式,接口继承和实现继承。
8.3.1原型链**(重点)**
JS高程的解释 每一个构造函数(star构造函数)都有一个原型对象(star原型对象),原型有一个函数(constructor)指回构造函数,而实例有一个内部指针指向原型(实例.proto)。如果原型是另一个类型的实例,那就意味着这个原型有一个内部指针(原型.proto)指向另一个原型,相应的另一个原型也有一个指针(原型.constructor)指向另一个构造函数。这样就在实例和原型之间构造了一条原型链
个人更推荐MDN文档的解释
在谈到继承的时候,JavaScript只有一种结构,那就是对象。每一个对象的实例都有一个私有属性(proto)指向它的构造函数的原型(prototype).该原型对象也有一个自己的原型对象(proto),层层向上直到一个对象的原型对象为null。根据定义,null没有原型,并作为原型链的中最后一个环节。换言之_proto_指到null就没了(这不就是链表吗?_proto_作为指向下一个的指针,然后每个节点有一个constructor函数指向构造函数,构造函数通过prototype指回节点)
下面代码用火狐打开
let Star=function(Name,Age){
this.age=Age;
this.name=Name;
}
let jackMa=new Star("马云",58);
console.log(jackMa); //返回Object{name:"马云",age:58};
console.log(jackMa.constructor);//这里返回构造函数 function Star(Name,Age){...} 继承了Star
console.log(jackMa._proto_); //这里返回对象{}里面有constructor和prototype
console.log(jackMa.prototype); //返回undefined
console.log(jackMa.__proto__.constructor); //返回构造函数function Star(Name,Age)
console.log(jackMa.__proto__.prototype); //返回undefined
console.log(jackMa.__proto__.__proto__) //返回对象Object,所有的对象都继承于Object
console.log(jackMa.__proto__.__proto__.prototype);//返回undefined
console.log(jackMa.__proto__.__proto__.constructor); //返回 构造函数 function Object()
console.log(jackMa.__proto__.__proto__.__proto__); //返回 null
上面实例对象constructor指向的构造函数都继承于Star的构造函数,Star的构造函数继承于function Object()
2、原型与继承
原型与实例的关系可以通过两种方式来确定。第一种方式是使用instanceof操作符,如果一个实例的原型链中出现过相应的构造函数,则instancof返回true,否则返回false
MDN 1、继承属性
let f=function(){
this.a=1;
this.b=2;
}
let o=new f();
f.prototype.b=3;
f.prototype.c=4;
/*不要直接上面这样定义属性,会打破原型链*/
console.log(f); //返回 {b:3,c:4}
console.log(o); //返回 {a:1,b:2}
console.log(o._proto_); //返回 {b:3,c:4}
console.log(o._proto_._proto_);//返回 Object
console.log(o._proto_.proto_._proto_); //返回null
console.log(f.b); //返回undefined
console.log(f.c); //返回4
MDN 2、继承方法
在JavaScript中,并没有其他语言那样的方法,任何函数都可以添加到对象上作为对象的属性。函数的继承与其他属性的继承没有差别,包括“属性遮蔽”相当于方法重写
let o={
a:2,
m(){
return this.a+1;
}
};
console.log(o.m()); //返回3
let p=Object.create(o); //ES6之前的写法
let p1=new o(); //ES6的写法
p.a=4;
console.log(p.m()); //返回5
MDN 3、在Javascript中使用原型
function doSth(){}
console.log(doSth.prototype); //这里返回对象{constructor:f},constructor构造函数指向的是f doSth()
//和声明函数的方式无关
//JavaScript中的函数永远有一个默认原型属性
var doSth=function(){};
console.log(doSth); //这里返回对象{constructor:f},constuctor指向的是f()
//
MDN 4、给原型对象添加属性
function doSomthing(){}
doSomthing.prototype.foo="bar";
doSomthing.prototype.tel=110;
console.log(doSomthing.prototype); //这里返回对象doSth里面有两个属性 1、foo和2、tel
MDN 5、通过new来创建实例
function doSth(){
}
doSth.prototype.thing="加班";
let doSthInstacne=new doSth();
doSthInstance.prototype.name="JackMa";
console.log(doSthInstance);//这里返回对象
/*
doSth{
name:"JackMa",
_proto_:{
thing:"加班"
constructor:f doSth(){}
_proto_:Object
}
}
*/