成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

匯總有關(guān)JS對象的創(chuàng)建與繼承

3403771864 / 505人閱讀

  之前也有和大家講過有關(guān)JS的對象創(chuàng)建和對象繼承,本篇文章主要為大家做個匯總和梳理。

  JS中其實(shí)就是原型鏈繼承和構(gòu)造函數(shù)繼承的“毛病”,還有就是“工廠、構(gòu)造、原型”設(shè)計(jì)模式與JS繼承。

       JS高級程序設(shè)計(jì)4:class繼承的重點(diǎn),不只是簡簡單單的語法而已。

  對象創(chuàng)建

  不難發(fā)現(xiàn),每一篇都離不開工廠、構(gòu)造、原型這3種設(shè)計(jì)模式中的至少其一!

  那JS為什么非要用到這種3種設(shè)計(jì)模式了呢??

  我們先從對象創(chuàng)建講起:

  let car={
  price:100,
  color:"white",
  run:()=>{console.log("run fast")}
  }

  當(dāng)有兩個或多個這樣的對象需要聲明時(shí),無法一直這樣復(fù)制下去的:

  let car1={
  price:100,
  color:"white",
  run:()=>{console.log("run fast")}
  }
  let car2={
  price:200,
  color:"balck",
  run:()=>{console.log("run slow")}
  }
  let car3={
  price:300,
  color:"red",
  run:()=>{console.log("broken")}
  }

  這樣寫:

  其實(shí)上面寫的不僅麻煩,而且代碼量也比較大;

  也不必方便修改,比如當(dāng)car對象要增刪改一個屬性,需要多處進(jìn)行增刪改;

  工廠函數(shù)

  肯定是要封裝啦,第一個反應(yīng),可以借助函數(shù)來幫助我們批量創(chuàng)建對象~

  于是乎:

  function makeCar(price,color,performance){
  let obj={}
  obj.price=price
  obj.color=color
  obj.run=()=>{console.log(performance)}
  return obj
  }
  let car1=makeCar("100","white","run fast")
  let car2=makeCar("200","black","run slow")
  let car3=makeCar("300","red","broken")

  上面的是工廠設(shè)計(jì)模式在JS創(chuàng)建對象時(shí)應(yīng)用的由來~

  如果有其他需求,比如,需要創(chuàng)建car4、car5、car6對象,它們要在原有基礎(chǔ)上再新增一個brand屬性,會怎么寫?

  第一反應(yīng),直接修改makeCar

  function makeCar(price,color,performance,brand){
  let obj={}
  obj.price=price
  obj.color=color
  obj.run=()=>{console.log(performance)}
  obj.brand=brand
  return obj
  }
  let car4=makeCar("400","white","run fast","benz")
  let car5=makeCar("500","black","run slow","audi")
  let car6=makeCar("600","red","broken","tsl")

  這代碼是錯誤的,會影響原有的car1、car2、car3對象;

  那再重新寫一個makeCarChild工廠函數(shù)行不行?

  function makeCarChild(price,color,performance,brand){
  let obj={}
  obj.price=price
  obj.color=color
  obj.run=()=>{console.log(performance)}
  obj.brand=brand
  return obj
  }
  let car4=makeCarChild("400","white","run fast","benz")
  let car5=makeCarChild("500","black","run slow","audi")
  let car6=makeCarChild("600","red","broken","tsl")

  為了方便,全量復(fù)制之前的屬性,建立N個相像的工廠,這種方法不行。

  構(gòu)造函數(shù)

  于是乎,在工廠設(shè)計(jì)模式上,發(fā)展出了:構(gòu)造函數(shù)設(shè)計(jì)模式,來解決以上復(fù)用(也就是繼承)的問題。

  function MakeCar(price,color,performance){
  this.price=price
  this.color=color
  this.run=()=>{console.log(performance)}
  }
  function MakeCarChild(brand,...args){
  MakeCar.call(this,...args)
  this.brand=brand
  }
  let car4=new MakeCarChild("benz","400","white","run fast")
  let car5=new MakeCarChild("audi","500","black","run slow")
  let car6=new MakeCarChild("tsl","600","red","broken")

  構(gòu)造函數(shù)區(qū)別于工廠函數(shù):

  函數(shù)名首字母通常大寫;

  創(chuàng)建對象的時(shí)候要用到new關(guān)鍵字(new的過程這里不再贅述了,之前文章有);

  函數(shù)沒有return,而是通過this綁定來實(shí)現(xiàn)尋找屬性的;

  到此為止,工廠函數(shù)的復(fù)用也解決了。

  構(gòu)造+原型

  新的問題在于,我們不能通過查找原型鏈從MakeCarChild找到MakeCar

  car4.__proto__===MakeCarChild.prototype//true
  MakeCarChild.prototype.__proto__===MakeCar.prototype//false
  MakeCarChild.__proto__===MakeCar.prototype//false

  無論在原型鏈上怎么找,都無法從MakeCarChild找到MakeCar

  這樣也就明白了,子類不能繼承父類原型上的屬性

  這里提個思考問題:為什么“要從原型鏈查找到”很重要?為什么“子類要繼承父類原型上的屬性”?就靠this綁定來找不行嗎?

  于是乎,構(gòu)造函數(shù)設(shè)計(jì)模式+原型設(shè)計(jì)模式的【組合繼承】應(yīng)運(yùn)而生 

 function MakeCar(price,color,performance){
  this.price=price
  this.color=color
  this.run=()=>{console.log(performance)}
  }
  function MakeCarChild(brand,...args){
  MakeCar.call(this,...args)
  this.brand=brand
  }
  MakeCarChild.prototype=new MakeCar()//原型繼承父類的構(gòu)造器
  MakeCarChild.prototype.constructor=MakeCarChild//重置constructor
  let car4=new MakeCarChild("benz","400","white","run fast")

  現(xiàn)在再找原型,就找的到啦:

  car4.__proto__===MakeCarChild.prototype//true
  MakeCarChild.prototype.__proto__===MakeCar.prototype//true

  其實(shí),能到這里,就已經(jīng)很很優(yōu)秀了,該有的都有了,寫法也不算是很復(fù)雜。

  工廠+構(gòu)造+原型

  但,總有人在追求極致。

  上述的組合繼承,父類構(gòu)造函數(shù)被調(diào)用了兩次,一次是call的過程,一次是原型繼承new的過程,如果每次實(shí)例化,都重復(fù)調(diào)用,肯定是不可取的,怎樣避免?

  工廠+構(gòu)造+原型=寄生組合繼承應(yīng)運(yùn)而生

  核心是,通過工廠函數(shù)新建一個中間商F(),復(fù)制了一份父類的原型對象,再賦給子類的原型;

  function object(o){//工廠函數(shù)
  function F(){}
  F.prototype=o;
  return new F();//new一個空的函數(shù),所占內(nèi)存很小
  }
  function inherit(child,parent){//原型繼承
  var prototype=object(parent.prototype)
  prototype.constructor=child
  child.prototype=prototype
  }
  function MakeCar(price,color,performance){
  this.price=price
  this.color=color
  this.run=()=>{console.log(performance)}
  }
  function MakeCarChild(brand,...args){//構(gòu)造函數(shù)
  MakeCar.call(this,...args)
  this.brand=brand
  }
  inherit(MakeCarChild,MakeCar)
  let car4=new MakeCarChild("benz","400","white","run fast")
  car4.__proto__===MakeCarChild.prototype//true
  MakeCarChild.prototype.__proto__===MakeCar.prototype//true

  ES6 class

  再到后來,ES6的class作為寄生組合繼承的語法糖:

  class MakeCar{
  constructor(price,color,performance){
  this.price=price
  this.color=color
  this.performance=performance
  }
  run(){
  console.log(console.log(this.performance))
  }
  }
  class MakeCarChild extends MakeCar{
  constructor(brand,...args){
  super(brand,...args);
  this.brand=brand;
  }
  }
  let car4=new MakeCarChild("benz","400","white","run fast")

 

 car4.__proto__===MakeCarChild.prototype//true
  MakeCarChild.prototype.__proto__===MakeCar.prototype//true

  有興趣的工友,可以看下ES6解析成ES5的代碼:原型與原型鏈-ES6 Class的底層實(shí)現(xiàn)原理#22

  對象與函數(shù)

  最后本瓜想再談?wù)勱P(guān)于JS對象和函數(shù)的關(guān)系:

  即使是這樣聲明一個對象,let obj={},它一樣是由構(gòu)造函數(shù)Object構(gòu)造而來的:

  let obj={}
  obj.__proto__===Object.prototype//true

  在JS中,萬物皆對象,對象都是有函數(shù)構(gòu)造而來,函數(shù)本身也是對象。

  對應(yīng)代碼中的意思:

  所有的構(gòu)造函數(shù)的隱式原型都等于Function的顯示原型,函數(shù)都是由Function構(gòu)造而來,Object構(gòu)造函數(shù)也不例外;

  所有構(gòu)造函數(shù)的顯示原型的隱式原型,都等于Object的顯示原型,F(xiàn)unction也不例外;

  //1.
  Object.__proto__===Function.prototype//true
  //2.
  Function.prototype.__proto__===Object.prototype//true

  對于這個設(shè)計(jì)我只可以給一個大大的無語了。

  先這樣說吧:Function就是上帝,上帝創(chuàng)造了萬物;Object就是萬物。萬物由上帝創(chuàng)造(對象由函數(shù)構(gòu)造而來),上帝本身也屬于一種物質(zhì)(函數(shù)本身卻也是對象);

  對于本篇來說,繼承,其實(shí)都是父子構(gòu)造函數(shù)在繼承,然后再由構(gòu)造函數(shù)實(shí)例化對象,以此來實(shí)現(xiàn)對象的繼承。

  到底是誰在繼承?函數(shù)?對象?都是吧~~

  小結(jié)

  本篇由創(chuàng)建對象說起,講了工廠函數(shù),它可以做一層最基本的封裝;

  再到,對工廠的拓展,演進(jìn)為構(gòu)造函數(shù);

  再基于原型特點(diǎn),構(gòu)造+原型,得出組合繼承;

  再追求極致,講到寄生組合;

  再講到簡化書寫的Es6 class;

  以及最后對對象與函數(shù)的思考。

     本篇文章到此結(jié)束了,歡迎大家關(guān)注后續(xù)更多精彩內(nèi)容。



