ES5没有类,所以函数即是类,习惯类的首字母大写
基本类型:object、function、array、boolean、number、string(记忆:即6个基本数据类型,用function和array替换掉null、undefined)
明确一点:ES5
1、实例(new)可以继承父类原型方法以及父类私有属性。
2、寄生继承只做继承父类原型方法,不继承父类私有属性;
3、组合继承即继承父类原型方法和继承父类私有属性。
ES5继承从两方面讲:继承父类私有属性,继承父类原型方法
最终目的:创建实例A继承Student.prototype、继承People.prototype,实例A继承学生类,学生类继承人类。即:A -> Student.prototype -> People.prototype
//父类(人类):
function People(name){ this.name = name; //构造函数,提供私有属性 }
People.prototype.SayName = function (){ console.log(this.name); }
//子类(学生类):
function Student(){ this.number = number; //构造函数,提供私有属性 }
一、目的:继承父类原型方法
错误做法:
有些人的做法是:Student.prototype = new People()
这样子做不会报错,也确实能够继承到父类的原型(方法)。但仔细一看,有他的“尴尬之处”。
不好的点有:1、我只想Student子类继承People父类的原型(方法),但这么实例的话使得Student.prototype(学生原型链)变成People父类的一个实例了(父类的原型方法以及私有属性,变成了Student.prototype的公有属性,多继承了一个东西,即父类的私有属性);
2、这样子做,使得People类“无缘无故”调用了一次(影响性能);
正确做法(寄生继承):
将Student.prototype = new People()换成以下写法
function fn(){
let fun = function(){};
fun.prototype=People.prototype; //将People.prototype赋值给fun.prototype
return new fun()
}
Student.prototype = fn();//这样子继承,fun是一个没有私有属性,只有人类的原型方法,是一个很干净的函数。即:达到了我们的目的,只继承父类的原型方法。
二、目的:继承父类私有属性
在学生类创建时进行
function Student(name,number){
People.call(this,name); //达成目的,继承父类私有属性
this.number = number;
}
最后将目的一、目的二整合就成了组合继承
//父类(人类):
function People(name){ this.name = name; }
People.prototype.sayName = function (){ console.log(this.name); }
//子类(学生类):
function Student(name,number){
People.call(this,name); //达成目的,继承父类私有属性
this.number = number;
}
function fn(){
let fun = function(){};
fun.prototype=People.prototype; //将People.prototype赋值给fun.prototype
return new fun()
}
Student.prototype = fn();
Student.prototype.sayNumber = function(){console.log(console.log(this.number))}//给Student原型添加方法,根据自己的需求决定是否添加。
// 实例化:
let A = new Student()
这样子A实例就可访问sayName和sayNumber原型方法了。达到我们的最终目的。即:A -> Student.prototype -> People.prototype
如果ES5的继承你已经能够清楚,那么ES6的继承学习起来将很轻松
ES6有类的概念,即class,不再用function创建类
// 创建父类:
class People{
constructor(name){ this.name = name; }//构造函数,提供私有属性(constructor)
sayName(){console.log(this.name)}//原型方法,不再用prototype添加
}
// ES6继承:创建子类继承子类:
class Student extends People{ //extends就相当于继承了父类的原型方法
constructor(name,number){
super(name); this.number = number;
//super继承父类私有属性,相当于ES5中People.call(this,name);
}
}
// 实例化:
let oA = new Student('天才威',24)
Tip1:可以只写extends不写constructor,相当于没有私有属性。
Tip2:写了constructor,就必须写super,且需要写在自己的私有属性之前。否则报错
篇幅过长,如有所遗漏评论区友好交流!