js继承
原型讲解
普通对象只有__proto__属性指向其原型对象,只有构造函数构本体才具有Prototype属性
js的原型,每个构造函数都有一个原型对象,原型对象里面有一个指针constructor指向构造函数
每个示列里面都有一个__proto__指向原型对象, 从一个实列里找到他构造函数的原型对象,该原型对象又有构造他的原型对象__proto__
这样就形成了一条原型链。原型链的最顶端是Object.prototype.
function Person(){ //原型对象为Person.prototype
this.age = 20
}
console.log(Person.prototype.constructor ==Person) //原型对象里面有一个指针constructor指向构造函数Person
var person = new Person()
// person.say() //person里面有一个__proto__属性指向构造他的原型对象
console.log(person.__proto__ === Person.prototype)
//分析:person(__proto__) ----> Person.prototype(constructor) ---> Person 这就是原型关系
//原型链
GranFather.prototype.lastName = 'ghost'
GranFather.prototype.say = function(){
console.log(this.name) //谁调用this指向谁
}
function GranFather(){
}
var grand = new GranFather()
Father.prototype = grand
function Father(){
this.name="charry";
this.money = 100;
}
var father = new Father()
Son.prototype = father
function Son(){
this.age = 20
this.name ="liejian"
}
function daughter(){
this.age =10
this.name = 'mianmian'
}
var son = new Son()
console.log(son.lastName) //ghost
console.log(son.money) //100
console.log(son.name) //liejian
son.say() //liejian
继承
1 原型链继承
function Father(){
this.name = 'ghost',
this.age = 18,
this.say = function (){
console.log(this.name)
}
}
var father = new Father()
Son.prototype = father
function Son(){
this.age = 30
}
var son = new Son()
son.say() //__proto__ --->father 缺点:继承了过多没有用的属性
2 call/apply继承
function Father(name, age ,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
function Son(name, age, sex, tel, grade){
Father.call(this, name, age, sex);
this.tel = tel;
this.grade = grade;
}
var son = new Son('ghost', '18', '20', '18208891933', 100)
console.log(son.name) //ghost 调用Father这个工厂来生成, 所以不算标准继承, 每次继承要多走一个函数浪费性能
3 共享原型继承
function Father(){
}
function Son(){
}
Father.prototype.name = 'ghost'
Son.prototype = Father.prototype;
Son.prototype.age = 20;
var son = new Son()
console.log(son.name) //ghost
console.log(son.age) //20 共享原型继承的缺点是不能随便改动自己的原型,因为原型是一个对象存放的是引用值
var father = new Father()
console.log(father.age) //20 污染father
4 圣杯模式继承(最推荐使用的一种继承方法)
function Father(){
}
function F(){
name:'charry'
}
function Son(){
}
Father.prototype.name = 'ghost'
F.prototype.name = 'charry'
var f = new F()
Son.prototype = f
var father = new Father()
console.log(father.name) //ghost
var son = new Son()
console.log(son.name) //charry
//son.__proto__ -->f--->f.proto--->Father.prototype
5 封装圣杯继承的方法
function inherit(target, origin){
function F(){}
F.prototype = origin.prototype;
target.prototype = new F()
target.constructor = target
}
inherit(Son, Father)
var son = new Son()
console.log(son.name)