1.原型链继承
Person.prototype.age = 18;
function Person(){
}
function Student(){
}
var p = new Person();
Student.prototype = p;
var s = new Student();
console.log(s.age);//18
2.call apply继承
function Person(name,age){
this.name = name;
this.age = age
}
function Student(grade,name,age){
Person.call(this,name,age)
//Person.apply(this,[name,age])
this.grade = grade
}
var s = new Student(100,"xy",18)
console.log(s);//{name: "xy", age: 18, grade: 100}
call apply 的区别
共同:
1.都是要改变this指向
2.第一个参数是this要指向的对象
3.都可以利用后续的参数
不同 :
1.call方法参数将依次传递给借用的方法做参数 可以有n个
2.apply方法第一个参数是一个对象 第二个参数是一个伪数组argnments
3.共享原型继承
Person.prototype.age = 18;
function Person(){
}
function Student(){
}
function extend(Target,Origin){
Target.prototype = Origin.prototype
}
extend(Student,Person);
var s = new Student();
console.log(s.age)//18
缺点:如果Student想在自己的原型上增加新的属性,Person也会被影响。看例子:
Person.prototype.age = 18;
function Person(){}
function Student(){}
function extend(Target,Origin){
Target.prototype = Origin.prototype
}
extend(Student,Person);
Student.prototype.sex = "male"
var s = new Student();
console.log(s.sex)//male
var p = new Person();
console.log(p.sex)//male 被影响了
4.圣杯模式
这种圣杯模式的本质在于,中间生成了一个对象,起到了隔离的作用,今后为Son.prototype添加属性时,全部都会加在这个对象里面,所以不会对父级产生影响。而向上查找是沿着__proto__查找,可以顺利查找到父级的属性,实现继承。
function Father(){}
function Son(){}
Father.prototype.lastName='Jack';
function inherit(Target,Origin){
function F(){};
F.prototype=Origin.prototype;
Target.prototype=new F();
Target.prototype.constructor=Target;
Target.prototype.uber=Origin.prototype;
}
inherit(Son,Father);
var son=new Son();
var father=new Father();
Son.prototype.sex="male";
console.log(son.lastName);//Jack
console.log(son.sex);//male
console.log(father.sex);//undefined
Target.prototype.constructor=Target;
由于Target.prototype指向的是objF,因此并没有constructor这一属性,沿着__proto__向上查找,发现constructor指向的是Father,因此这里可以进行归位,让它的constructor重新指向它自己
Target.prototype.uber=Origin.prototype;
//uber是超类的意思,这里主要用来储存这个目标到底继承自谁,可写可不写
5.ES6–Class继承
class Person{
constructor(name, age) {
this.name = name;
this.age = age;
}
sayName(){
console.log("the name is:"+this.name);
}
}
class Worker extends Person{
constructor(name, age,job) {
super(name, age);
this.job = job;
}
sayJob(){
console.log("the job is:"+this.job)
}
}
var worker = new Worker('tcy',20,'teacher');
worker.sayJob();//the job is:teacher
worker.sayName();//the name is:tcy