JS基础之继承
继承 一个实例想要试用父亲构造函数的属性和方法
一、继承方法之原型继承
// 准备父类
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.eat = function(){
console.log('eating')
}
/*
Student.prototype = {name: 'tom', age: 20, __proto__:Person.prototype}
继承方法之原型继承
- 通过改变原型链的方式实现继承
- 核心思路 父亲的实例作为子类的prototype
- 好处 可以实现继承父亲的属性和父亲原型伤的
- 缺点 传参分开传、继承的属性不在自己的实例上
*/
// 子类
function Student(name,age,sex){
this.sex = sex;
}
Student.prototype = new Person('Leo',20);
var s = new Student('man');
console.log(s)
二、继承方法之构造函数继承
// 准备父类
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.eat = function(){
console.log('eating')
}
/*
Student.prototype = {name: 'tom', age: 20, __proto__:Person.prototype}
继承方法之借用继承(构造函数继承)
- 构造函数继承
- 核心思路 在子类的构造函数中,使用父类的构造函数.call(this,...)
- 好处 继承的属性在自己实例上,传参不需要分开传
- 缺点 父类的原型上的内容不能继承
*/
// 子类
function Student(name,age,sex){
this.sex = sex;
// Person也是函数。可以直接调用,直接调用Person函数中的this是window
// 通过call调用弗雷构造函数,并且改变Person函数中的this的指向为student实例
Person.call(this,name,age)
}
Student.prototype = new Person();
Student.prototype.study = function(){
console.log('studing')
}
var s = new Student('Leo',20,'man');
s.eat();
console.log(s)
三、继承方法之组合继承
// 准备父类
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.eat = function(){
console.log('eating')
}
// 子类
function Student(name,age,sex){
this.sex = sex;
// Person也是函数。可以直接调用,直接调用Person函数中的this是window
// 通过call调用弗雷构造函数,并且改变Person函数中的this的指向为student实例
Person.call(this,name,age)
}
Student.prototype = new Person();// {name:undfined,age:undfined,__proto__:Person.prototype}
Student.prototype.study = function(){
console.log('work hard')
}
Student.prototype.constructor = Student;
/*
Student.prototype = {name: 'tom', age: 20, __proto__:Person.prototype}
继承方法之借用继承----组合继承
- 原型继承+借用继承
- 核心思路
- 好处 继承的属性在自己实例上,传参不需要分开传;父类的原型上的内容能继承
- 缺点 子类的constructor指向的是父类
*/
var s = new Student('Leo',20,'man');
s.eat();
s.study();
console.log(s);
四、继承方法之拷贝继承--for in
// 准备父类
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.eat = function(){
console.log('eating')
}
// 子类
function Student(name, age, sex){
this.sex = sex;
var p = new Person(name, age)
for(var k in p){
Student.prototype[k] = p [k]
}
}
/*
Student.prototype = {name: 'tom', age: 20, __proto__:Person.prototype}
继承方法之拷贝继承
- for in继承
- 核心思路 对一个父亲实例,然后对其for in 把父实例及其原型的内容复制给子类的原型上
- 好处 传参不需要分开传;父类的属性和原型上的内容能继承,constructor正常指向
- 缺点 继承的属性不在自己的实例上,不能继承不能被枚举的属性,会一直遍历到Object.prototype
*/
Student.prototype = new Person('tom',20,"男")
var s = new Student('man');
console.log(s)
五、继承方法之寄生继承
// 准备父类
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.eat = function(){
console.log('eating')
}
// 寄生继承-寄生实例
// 子类
function Student(name, age, sex){
this.sex = sex;
var p = new Person(name, age)
return p;
}
/*
Student.prototype = {name: 'tom', age: 20, __proto__:Person.prototype}
继承方法之寄生继承
- 寄生实例
- 核心思路 var p = new Person(name, age); return p;
- 好处 父亲的属性或原型东西都可以继承
- 缺点 new 子类的时候没有自己的的属性和自己原型的东西
*/
var s = new Student('tom',20,"男");
console.log(s)
console.log(s instanceof Person) // true
// 寄生继承-寄生原型
// 子类
function Student1(name, age, sex){
this.name = name;
this.age = age;
this.sex = sex;
}
Student1.prototype = Person.prototype;
Student1.prototype.study = function(){
console.log('work hard')
}
/*
Student.prototype = {name: 'tom', age: 20, __proto__:Person.prototype}
继承方法之寄生继承
- 寄生原型
- 核心思路 Student1.prototype = Person.prototype;
- 好处 父亲的属性或原型东西都可以继承,自己的属性或方法都可以添加
- 缺点 父亲属性不能被继承,此外修改子类原型,父类实例也受影响
*/
var s1 = new Student1('tom',20,"男");
s1.eat();
s1.study();
console.log(s1)
六、继承方法之寄生组合式继承
借用继承+寄生继承+原型继承+第三方构造函数
// 准备父类
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.eat = function(){
console.log('eating')
}
// 寄生组合式继承
// 子类
function Student(name, age, sex){
this.sex = sex;
// 借用继承 实现继承父类的属性
Person.call(this,name, age)
}
(function(){
function A(){
}
A.prototype = Person.prototype; // 寄生原型
// var a = new A(); //a实例能够继承Person原型的东西
// Student.prototype = a; // a==={__proto__: Person.prototype} 原型继承
Student.prototype = new A();
})();
Student.prototype.love = function(){
console.log('loving')
}
var s = new Student('tom',20,"男");
console.log(s)// {name: 'tom',age:20,sex:'男',__proto__: {__proto__:Person.prototype}}
s.eat();
/*
Student.prototype === new A()
A.prototype === Person.prototype
s.__proto__
*/