亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript原型繼承和原型鏈原理詳解

 更新時(shí)間:2020年02月04日 09:58:01   作者:SIMPLE98  
這篇文章主要介紹了JavaScript原型繼承和原型鏈原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

這篇文章主要介紹了JavaScript原型繼承和原型鏈原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

在討論原型繼承之前,先回顧一下關(guān)于創(chuàng)建自定義類型的方式,這里推薦將構(gòu)造函數(shù)和原型模式組合使用,通過(guò)構(gòu)造函數(shù)來(lái)定義實(shí)例自己的屬性,再通過(guò)原型來(lái)定義公共的方法和屬性。

這樣一來(lái),每個(gè)實(shí)例都有自己的實(shí)例屬性副本,又能共享同一個(gè)方法,這樣的好處就是可以極大的節(jié)省內(nèi)存空間。同時(shí)還可以向構(gòu)造函數(shù)傳遞參數(shù),十分的方便。

這里還要再講一下兩種特色的構(gòu)造函數(shù)模式:

1.寄生構(gòu)造函數(shù)

從形式上來(lái)看,這種模式和工廠模式并無(wú)區(qū)別:

function Person(name, age, job) {
  var o = new Object();
  o.name = name;
  o.age = age;
  o.job = job;
  o.sayName = function() {
    alert(this.name);
  };
  return o;
}
var friend = new Person("Nicholas", 29, "Software Engineer");
friend.sayName(); //"Nicholas"

都是在內(nèi)部創(chuàng)建一個(gè)Object對(duì)象實(shí)例,再賦予屬性和方法,最后返回,這種構(gòu)造模式的好處是,對(duì)于原生的引用類型創(chuàng)建的實(shí)例,例如Array,想為實(shí)例創(chuàng)建新的方法或者屬性時(shí),因?yàn)椴唤ㄗh直接修改原生的Array引用類型的構(gòu)造函數(shù),所以可以利用寄生構(gòu)造函數(shù):

function SpecialArray() {
  //創(chuàng)建數(shù)組
  var values = new Array();
  //添加值
  values.push.apply(values, arguments);
  //添加方法
  values.toPipedString = function() {
    return this.join("|");
  };
  //返回?cái)?shù)組
  return values;
}
var colors = new SpecialArray("red", "blue", "green");
alert(colors.toPipedString()); //"red|blue|green"

通過(guò)在內(nèi)部創(chuàng)建一個(gè)Array實(shí)例,并添加新的方法,最后將這個(gè)實(shí)例返回,既沒(méi)有修改原生的Array構(gòu)造函數(shù),又成功添加了自定義的方法和屬性。

缺點(diǎn):使用寄生構(gòu)造函數(shù)有一個(gè)缺點(diǎn),那就是返回的實(shí)例與構(gòu)造函數(shù)或構(gòu)造函數(shù)原型屬性之間沒(méi)有關(guān)系,與在構(gòu)造函數(shù)外創(chuàng)建實(shí)例沒(méi)有區(qū)別,也無(wú)法通過(guò)instanceof來(lái)確定對(duì)象類型,因此有其他更好選擇的時(shí)候,不推薦使用該方法。

2.穩(wěn)妥構(gòu)造函數(shù)

穩(wěn)妥構(gòu)造函數(shù)與寄生構(gòu)造函數(shù)類似,但是并不使用new和this(某些環(huán)境下禁止使用),前面的函數(shù)可以改寫(xiě)成這樣:

function Person(name, age, job) {
  //創(chuàng)建要返回的對(duì)象
  var o = new Object();

  //可以在這里定義私有變量和函數(shù)
  //添加方法
  o.sayName = function() {
    alert(name);
  };
  //返回對(duì)象
  return o;
}

說(shuō)完這些,現(xiàn)在來(lái)談?wù)勗屠^承和原型鏈,所謂繼承,基本思想是利用原型讓一個(gè)引用類型繼承另一個(gè)引用類型的方法和屬性。每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象,原型對(duì)象都包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例都包含一個(gè)指向原型對(duì)象的內(nèi)部指針。所有引用類型默認(rèn)都繼承了Object,而這個(gè)繼承也是通過(guò)原型鏈實(shí)現(xiàn)的。大家要記住,所有函數(shù)的默認(rèn)原型都是Object 的實(shí)例,因此默認(rèn)原型都會(huì)包含一個(gè)內(nèi)部指針,指向Object.prototype。

