【JavaScript】实现继承的方式
2018-03-27 11:45
453 查看
引言:面向对象的编程语言都具继承这一机制,而 JavaScript 是基于原型(Prototype)面向对象程序设计,所以它的实现方式也是基于原型(Prototype)实现的。
实现继承有多种方式,下面我们还是以Person和Student来分析
JavaScript 继承:
类式继承
构造函数继承
组合继承
类式继承
通过 子类原型 继承 父类的实例 实现继承.
子类实例的原型都是父类实例,它的属性共用(值类型私用,引用类型共用或私用)。
类式继承 继承的是父类原型上的方法和属性(方法和属性都在proto原型链上,所以共用,导致一改全改) 。
构造函数
通过
apply() 接受的是一个包含多个参数的数组(或类数组对象)
call() 接受的是一个参数列表。
由于这种类型的继承没有涉及原型prototype,所以父类的原型方法自然不会被子类继承,而如果想被子类继承就必须要放在构造函数中,这样创建出来的每个实例都会单独拥有一份而不能共用,这就违背了代码复用的原则
构造函数 继承的是父类的共有属性,通过 call 将属性绑定到子类上。
组合继承
通过
优点是:它既可以保证属性的私用又能继承父类的方法
缺点是:它的类式继承和构造函数继承使其两次创建属性,不符合继承的特有的优点.
实现继承有多种方式,下面我们还是以Person和Student来分析
function Person() { } function Student() { } Student.prototype = Person.prototype; // 我们可不可用这种方式呢?这种方法是错误的:因为子类Student有自己的一些方法 //,如果通过这样赋值,改变Student的同时也改变了Person。 Student.prototype = new Person(); //这种方式是可以实现的,但是调用构造函数有时候也是有问题的,比如要传进Person一个name和age //,这里的Student是个类,还没实例化,这时候有些奇怪了,传什么都不是。 Student.prototype = Object.create(Person.prototype); //相对来说这中方式是比较理想的,这里我们创建了一个空的对象 //,并且对象的原型指向Person.prototype,这样我们既保证了继承了Person.prototype上的方法,并且Student.prototype又有自己空的对象。 //但是Object.create是ES5以后才有的
JavaScript 继承:
类式继承
构造函数继承
组合继承
|| 类式继承
//声明父类 function SuperClass(){ //值类型 this.superValue = true; //引用类型 this.book = ['c','java','htnl'] } //为父类添加方法 SuperClass.prototype.getSuperValue =function(){ return this.superValue; } //声明子类 function SubClass(){ this.subValue = false; } //继承父类 SubClass.prototype = new SuperClass(); //为子类添加方法 SubClass.prototype.getSubValue = function(){ return this.subValue; } //测试 var a = new SubClass(); var b = new SubClass(); console.log(a.getSubValue()); //false console.log(a.getSuperValue()); //true console.log(a.book);//["c", "java", "htnl"] console.log(b.book);//["c", "java", "htnl"] a.book.push('css'); console.log(a.book);//["c", "java", "htnl", "css"] console.log(b.book);//["c", "java", "htnl", "css"] console.log(a.getSuperValue())//true console.log(b.getSuperValue())//true a.superValue = 'a'; console.log(a.getSuperValue())//a console.log(b.getSuperValue())//true console.log(a.getSubValue())//false console.log(b.getSubValue())//false a.subValue = 'sub'; console.log(a.getSubValue())//sub console.log(b.getSubValue())//false a.book = ['1','2','3']; console.log(a.book);//['1','2','3'] console.log(b.book);//["c", "java", "htnl", "css"]
类式继承
通过 子类原型 继承 父类的实例 实现继承.
子类实例的原型都是父类实例,它的属性共用(值类型私用,引用类型共用或私用)。
类式继承 继承的是父类原型上的方法和属性(方法和属性都在proto原型链上,所以共用,导致一改全改) 。
|| 构造函数继承
function SuperClass(name){ this.name =name; this.book = ['c','java','htnl'] this.getBook =function(){ return this.book; } } //为父类添加方法 SuperClass.prototype.getName =function(){ return this.name; } //声明子类 function SubClass(name){ SuperClass.call(this,name) //子类通过 SuperClass.call(this,name) 将子类中的变量在父类中执行了一遍,由于父类中是给 this 绑定属性的,因此子类自然也就继承了父类的共有属性. } var a = new SubClass('demongao'); var b = new SubClass('gsc'); a.book.push("cccc"); console.log(a.book,a.name); //["c", "java", "htnl", "cccc"] "demongao" console.log(b.book,b.name); //["c", "java", "htnl"] "gsc" console.log(a.getBook()); //["c", "java", "htnl", "cccc"] console.log(a.getName()) //TypeError
构造函数
通过
call()或
apply()的使用,改变函数的作用环境。
call()和
apply()作用是一样的,唯一的区别在于:
apply() 接受的是一个包含多个参数的数组(或类数组对象)
call() 接受的是一个参数列表。
由于这种类型的继承没有涉及原型prototype,所以父类的原型方法自然不会被子类继承,而如果想被子类继承就必须要放在构造函数中,这样创建出来的每个实例都会单独拥有一份而不能共用,这就违背了代码复用的原则
构造函数 继承的是父类的共有属性,通过 call 将属性绑定到子类上。
|| 组合继承
//声明父类 function SuperClass(name){ //值类型共有属性 this.name = name; //引用类型共有属性 this.books = ["html","css","JavaScript"]; } //父类原型共有方法 SuperClass.prototype.getName = function () { console.log(this.name); } //声明子类 function SubClass(name,time){ SuperClass.call(this,name); this.time =time; } //类式继承 子类原型继承父类 SubClass.prototype = new SuperClass(); SubClass.prototype.getTime = function(){ console.log(this.time);
组合继承
通过
构造函数继承
子类, 通过
call方式获取
父类的属性,又通过
类式继承方式获取
父类的方法。
优点是:它既可以保证属性的私用又能继承父类的方法
缺点是:它的类式继承和构造函数继承使其两次创建属性,不符合继承的特有的优点.
相关文章推荐
- JavaScript是如何实现继承的(六种方式)
- javascript实现继承的方式
- JavaScript中实现继承的几种方式的使用和分析
- 讲述Javascript 实现继承的方式(基础知识)
- JavaScript面向对象(三)——继承与闭包、JS实现继承的三种方式
- javascript 5种方式实现继承
- Javascript继承实现方式
- 学习javascript面向对象 javascript实现继承的方式
- 学习javascript面向对象 javascript实现继承的方式
- JavaScript继承实现方式一览 - winter-cn - 博客园
- js(javascript) 继承的5种实现方式
- JavaScript使用伪造方式实现继承
- javascript【继承实现方式 】
- JavaScript中实现继承的几种方式
- javascript实现继承主要方式
- javascript 模拟java 实现继承的5种方式
- javascript 原型链---继承方式怎么实现继承
- JavaScript实现继承方式
- JavaScript实现继承的5种方式
- 从继承方式的实现看javascript语言的设计初衷