//將obj2混入到obj1中,也稱obj1繼承自obj2function mix(obj1,obj2){ for(var k in obj2){ obj1[k] = obj2[k]; }}一般在混入的時(shí)候,都是混入的函數(shù),所以考慮深拷貝的機(jī)會(huì)較少,在jq框架中,有一個(gè)方法叫 extend ,該方法實(shí)現(xiàn) jq 中的混入。該方法具有的特征是:① 將多個(gè)對(duì)象混入到一個(gè)對(duì)象中mix ( dest, obj1, obj2, obj3, ... )② 實(shí)現(xiàn)深拷貝③ 實(shí)現(xiàn)原型式繼承④ 實(shí)現(xiàn)對(duì)象的構(gòu)造(不使用構(gòu)造函數(shù)創(chuàng)建對(duì)象)(3)在實(shí)際開(kāi)發(fā)的時(shí)候,常常是這兩種方法混合使用(混合式繼承)在構(gòu)造函數(shù)的原型上使用混入,那么原型對(duì)象就具有了很多方法屬性等成員,那么構(gòu)造函數(shù)的實(shí)例對(duì)象就自動(dòng)的繼承了這些成員,而且還有共享。// 1.準(zhǔn)備一個(gè)構(gòu)造函數(shù)function Role( name ) { this.name = name;}// 2.在原型中準(zhǔn)備一個(gè) extend 方法Role.PRototype.extend = function ( obj ) { // 將 obj 的成員混入到 原型對(duì)象中 for ( var k in obj ) { this[ k ] = obj[ k ]; }};// 3.盡情的擴(kuò)展( 繼承 )// 為了簡(jiǎn)單這么處理Role.skill = Role.prototype;// 法術(shù)攻擊Role.skill.extend({ fireBall: function () { console.log( '火球之術(shù)' ); }, bigFireBall: fucntion () ...});// 雷電 thunderRole.skill.extend({ qidoli: fucntion() { .... } ... });// 增加技能Role.skill.extend({ iceSkill: fucntion() { .... } ... });// 4.創(chuàng)建角色var sasigi = new Role( 'f' );2. 經(jīng)典繼承語(yǔ)法
在ES5出現(xiàn)以前,就有人模擬了繼承的方式,就是使用一個(gè)對(duì)象,創(chuàng)建出另一個(gè)對(duì)象出來(lái),保證被創(chuàng)建出來(lái)的對(duì)象的原型就是這個(gè)指定的對(duì)象。//調(diào)用該函數(shù),可以創(chuàng)建一個(gè)繼承自參數(shù)給定的對(duì)象的對(duì)象function create(baSEObj){ function F(){} F.prototype = baseObj; return new F();}//可以創(chuàng)建一個(gè)對(duì)象,該對(duì)象繼承自一個(gè)數(shù)組var myArray = create( [] );//可以將myArray作為數(shù)組使用,是真數(shù)組/*增*/myArray.push('第一個(gè)被push進(jìn)來(lái)的數(shù)據(jù)');myArray.unshift('第二個(gè)被unshift加入的數(shù)據(jù)');myArray[myArray.length++]='利用數(shù)組索引加入的數(shù)據(jù)';/*刪*/myArray.pop();//刪并返回最后一個(gè)myArray.shift();//刪并返回第一個(gè)myArray.splice(1,1);/*改*/myArray[1] = '哈哈哈';myArray.splice(1,1,'a','b','c');//從下標(biāo)為1開(kāi)始,刪掉1個(gè)元素,把后面的數(shù)據(jù)插入此位置/*查*/var i1 = myArray.indexOf('b');在較新的 ES5 的規(guī)范中已經(jīng)內(nèi)置了該算法,使用 Object.create 來(lái)實(shí)現(xiàn)該功能。所謂的簡(jiǎn)單對(duì)象,首先要保證簡(jiǎn)單,沒(méi)有多余的復(fù)雜數(shù)據(jù):var obj = Object.create(null);console.log(obj); //空的簡(jiǎn)單對(duì)象,里面什么都沒(méi)有沒(méi)有寫構(gòu)造函數(shù),obj 就是 Object 創(chuàng)建出來(lái)的。var obj = Object.create(base);//此時(shí)是一種特殊情況,obj 沒(méi)有構(gòu)造函數(shù),是內(nèi)部創(chuàng)建的3. 比較高級(jí)的繼承方法
Object.create(base) => sub該方法有兩大缺點(diǎn):① 沒(méi)有構(gòu)造函數(shù),無(wú)法復(fù)用② 沒(méi)有擴(kuò)展,創(chuàng)建的子對(duì)象與父對(duì)象其實(shí)一模一樣,只是層級(jí)結(jié)構(gòu)不同我們需要提供一個(gè)函數(shù),滿足以下功能:① 可配置構(gòu)造函數(shù),由用戶決定構(gòu)造函數(shù)應(yīng)該如何定義② 可返回構(gòu)造函數(shù)③ 應(yīng)該有繼承要求可以配置,其實(shí)就是可以自己定義屬性和方法function createClass( options ){ return function(){ //這個(gè)函數(shù)就應(yīng)該是最終的構(gòu)造函數(shù) }}由于需要重新配置構(gòu)造函數(shù)的內(nèi)容與原型,也要配置方法,可以讓 options 中必須帶有方法數(shù)據(jù),因此代碼可以修改為另一種形式:function createClass( options ){ //要求 options中必須包含 constructor 和 methods //constructor是構(gòu)造函數(shù),它需要被返回 //methods是該對(duì)象應(yīng)該具有的方法,應(yīng)該將方法加到原型中 options.constructor.prototype = options.methods; return options.constructor;}簡(jiǎn)單優(yōu)化后:function createClass( options ){ var ctr = options.constructor; ctr.prototype = options.methods;//用替換原型的辦法 return ctr;}使用:屬性應(yīng)該放在實(shí)例對(duì)象中,方法應(yīng)該放在原型中。因此,兩個(gè)參數(shù),第一個(gè)參數(shù)用于配置實(shí)例對(duì)象的成員,第二個(gè)參數(shù)用于描述原型。var Person = createClass({ constructor: function(name,age,gender){ this.name = name; this.age = age; this.gender = gender; }, methods: { sayHello: function(){ console.log( '你好,我是'+ this.name ); }, run: function(){ console.log( '你好,'+ this.name + '在跑' ); } }});var p = new Person('jim', 19, '男');p.sayHello();p.run();此時(shí)已經(jīng)有Person了,希望再派生一個(gè)Student出來(lái)應(yīng)該提供需要繼承的目標(biāo)(對(duì)象?函數(shù)?)實(shí)現(xiàn)如下形式:那么將需要繼承的對(duì)象傳入要求options提供同一個(gè)base屬性,表明需要繼承誰(shuí)代碼中的ctr的原型應(yīng)該由base提供
function createClass( options ){ var ctr = options.constructor, base = options.base || Object.prototype; ctr.prototype = Object.create(base);//如果直接把base賦給原型,會(huì)出bug,派生對(duì)象中增加的東西在原型對(duì)象中也會(huì)增加 //方法的加入 for(var k in options.methods){ ctr.prototype[k] = options.methods[k]; } return ctr;}正確的(ctr.prototype = Object.create(base);):錯(cuò)誤的(ctr.prototype = base;):
|
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注