js----js实现继承的方式及其优缺点
js实现继承的方式
1.继承方式一 -------------- 通过改变父类的执行环境(不常用) 2.call()继承------------只能继承实例的属性和方法
3.apply() 的继承---------------只能继承实例的属性和方法
4.原型继承
5.混合继承
1.继承方式一 -- 通过改变父类的执行环境(不常用)
子类中有一个特殊属性 指向父类 , 通过子类的属性 调用父类 //子类的属性指向父类构造函数,实现继承,此时子类的parent属性中有父类的所有属性和方法 this.parent = Father; //调用调用子类的属性 this.parent();
2.call()继承------------只能继承实例的属性和方法
//改变父类Father构造函数的指向,指向子类Son,此时的this指向Son new出来的对象 //子类继承父类的属性和方法,方法会自动继承,属性要写上 Father.call(this,name,age);----------继承的属性个数不固定
3.apply() 的继承---------------只能继承实例的属性和方法
//改变父类iPhone5的this指向,指向子类iPhone6 new出的对象,实现iPhone6继承iPhone5, //参2必须为数组或者arguments,否则会报错(方法会自动继承,但是属性必须在第二个参数写上才会继承) // iPhone5.apply(this,[price,color,size,memsize]);//数组-------继承的属性不固定 // 在函数内部实现接收实参------arguments,,提高编程 效率 iPhone5.apply(this,arguments);//arguments 继承了价格,颜色两个属性 console.log(arguments);//,实参有几个,arguments就接收几个,相当于继承了几个属性,实参的个数不一定和形参个数相同
4.原型继承
子类.prototype = new 父类() 缺点 :如果父类的实例属性值 不固定,子类 继承实例属性值时,子类无法更改父类的属性值
5混合继承
通过 call或apply方式继承 实例属性
通过 原型方式继承原型方法
解释如下:
1、继承方式一 -- 通过改变父类的执行环境(不常用)
子类中有一个特殊属性 指向父类 , 通过子类的属性 调用父类 <script> function Father(){ this.money = 9999999; this.liaomei = function(){ console.log("钱") } } // console.log(Father);//函数块 function Son(){ //子类的属性指向父类,实现继承,此时子类的parent属性中有父类的所有属性和方法 this.parent = Father; //调用调用子类的属性 this.parent(); //删除子类的parent属性 delete this.parent; } var son = new Son(); console.log(son); </script>
2、继承方式二call()
call() 和 apply() 的继承 : 只能继承实例属性和实例方法 区别 : call的第二个参数的个数不固定 apply的第二个参数是一个数组 可以通过arguments代替这个数组,提高编程效率 <script> function Father(name,age){ this.name = name; this.age = age; this.dance = function(){ console.log("跳舞"); } this.sing = function(){ console.log("唱歌"); } } //score表示子类特有的属性 function Son(name,age,score){ //改变父类Father构造函数的指向,指向Son,此时的this指向Son new出来的对象 //子类继承父类的属性和方法,方法会自动继承,属性要写上 Father.call(this,name,age); //子类的属性和方法 this.score = score; this.study = function(){ console.log("study"); } } var fa = new Father(); var son = new Son("小明",22); console.log(fa); console.log(son); console.log(son.name); console.log(son.sing); </script>
3.继承方式三------apply()
function iPhone5(price,color,size,memsize){ this.price = price; this.color = color; this.size = size; this.memsize = memsize; this.sendMessage = function(){ console.log("发短信"); } } //iphone6子类,继承iPhone5 function iPhone6(price,color,size,memsize){ //改变iPhone5的this指向,指向iPhone6 new出的对象,实现iPhone6继承iPhone5, //参2必须为数组或者arguments,否则会报错(方法会自动继承,但是属性必须在第二个参数写上才会继承) // iPhone5.apply(this,[price,color,size,memsize]);//数组 // 在函数内部实现接收实参------arguments iPhone5.apply(this,arguments);//arguments 继承了价格,颜色两个属性 console.log(arguments);//,实参有几个,arguments就接收几个,相当于继承了几个属性,实参的个数不一定和形参个数相同 console.log(arguments.length);//2 //子类独有的方法 this.photo = function(){ console.log("拍照"); } } var ip6 = new iPhone6(15555,"red");//实参 ip6.sendMessage(); ip6.photo(); console.log(ip6.color); </script>
4、继承方式 四---------原型继承
原型继承 : 子类.prototype = new 父类() 缺点 :如果父类的实例属性值 不固定,原型继承 继承实例属性值时 值无法更改 function Father(age){ this.age = age; this.money = 999999; this.dance = function(){ console.log("跳舞"); } } Father.prototype.name = "父类"; Father.prototype.music = function(){ console.log("唱歌"); } function Son(){ } //原型继承 ,继承了父类的所有属性和方法 子类.prototype = new Father(); Son.prototype = new Father(38);//38实际上是父类的年龄, 但子类继承了age这个属性,同样子类的age也是38,子类无法改变age的值 var son = new Son(); console.log(son); console.log(son.age);//38 console.log(son.money); console.log(son.name); son.dance(); son.music() </script>
5 、 继承方法五----------混合继承
通过 call或apply方式继承 实例属性 通过 原型方式继承原型方法 function Human(hobody){ this.hobody = hobody; } Human.prototype.walk = function(){ console.log("行走"); } Human.prototype.eat = function(){ console.log("吃饭"); } function Student(hobody,name,age){ //继承,继承实例属性 Human.call(this,hobody); //子类独有的属性 this.name = name; this.age = age; this.study = function(){ console.log("学习"); } } //继承原型方法 Student.prototype = new Human(); var stu = new Student("学习","xiamm",18); console.log(stu);