文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/130356.html

相關(guān)文章

  • 前端工程師面試必備(持續(xù)更新中)

    摘要:最近的一次更新的變量有效,并且會作用于全部的引用的處理方式和相同,變量值輸出時(shí)根據(jù)之前最近的一次定義計(jì)算,每次引用最近的定義有效嵌套三種預(yù)編譯器的選擇器嵌套在使用上來說沒有任何區(qū)別,甚至連引用父級選擇器的標(biāo)記也相同。 面試匯總一:2018大廠高級前端面試題匯總 高級面試:【半月刊】前端高頻面試題及答案匯總 css內(nèi)容 響應(yīng)式布局 當(dāng)前主流的三種預(yù)編譯器比較 CSS預(yù)處理器用一種專門的...

    jubincn 評論0 收藏0
  • js對象創(chuàng)建方法匯總及對比

    摘要:中創(chuàng)建對象的方式有很多,尤其是基于原型的方式創(chuàng)建對象,是理解基于原型繼承的基礎(chǔ)。該函數(shù)中的屬性指向該源性對象當(dāng)通過該函數(shù)的構(gòu)造函數(shù)創(chuàng)建一個具體對象時(shí),在這個對象中,就會有一個屬性指向原型。 js中創(chuàng)建對象的方式有很多,尤其是基于原型的方式創(chuàng)建對象,是理解基于原型繼承的基礎(chǔ)。因此在這里匯總一下,并對各種方法的利弊進(jìn)行總結(jié)和對比,不至于以后對這些概念有模糊。 簡單方式創(chuàng)建 var o = ...

    piapia 評論0 收藏0
  • 屬性設(shè)置百分比時(shí)計(jì)算參考匯總

    摘要:對象脫離常規(guī)流,偏移定位是以窗口為參考絕對定位的元素,在,,,屬性未設(shè)置時(shí),會緊隨在其前面的兄弟元素之后,但在位置上不影響常規(guī)流中的任何元素。例如設(shè)置百分比時(shí),子元素繼承是父元素乘以百分百之后的具體數(shù)值,所以可能會出現(xiàn)重疊現(xiàn)象。元素寬高 width,min-width,max-width等元素寬度設(shè)置百分比,以包含塊的寬度為標(biāo)準(zhǔn)進(jìn)行計(jì)算; height,min-height,max-hei...

    Moxmi 評論0 收藏0
  • 前端面試經(jīng)典題目匯總(持續(xù)更新中)

    摘要:只要沒有被覆蓋的話對象原型的屬性就能在所有的實(shí)例中找到,若整個原型鏈未找到則返回如何實(shí)現(xiàn)繼承構(gòu)造繼承原型繼承實(shí)例繼承拷貝繼承原型機(jī)制或和方法去實(shí)現(xiàn)較簡單,建議使用構(gòu)造函數(shù)與原型混合方式。 HTML相關(guān)問題 1.XHTML和HTML有什么區(qū)別 HTML是一種基本的WEB網(wǎng)頁設(shè)計(jì)語言,XHTML是一個基于XML的標(biāo)記語言最主要的不同:XHTML 元素必須被正確地嵌套。XHTML 元素必須被...

    BigNerdCoding 評論0 收藏0
  • 前端面試經(jīng)典題目匯總(持續(xù)更新中)

    摘要:只要沒有被覆蓋的話對象原型的屬性就能在所有的實(shí)例中找到,若整個原型鏈未找到則返回如何實(shí)現(xiàn)繼承構(gòu)造繼承原型繼承實(shí)例繼承拷貝繼承原型機(jī)制或和方法去實(shí)現(xiàn)較簡單,建議使用構(gòu)造函數(shù)與原型混合方式。 HTML相關(guān)問題 1.XHTML和HTML有什么區(qū)別 HTML是一種基本的WEB網(wǎng)頁設(shè)計(jì)語言,XHTML是一個基于XML的標(biāo)記語言最主要的不同:XHTML 元素必須被正確地嵌套。XHTML 元素必須被...

    Warren 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<