借用構(gòu)造函數(shù)(即在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型構(gòu)造函數(shù))

如果僅僅是借用構(gòu)造函數(shù),那么也將無(wú)法避免構(gòu)造函數(shù)模式存在的問(wèn)題——方法都在構(gòu)造函數(shù)中定
義,因此函數(shù)復(fù)用就無(wú)從談起了。而且,在超類型的原型中定義的方法,對(duì)子類型而言也是不可見(jiàn)的,結(jié)
果所有類型都只能使用構(gòu)造函數(shù)模式??紤]到這些問(wèn)題,借用構(gòu)造函數(shù)的技術(shù)也是很少單獨(dú)使用的。

組合繼承(思路是使用原型鏈實(shí)現(xiàn)對(duì)原型屬性和方法的繼承,而通過(guò)借用構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)對(duì)實(shí)例屬性的繼承)

function SuperType(name) {
  this.name = name;
  this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
  alert(this.name);

};
function SubType(name, age) {
  //繼承屬性
  SuperType.call(this, name);
  this.age = age;
}
//繼承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
  alert(this.age);
};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27

SuperType 構(gòu)造函數(shù)定義了兩個(gè)屬性:name 和colors。SuperType 的原型定義了一個(gè)方法sayName()。SubType 構(gòu)造函數(shù)在調(diào)用SuperType 構(gòu)造函數(shù)時(shí)傳入了name 參數(shù),緊接著又定義了它自己的屬性age。然后,將SuperType 的實(shí)例賦值給SubType 的原型,然后又在該新原型上定義了方法sayAge()。這樣一來(lái),就可以讓兩個(gè)不同的SubType 實(shí)例既分別擁有自己屬性——包括colors 屬性,又可以使用相同的方法了。

原型式繼承(借助原型可以基于已有的對(duì)象創(chuàng)建新對(duì)象,同時(shí)還不必因此創(chuàng)建自定義類型)

