国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

JavaScript 繼承

2019-11-06 06:12:13
字體:
供稿:網(wǎng)友

1. 繼承(inherit)

js本身是沒有繼承這個(gè)特性或語(yǔ)法的,所以js的繼承比較特殊。本質(zhì):拿來主義,原本不是自己的,但是自己可以直接用,好像就是自己的一樣,這個(gè)就是繼承。因此在js中,凡是符合上述特征的都是繼承(js中繼承沒有特定的語(yǔ)法)。(1)最簡(jiǎn)單的繼承就是原型式繼承就是寫一個(gè)構(gòu)造函數(shù),在原型中添加成員,那么實(shí)例對(duì)象就含有了該成員,這就稱為實(shí)例對(duì)象繼承自原型。(2)混入式繼承(mix)在js中混入就是將一個(gè)對(duì)象的成員加到另一個(gè)對(duì)象中。典型的語(yǔ)法結(jié)構(gòu):
//將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í)際開發(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ì)象出來,保證被創(chuàng)建出來的對(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)來的數(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開始,刪掉1個(gè)元素,把后面的數(shù)據(jù)插入此位置/*查*/var i1 = myArray.indexOf('b');在較新的 ES5 的規(guī)范中已經(jīng)內(nèi)置了該算法,使用 Object.create 來實(shí)現(xiàn)該功能。所謂的簡(jiǎn)單對(duì)象,首先要保證簡(jiǎn)單,沒有多余的復(fù)雜數(shù)據(jù):
var obj = Object.create(null);console.log(obj); //空的簡(jiǎn)單對(duì)象,里面什么都沒有沒有寫構(gòu)造函數(shù),obj 就是 Object 創(chuàng)建出來的。
var obj = Object.create(base);//此時(shí)是一種特殊情況,obj 沒有構(gòu)造函數(shù),是內(nèi)部創(chuàng)建的

3. 比較高級(jí)的繼承方法

Object.create(base) => sub該方法有兩大缺點(diǎn):① 沒有構(gòu)造函數(shù),無法復(fù)用② 沒有擴(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出來應(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;):


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 小金县| 乃东县| 瑞安市| 库伦旗| 黄陵县| 额尔古纳市| 深水埗区| 龙岩市| 乐业县| 隆回县| 永仁县| 重庆市| 安福县| 凤冈县| 台北县| 教育| 黑山县| 敖汉旗| 麦盖提县| 张家口市| 拉孜县| 白山市| 宁化县| 松原市| 江孜县| 永丰县| 泰来县| 凤山市| 阿鲁科尔沁旗| 桂平市| 洛南县| 辽源市| 新安县| 布尔津县| 安丘市| 如东县| 灌云县| 乌兰察布市| 合阳县| 吕梁市| 马关县|