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. 簡單,易于實現(xiàn)缺點:1. 在Cat構造函數(shù)中,為Cat實例增加實例屬性。
如果要新增原型屬性和方法,則必須放在new Animal()這樣的語句之后執(zhí)行。2. 無法實現(xiàn)多繼承3. 來自原型對象的引用屬性是所有實例共享的(詳細請看附錄代碼: 示例1)4. 創(chuàng)建子類實例時,無法向父類構造函數(shù)傳參推薦指數(shù):★★(3、4兩大致命缺陷)2、構造繼承核心:使用父類的構造函數(shù)來增強子類實例,等于是復制父類的實例屬性給子類(沒用到原型)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. 創(chuàng)建子類實例時,可以向父類傳遞參數(shù)3. 可以實現(xiàn)多繼承(call多個父類對象)缺點:1. 實例并不是父類的實例,只是子類的實例2. 只能繼承父類的實例屬性和方法,不能繼承原型屬性/方法3. 無法實現(xiàn)函數(shù)復用,每個子類都有父類實例函數(shù)的副本,影響性能推薦指數(shù):★★(缺點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. 不支持多繼承推薦指數(shù):★★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 訪問到)推薦指數(shù):★(缺點1)5、組合繼承核心:通過調用父類構造,繼承父類的屬性并保留傳參的優(yōu)點,然后通過將父類實例作為子類原型,實現(xiàn)函數(shù)復用function Cat(name){ Animal.call(this); this.name = name || 'Tom';}Cat.prototype = new Animal();// 組合繼承也是需要修復構造函數(shù)指向的。
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. 函數(shù)可復用缺點:1. 調用了兩次父類構造函數(shù),生成了兩份實例(子類實例將子類原型上的那份屏蔽了)推薦指數(shù):★★★★(僅僅多消耗了一點內存)6、寄生組合繼承核心:通過寄生方式,砍掉父類的實例屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次實例方法/屬性,避免的組合繼承的缺點function Cat(name){ Animal.call(this); this.name = name || 'Tom';}(function(){ // 創(chuàng)建一個沒有實例方法的類 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//該實現(xiàn)沒有修復constructor。Cat.prototype.constructor = Cat; // 需要修復下構造函數(shù)特點:1. 堪稱完美缺點:1. 實現(xiàn)較為復雜推薦指數(shù):★★★★(實現(xiàn)復雜,扣掉一顆星)示例代碼: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中要實現(xiàn)繼承,其實就是實現(xiàn)三層含義:1、子類的實例可以共享父類的方法;2、子類可以覆蓋父類的方法或者擴展新的方法;3、子類和父類都是子類實例的“類型”。
JavaScript中,并不直接從語法上支持繼承,但是可以通過模擬的方法來實現(xiàn)繼承,以下是關于實現(xiàn)繼承的幾種方法的總結:1、構造繼承法2、原型繼承法3、實例繼承法4、拷貝繼承法1、構造繼承法:在子類中執(zhí)行父類的構造函數(shù)。 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() //靜態(tài)方法,可以被繼承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 可以繼承靜態(tài)方法42 dwn(p3.distance()); //6 可以繼承靜態(tài)方法<。
js繼承用的還是比較少的,一般通過原型鏈繼承或混合繼承目的就是降低創(chuàng)建對象的開銷!各種繼承示例如下:構造函數(shù)繼承:原型鏈繼承:混合繼承: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.簡單,易于實現(xiàn)缺點:1.要想為子類新增屬性和方法,必須要在new Animal()這樣的語句之后執(zhí)行(可以在cat構造函數(shù)中,為Cat實例增加實例屬性)2.無法實現(xiàn)多繼承3.來自原型對象的引用屬性被所有實例共享 4.創(chuàng)建子類實例時,無法向父類構造函數(shù)傳參下面代碼解釋缺點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.構造繼承核心:使用父類的構建函數(shù)來增強子類實例,等于復制父類的實例屬性給子類(沒用到原型),除了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.創(chuàng)建子類實例時,可以向父類傳遞參數(shù) 3.可以實現(xiàn)多繼承(call多個父類對象)缺點:1.實例并不是父類的實例,只是子類的實例 2.只能繼承父類的實例屬性和方法,不能繼承原型屬性和方法 3.無法實現(xiàn)函數(shù)復用,每個子類都有父類的實例函數(shù)的副本,影響性能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.組合繼承核心:通過調用父類構造,繼承父類的屬性并保留傳參的優(yōu)點,然后通過將父類實例作為子類原型,實現(xiàn)函數(shù)復用function Cat(name){Animal.call(this);this.name = name || 'Tom';}Cat.prototype = new Animal();//組合繼承需要修復構造函數(shù)的指向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.函數(shù)可復用缺點:1.調用了兩次父類構造函數(shù),生成了兩份實例(子類實例將子類原型上的那份屏蔽了)6.寄生組合繼承核心:通過寄生方式,砍掉父類的實例屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次實例方法/屬性,避免的組合繼承的缺點function Cat(name){Animal.call(this);this.name = name || 'Tom';}(function(){// 創(chuàng)建一個沒有實例方法的類var Super = function(){};Super.prototype = Animal.prototype;//將實例作為子類的原型Cat.prototype = new Super();//寄生組合繼承需要修復構造函數(shù)的指向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.實現(xiàn)較為復雜 (BY三人行慕課)。
JavaScript中要實現(xiàn)繼承,其實就是實現(xiàn)三層含義:1、子類的實例可以共享父類的方法;2、子類可以覆蓋父類的方法或者擴展新的方法;3、子類和父類都是子類實例的“類型”。
JavaScript中,并不直接從語法上支持繼承,但是可以通過模擬的方法來實現(xiàn)繼承,以下是關于實現(xiàn)繼承的幾種方法的總結:1、構造繼承法2、原型繼承法3、實例繼承法4、拷貝繼承法1、構造繼承法:在子類中執(zhí)行父類的構造函數(shù)。 12、原型繼承法:JavaScript是一種基于原型的語言。
要了解什么是“原型繼承法”,先了解一下prototype的特性:prototype的最大特性是能夠讓對象實例共享原型對象的屬性,因此如果把某個對象作為一個類型的原型,那么我們說這個類型的所有實例都一這個對象為原型。這個時候,實際上這個對象的類型也可以作為那些以這個對象為原型的實例的類型。
假如:Point類的對象作為Point2D類型的原型(Point2D.prototype = new Point(2)),那么說Point2D的所有實例都是以Point類的對象為原型。此時,實際上Point類就可以作為Point2D類型的對象的類型(相當于Point2D類型“繼承”了Point類型)。
見例:1 3、實例繼承法 構造繼承法和原型繼承法各有各的缺點,如: 構造繼承法沒有辦法繼承類型的靜態(tài)方法,因此它無法很好的繼承JavaScript的核心對象。 原型繼承法雖然可以繼承靜態(tài)方法,但是依然無法很好地繼承核心對象中的不可枚舉方法。
其中,javascript核心對象包括: Array 表述數(shù)組。 Boolean 表述布爾值。
Date 表述日期。 Function 指定了一個可編譯為函數(shù)的字符串 JavaScript 代碼。
Math 提供了基本的數(shù)學常量和函數(shù);如其 PI 屬性包含了π的值。
繼承的方式一共有三種:一、原型繼承通過prototype 來實現(xiàn)繼承。
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); //實現(xiàn)原型繼承var stu = new Student();Student.prototype.grade=5; Student.prototype.intr=function(){alert(this.grade);} stu.sayHello();//輸出:使用原型得到Name:洪如彤stu.intr();//輸出:5 二、構造函數(shù)實現(xiàn)繼承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 實現(xiàn)繼承。
1、原型鏈繼承核心: 將父類的實例作為子類的原型缺點: 父類新增原型方法/原型屬性,子類都能訪問到,父類一變其它的都變了2、構造繼承核心:使用父類的構造函數(shù)來增強子類實例,等于是復制父類的實例屬性給子類(沒用到原型)缺點: 方法都在構造函數(shù)中定義, 只能繼承父類的實例屬性和方法,不能繼承原型屬性/方法,無法實現(xiàn)函數(shù)復用,每個子類都有父類實例函數(shù)的副本,影響性能3、組合繼承組合繼承(所有的實例都能擁有自己的屬性,并且可以使用相同的方法,組合繼承避免了原型鏈和借用構造函數(shù)的缺陷,結合了兩個的優(yōu)點,是最常用的繼承方式)核心:通過調用父類構造,繼承父類的屬性并保留傳參的優(yōu)點,然后再通過將父類實例作為子類原型,實現(xiàn)函數(shù)復用缺點:調用了兩次父類構造函數(shù),生成了兩份實例(子類實例將子類原型上的那份屏蔽了)4、寄生組合繼承核心:通過寄生方式,砍掉父類的實例屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次實例方法/屬性,避免的組合繼承的缺點缺點:堪稱完美,但實現(xiàn)較為復雜。
聲明:本網(wǎng)站尊重并保護知識產權,根據(jù)《信息網(wǎng)絡傳播權保護條例》,如果我們轉載的作品侵犯了您的權利,請在一個月內通知我們,我們會及時刪除。
蜀ICP備2020033479號-4 Copyright ? 2016 學習鳥. 頁面生成時間:3.388秒