Js的继承方式有以下方式:// 定义一个动物类为父类function Animal (name) { // 属性 this.name = name || 'Animal'; // 实例方法 this.sleep = function(){ console.log(this.name + '正在睡觉!'); }}// 原型方法Animal.prototype.eat = function(food) { console.log(this.name + '正在吃:' + food);};1、原型链继承核心: 将父类的实例作为子类的原型function Cat(){ }Cat.prototype = new Animal();Cat.prototype.name = 'cat';// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.eat('fish'));console.log(cat.sleep());console.log(cat instanceof Animal); //true console.log(cat instanceof Cat); //true特点:1. 非常纯粹的继承关系,实例是子类的实例,也是父类的实例2. 父类新增原型方法/原型属性,子类都能访问到3. 简单,易于实现缺点:1. 在Cat构造函数中,为Cat实例增加实例属性。
如果要新增原型属性和方法,则必须放在new Animal()这样的语句之后执行。2. 无法实现多继承3. 来自原型对象的引用属性是所有实例共享的(详细请看附录代码: 示例1)4. 创建子类实例时,无法向父类构造函数传参推荐指数:★★(3、4两大致命缺陷)2、构造继承核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)function Cat(name){ Animal.call(this); this.name = name || 'Tom';}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true特点:1. 解决了1中,子类实例共享父类引用属性的问题2. 创建子类实例时,可以向父类传递参数3. 可以实现多继承(call多个父类对象)缺点:1. 实例并不是父类的实例,只是子类的实例2. 只能继承父类的实例属性和方法,不能继承原型属性/方法3. 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能推荐指数:★★(缺点3)3、实例继承核心:为父类实例添加新特性,作为子类实例返回function Cat(name){ var instance = new Animal(); instance.name = name || 'Tom'; return instance;}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // false特点:1. 不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果缺点:1. 实例是父类的实例,不是子类的实例2. 不支持多继承推荐指数:★★4、拷贝继承function Cat(name){ var animal = new Animal(); for(var p in animal){ Cat.prototype[p] = animal[p]; } Cat.prototype.name = name || 'Tom';}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true特点:1. 支持多继承缺点:1. 效率较低,内存占用高(因为要拷贝父类的属性)2. 无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)推荐指数:★(缺点1)5、组合继承核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用function Cat(name){ Animal.call(this); this.name = name || 'Tom';}Cat.prototype = new Animal();// 组合继承也是需要修复构造函数指向的。
Cat.prototype.constructor = Cat;// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // true特点:1. 弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法2. 既是子类的实例,也是父类的实例3. 不存在引用属性共享问题4. 可传参5. 函数可复用缺点:1. 调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)推荐指数:★★★★(仅仅多消耗了一点内存)6、寄生组合继承核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点function Cat(name){ Animal.call(this); this.name = name || 'Tom';}(function(){ // 创建一个没有实例方法的类 var Super = function(){}; Super.prototype = Animal.prototype; //将实例作为子类的原型 Cat.prototype = new Super();})();// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); //true//该实现没有修复constructor。Cat.prototype.constructor = Cat; // 需要修复下构造函数特点:1. 堪称完美缺点:1. 实现较为复杂推荐指数:★★★★(实现复杂,扣掉一颗星)示例代码:function Animal (name) { // 属性 this.name = name || 'Animal'; // 实例方法 this.sleep = function(){ console.log(this.name + '正在睡觉!'); } //实例引用属性 this.features = [];}function Cat(name){}Cat.prototype = new Animal();var tom = new Cat('Tom');var kissy = new Cat('Kissy');console.log(tom.name); // "Animal"console.log(kissy.name); // "Animal"console.log(tom.features); // []console.log(kissy.features); 。
JavaScript中要实现继承,其实就是实现三层含义:1、子类的实例可以共享父类的方法;2、子类可以覆盖父类的方法或者扩展新的方法;3、子类和父类都是子类实例的“类型”。
JavaScript中,并不直接从语法上支持继承,但是可以通过模拟的方法来实现继承,以下是关于实现继承的几种方法的总结:1、构造继承法2、原型继承法3、实例继承法4、拷贝继承法1、构造继承法:在子类中执行父类的构造函数。 12、原型继承法:JavaScript是一种基于原型的语言。
要了解什么是“原型继承法”,先了解一下prototype的特性:prototype的最大特性是能够让对象实例共享原型对象的属性,因此如果把某个对象作为一个类型的原型,那么我们说这个类型的所有实例都一这个对象为原型。这个时候,实际上这个对象的类型也可以作为那些以这个对象为原型的实例的类型。
假如:Point类的对象作为Point2D类型的原型(Point2D.prototype = new Point(2)),那么说Point2D的所有实例都是以Point类的对象为原型。此时,实际上Point类就可以作为Point2D类型的对象的类型(相当于Point2D类型“继承”了Point类型)。
见例:1 <script LANGUAGE="JavaScript"> 2 <!---ecms 3 function dwn(s) 4 { 5 document.write(s+""); 6 } 7 8 function Point(dimension) //定义一个Point类 9 {10 this.dimension = dimension;11 }1213 Point.prototype.distance = function() //静态方法,可以被继承14 {15 return this.dimension*2;16 }1718 function Point2D(x,y) //定义一个Point2D类19 {20 this.x = x;21 this.y = y;22 }2324 Point2D.prototype = new Point(2); //运行“原型继承法”使Point2D继承Point2526 function Point3D(x,y,z) //定义Point3D类27 {28 this.x = x;29 this.y = y;30 this.z = z;31 }3233 Point3D.prototype = new Point(3); //Point3D继承Point类3435 var p2 = new Point2D(1,2); //构造一个Point2D对象3637 var p3 = new Point3D(1,2,3); //构造一个Point3D对象3839 dwn(p2.dimension); //240 dwn(p3.dimension); //341 dwn(p2.distance()); //4 可以继承静态方法42 dwn(p3.distance()); //6 可以继承静态方法<。
js继承用的还是比较少的,一般通过原型链继承或混合继承目的就是降低创建对象的开销!各种继承示例如下:构造函数继承:原型链继承:混合继承:ES6 extends继承:。
定义一个父类:// 定义一个动物类function Animal (name) {// 属性this.name = name || 'Animal';// 实例方法this.sleep = function(){console.log(this.name + '正在睡觉!');}}// 原型方法Animal.prototype.eat = function(food) {console.log(this.name + '正在吃:' + food);1.原型链继承核心:将父类的实例作为子类的原型function Cat(){}Cat.prototype = new Animal();Cat.prototype.name = 'cat';// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.eat('fish'));console.log(cat.sleep());console.log(cat instanceof Animal); //trueconsole.log(cat instanceof Cat); //true特点:1.非常纯粹的继承关系,实例是子类的实例,也是父类的实例 2.父类新增的原型方法、属性,子类都能访问到 3.简单,易于实现缺点:1.要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行(可以在cat构造函数中,为Cat实例增加实例属性)2.无法实现多继承3.来自原型对象的引用属性被所有实例共享 4.创建子类实例时,无法向父类构造函数传参下面代码解释缺点3(注意是引用属性):function Super(){ this.val = 1; this.arr = [1];}function Sub(){ // 。
}Sub.prototype = new Super(); // 核心var sub1 = new Sub();var sub2 = new Sub();sub1.val = 2;sub1.arr.push(2);alert(sub1.val); // 2alert(sub2.val); // 1alert(sub1.arr); // 1, 2alert(sub2.arr); // 1, 22.构造继承核心:使用父类的构建函数来增强子类实例,等于复制父类的实例属性给子类(没用到原型),除了call方法,也可以用apply()function Cat(name){Animal.call(this);this.name = name || 'Tom';}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true特点:1.解决了1中,子类实例共享父类引用属性的问题 2.创建子类实例时,可以向父类传递参数 3.可以实现多继承(call多个父类对象)缺点:1.实例并不是父类的实例,只是子类的实例 2.只能继承父类的实例属性和方法,不能继承原型属性和方法 3.无法实现函数复用,每个子类都有父类的实例函数的副本,影响性能3.实例继承核心:为父类实例添加新特性,作为子类实例返回function Cat(name){var instance = new Animal();instance.name = name || 'Tom';return instance;}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // false特点:1.不限制调用方式,不管是new 子类()还是子类(),返回的对象都具有相同的效果缺点:1.实例是父类的实例,不是子类的实例2.不支持多继承4. 拷贝继承核心:使用for…in将父类实例中的方法赋给子类实例unction Cat(name){var animal = new Animal();for(var p in animal){Cat.prototype[p] = animal[p];}Cat.prototype.name = name || 'Tom';}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true特点:1.支持多继承缺点:1.效率较低,内存占用高(因为要拷贝父类的属性)2.无法获取父类不可枚举的方法(for in无法访问不可枚举的方法)5.组合继承核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用function Cat(name){Animal.call(this);this.name = name || 'Tom';}Cat.prototype = new Animal();//组合继承需要修复构造函数的指向Cat.prototype.constructor=Cat;// Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // true特点:1.弥补了方式2的缺陷,可以继承实例属性、方法,也可以继承原型属性、方法2.既是子类的实例,也是父类的实例3.不存在引用属性的共享问题4.可传参5.函数可复用缺点:1.调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)6.寄生组合继承核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点function Cat(name){Animal.call(this);this.name = name || 'Tom';}(function(){// 创建一个没有实例方法的类var Super = function(){};Super.prototype = Animal.prototype;//将实例作为子类的原型Cat.prototype = new Super();//寄生组合继承需要修复构造函数的指向Cat.prototype.constructor=Cat;})(); // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); //true特点:1.堪称完美缺点:1.实现较为复杂 (BY三人行慕课)。
JavaScript中要实现继承,其实就是实现三层含义:1、子类的实例可以共享父类的方法;2、子类可以覆盖父类的方法或者扩展新的方法;3、子类和父类都是子类实例的“类型”。
JavaScript中,并不直接从语法上支持继承,但是可以通过模拟的方法来实现继承,以下是关于实现继承的几种方法的总结:1、构造继承法2、原型继承法3、实例继承法4、拷贝继承法1、构造继承法:在子类中执行父类的构造函数。 12、原型继承法:JavaScript是一种基于原型的语言。
要了解什么是“原型继承法”,先了解一下prototype的特性:prototype的最大特性是能够让对象实例共享原型对象的属性,因此如果把某个对象作为一个类型的原型,那么我们说这个类型的所有实例都一这个对象为原型。这个时候,实际上这个对象的类型也可以作为那些以这个对象为原型的实例的类型。
假如:Point类的对象作为Point2D类型的原型(Point2D.prototype = new Point(2)),那么说Point2D的所有实例都是以Point类的对象为原型。此时,实际上Point类就可以作为Point2D类型的对象的类型(相当于Point2D类型“继承”了Point类型)。
见例:1 3、实例继承法 构造继承法和原型继承法各有各的缺点,如: 构造继承法没有办法继承类型的静态方法,因此它无法很好的继承JavaScript的核心对象。 原型继承法虽然可以继承静态方法,但是依然无法很好地继承核心对象中的不可枚举方法。
其中,javascript核心对象包括: Array 表述数组。 Boolean 表述布尔值。
Date 表述日期。 Function 指定了一个可编译为函数的字符串 JavaScript 代码。
Math 提供了基本的数学常量和函数;如其 PI 属性包含了π的值。
继承的方式一共有三种:一、原型继承通过prototype 来实现继承。
function Person(name,age) { this.name=name; this.age=age;}Person.prototype.sayHello=function(){alert (''使用原型得到Name:'' + this.name);} var per = new Person(";马小倩",21);per.sayHello();//输出:使用原型得到Name:马小倩 function Student(){}Student.prototype=new Person(";洪如彤",21); //实现原型继承var stu = new Student();Student.prototype.grade=5; Student.prototype.intr=function(){alert(this.grade);} stu.sayHello();//输出:使用原型得到Name:洪如彤stu.intr();//输出:5 二、构造函数实现继承function Person(name,age) { this.name=name; this.age=age;}Person.prototype.sayHello=function(){alert (''使用原型得到Name:'' + this.name);} var per = new Person(";马小倩",21);per.sayHello();//输出:使用原型得到Name:马小倩三、通过call、apply 实现继承。
1、原型链继承核心: 将父类的实例作为子类的原型缺点: 父类新增原型方法/原型属性,子类都能访问到,父类一变其它的都变了2、构造继承核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)缺点: 方法都在构造函数中定义, 只能继承父类的实例属性和方法,不能继承原型属性/方法,无法实现函数复用,每个子类都有父类实例函数的副本,影响性能3、组合继承组合继承(所有的实例都能拥有自己的属性,并且可以使用相同的方法,组合继承避免了原型链和借用构造函数的缺陷,结合了两个的优点,是最常用的继承方式)核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后再通过将父类实例作为子类原型,实现函数复用缺点:调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)4、寄生组合继承核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点缺点:堪称完美,但实现较为复杂。
声明:本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
蜀ICP备2020033479号-4 Copyright © 2016 学习鸟. 页面生成时间:3.388秒