学习中,如果发现有什么问题可以一起改正
继承的目的:减少重复的代码
关于原型继承
//创建一个公共构造函数
function fn1 (){
this.name = ‘zs’;
this.age = 15;
}
//创建新的构造函数
function fn2 (){}
//将fn2的原型修改为fn1,使fn2也有name和age属性
fn2.prototype = new fn1();
//这里fn2使用了new操作符,说明fn2也是作为构造函数使用
var fn2_1 = new fn2();
//调用name属性,fn2中没有,向上查找原型对象fn1中是否存在name属性
var name = fn2_1.name;
console.log(name);//输出 ‘zs’
//原型继承的缺点:一旦修改了公共属性,所有引用公共属性的值都会改变
var fn2_2 = new fn2();
//因为fn2_2中没有name属性,此时要修改公共属性只能在原型上进行修改
//而原型一旦修改所有引用fn1中name属性的函数都被修改这不是我们想要的结果
fn2_2.proto.name = ‘li’;
console.log(fn2_1.name);//输出 ‘li’
console.log(fn2_2.name);//输出 ‘li’
关于借用构造函数继承(call()方法)
//借用构造函数继承
function fn1 (name, age){
this.name = name;
this.age = age;
}
//带参数的构造函数
function fn2 (name, age) {
//借用fn1中的属性,并将fn1中的this替换成构造函数new出来的对象
fn1.call(this, name, age);
}
//fn2实例化
var fn2_1 = new fn2(‘张三’,’18’);
console.log(fn2_1.name);//输出 ‘张三’
console.log(fn1);//输出 function fn1(){this.name = ‘zs’;this.age = 15;}
//借用构造函数方法无法重用的问题
call()方法相当于复制了一份fn1构造函数,将里面的this指向构造函数new出来的对象,但是由于fn2和fn1不是同一个原型,这样就存在fn1原型中的方法fn2无法访问和使用,所以借用构造函数无法实现方法的重用
案例:
function fn1 (name, age){
this.name = name;
this.age = age;
}
fn1.prototype.sayHi = function (){
console.log(123);
}
function fn2 (name, age) {
fn1.call(this, name, age);
}
var fn2_1 = new fn2(‘张三’, ‘18’);
console.log(fn2_1.sayHi())//报错,因为fn2原型链上并没有sayHi()方法
组合继承
基于原型继承和借用函数继承的优缺点,出现组合继承
function fn1 (name, age){
this.name = name;
this.age = age;
}
fn1.prototype.sayHi = function () {
console.log(this.name+’你好’);
}
function fn2 (name, age) {
fn1.call(this, name, age);
}
fn2.prototype = new fn1();
var fn2_1 = new fn2(‘张三’, ‘18’);
console.log(fn2_1.sayHi());//输出 ‘张三你好’
关于原型的constructor属性指向问题