var person = {
  name: "Nicholas",
  friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
alert(person.friends); //"Shelby,Court,Van,Rob,Barbie"

在沒(méi)有必要興師動(dòng)眾地創(chuàng)建構(gòu)造函數(shù),而只想讓一個(gè)對(duì)象與另一個(gè)對(duì)象保持類似的情況下,原型式
繼承是完全可以勝任的。不過(guò)別忘了,包含引用類型值的屬性始終都會(huì)共享相應(yīng)的值,就像使用原型模
式一樣。

寄生式繼承(寄生式繼承的思路與寄生構(gòu)造函數(shù)和工廠模式類似,即創(chuàng)建一個(gè)僅用于封裝繼承過(guò)程的函數(shù),該函數(shù)在內(nèi)部以某種方式來(lái)增強(qiáng)對(duì)象,最后再像真地是它做了所有工作一樣返回對(duì)象)

function createAnother(original) {
  var clone = object(original); //通過(guò)調(diào)用函數(shù)創(chuàng)建一個(gè)新對(duì)象
  clone.sayHi = function() { //以某種方式來(lái)增強(qiáng)這個(gè)對(duì)象
    alert("hi");
  };
  return clone; //返回這個(gè)對(duì)象
}

寄生組合式繼承

通過(guò)借用構(gòu)造函數(shù)來(lái)繼承屬性,通過(guò)原型鏈的混成形式來(lái)繼承方法。其背后的基本思路是:不必為了指定子類型的原型而調(diào)用超類型的構(gòu)造函數(shù),我們所需要的無(wú)非就是超類型原型的一個(gè)副本而已。本質(zhì)上,就是使用寄生式繼承來(lái)繼承超類型的原型,然后再將結(jié)果指定給子類型的原型。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • tablesorter.js表格排序使用方法(支持中文排序)

    tablesorter.js表格排序使用方法(支持中文排序)

    這篇文章主要為大家詳細(xì)介紹了tablesorter.js表格排序使用方法,支持中文排序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • JS將所有對(duì)象s的屬性復(fù)制給對(duì)象r(原生js+jquery)

    JS將所有對(duì)象s的屬性復(fù)制給對(duì)象r(原生js+jquery)

    這篇文章主要介紹了js中將所有對(duì)象s的屬性復(fù)制給對(duì)象r的方法,原生js+jquery分別實(shí)現(xiàn)
    2014-01-01
  • JavaScript自執(zhí)行函數(shù)和jQuery擴(kuò)展方法詳解

    JavaScript自執(zhí)行函數(shù)和jQuery擴(kuò)展方法詳解

    這篇文章主要為大家詳細(xì)介紹了JavaScript自執(zhí)行函數(shù)和jQuery擴(kuò)展方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • 實(shí)例詳解ECMAScript5中新增的Array方法

    實(shí)例詳解ECMAScript5中新增的Array方法

    這篇文章主要介紹了實(shí)例詳解ECMAScript5中新增的Array方法的相關(guān)資料,需要的朋友可以參考下
    2016-04-04
  • JavaScript的變量聲明提升問(wèn)題淺析(Hoisting)

    JavaScript的變量聲明提升問(wèn)題淺析(Hoisting)

    大家應(yīng)該都只奧javascript的變量聲明具有hoisting機(jī)制,JavaScript引擎在執(zhí)行的時(shí)候,會(huì)把所有變量的聲明都提升到當(dāng)前作用域的最前面。網(wǎng)上關(guān)于JavaScript的變量聲明提升問(wèn)題的文章有很多,這篇文章將再次談?wù)勱P(guān)于這方面的問(wèn)題,有需要的朋友們可以參考借鑒。
    2016-11-11
  • JavaScript中的迭代器和生成器詳解

    JavaScript中的迭代器和生成器詳解

    這篇文章主要介紹了JavaScript中的迭代器和生成器詳解,本文講解了迭代器、聲明自定義迭代器、生成器:一種更好的方式來(lái)構(gòu)建迭代器、生成器高級(jí)特性等內(nèi)容,需要的朋友可以參考下
    2014-10-10
  • JS常見(jiàn)問(wèn)題之為什么點(diǎn)擊彈出的i總是最后一個(gè)

    JS常見(jiàn)問(wèn)題之為什么點(diǎn)擊彈出的i總是最后一個(gè)

    最近有很多朋友問(wèn)我,為什么點(diǎn)擊彈出的i總是最后一個(gè),于是抽時(shí)間寫(xiě)了這篇文章,特此分享到腳本之家平臺(tái),供大家參考
    2016-01-01
  • setTimeout函數(shù)的神奇使用

    setTimeout函數(shù)的神奇使用

    setTimeout函數(shù)是一個(gè)原生的javascript函數(shù)。setTimeout函數(shù)會(huì)在一個(gè)指定的延遲時(shí)間之后調(diào)用一個(gè)函數(shù)或執(zhí)行一段指定的代碼。它的應(yīng)用非常廣泛,例如我們希望用戶在瀏覽器某個(gè)頁(yè)面一段時(shí)間后彈出一個(gè)對(duì)話框,或者是鼠標(biāo)點(diǎn)擊某個(gè)元素后隔幾秒鐘在刪除這個(gè)元素。
    2017-02-02
  • 一個(gè)js封裝的不錯(cuò)的選項(xiàng)卡效果代碼

    一個(gè)js封裝的不錯(cuò)的選項(xiàng)卡效果代碼

    在論壇里經(jīng)??吹饺藛?wèn)選項(xiàng)卡或者類似選項(xiàng)卡的切換效果 這里封裝了個(gè)js,希望對(duì)大家有用 所有代碼都在下面了 如果有錯(cuò)誤或者建議,可以回貼告訴我,謝謝
    2008-02-02
  • JS 根據(jù)子網(wǎng)掩碼,網(wǎng)關(guān)計(jì)算出所有IP地址范圍示例

    JS 根據(jù)子網(wǎng)掩碼,網(wǎng)關(guān)計(jì)算出所有IP地址范圍示例

    這篇文章主要介紹了JS 根據(jù)子網(wǎng)掩碼,網(wǎng)關(guān)計(jì)算出所有IP地址范圍,涉及IP地址、子網(wǎng)的正則驗(yàn)證,子網(wǎng)掩碼計(jì)算等相關(guān)操作技巧,需要的朋友可以參考下
    2016-09-09

最新評(píng)論