久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      es6 class是語法糖嗎

      class是語法糖。原因:class是基于原型繼承的實現(xiàn),對語言的功能并沒有什么影響,只是方便了語法的書寫及閱讀;class的本質(zhì)是function,能夠讓對象原型的寫法更加清晰,更像面向?qū)ο缶幊痰恼Z法。

      es6 class是語法糖嗎

      前端(vue)入門到精通課程:進入學(xué)習(xí)
      Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調(diào)試工具:點擊使用

      本教程操作環(huán)境:windows7系統(tǒng)、ECMAScript 6版、Dell G3電腦。

      ES6 class類——語法糖

      class (類)作為對象的模板被引入,可以通過 class 關(guān)鍵字定義類。它的本質(zhì)是函數(shù)(function),可以看作一個語法糖,讓對象原型的寫法更加清晰、更像面向?qū)ο缶幊痰恼Z法。

      它的class和別的語言不一樣,它依舊是基于原型繼承的實現(xiàn),對語言的功能并沒有影響,只是方便了你的書寫及閱讀

      為什么說ES6的class是語法糖

      我們帶著問題去閱讀下文:

      • 為什么說ES6的class是語法糖?
      • class是原型的語法糖嗎?
      • 那又是如何使用原型來實現(xiàn)class這一語法糖的呢?

      1. 基于Prototype的OOP

      先來看一個prototype的例子:

      function Person (name, sex) { 	this.name = name 	this.sex = sex }   function Man (name) { 	this.name = name }   Man.prototype = new Person('', 'male')   let Jy = new Man('Jy')   console.log(Jy.name, Jy.sex) // Jy, male
      登錄后復(fù)制

      這是我們使用原型的一個很簡單的例子,Person具有名字和性別,Man是一個性別為男的Person,Jy是一個Man。我們先記住這一個例子,下面將使用class重寫這個例子。

      Tips: new, this等是Brendan Eich使之更像Java的OOP而加上的,有興趣的讀者可以自行查閱相關(guān)信息。

      2. ES6 Class的OOP

      class Person { 	constructor (name, sex) { 		this.name = name 		this.sex = sex 	} }   class Man extends Person { 	constructor (name) { 		super('', 'male') 		this.name = name 	} }   let Jy = new Man('Jy')   console.log(Jy.name, Jy.sex) // Jy, 'male'
      登錄后復(fù)制

      我們通過重寫這個例子,采用了class、constructor、extends、super 這些單詞,接下來就具體來說說ES6規(guī)范中對它們做了什么。

      3. 使用Prototype實現(xiàn)的Class OOP(ES6規(guī)范)

      在ES6之前,JS對象其實就是屬性的集合,而屬性則是一組鍵值對(key, value),key可以是String or Symbol, value包括數(shù)據(jù)屬性特征值和訪問器特征值。

      你說普通的屬性還好,不還有對象下面的方法嗎?怎么就變成了屬性的集合呢?

      其實在ES5規(guī)范中出現(xiàn)的method的定義是“function that is the value of a property”,是對象的函數(shù)屬性而已,不能稱之為方法,直到ES6出現(xiàn),規(guī)范中才有Method Definitions。

      我們能想到的在ES3有關(guān)OOP的東西: prototype、new、 this、 constructor、 instanceof, 甚至不是規(guī)范的 __proto__ 屬性。

      所幸的是在ES5中我們增加了很多方法來補全它,使之完備:

      • Object.defineProperty
      • Object.freeze
      • Object.create
      • Object.getPrototypeOf
      • Object.setPrototypeOf
      • isPrototypeOf
      • ……

      再來看一段代碼:

      let obj = { 	name: 'Jy', 	speak () { // Note: it's not speak: function () {} 		console.log(this.name, super.name) 	} }   obj.speak() // Jy, undefined   Object.setPrototypeOf(obj,  { name: 'super' })   obj.speak() // Jy, super   let speak = obj.speak speak() // undefined, super
      登錄后復(fù)制

      obj.speak在ES6中定義已經(jīng)是Method了,它具有屬性[[homeObject]],homeObject指向方法被調(diào)用的對象(代碼中指的是obj), 它是綁定在對象中的Internal Slots,也就是你不能去修改,就相當于寫死了。

      那么homeObject有什么用呢?它跟super密切相關(guān),當解析到super這一關(guān)鍵字的時候就會找homeObject的prototype。

      簡單來說,總結(jié)為下面兩條公式:

      • let homeObj = Method[[HomeObject]] = obj
      • super = Object.getPrototypeOf(homeObj)

      Note: homeObject是靜態(tài)綁定在internal slots中的,而super是動態(tài)查找的。

      講完super,我們來講講extends和constructor

      class A extends B { }   class A extends B { 	constructor (...args) { 		super(args) 	} }   class C extends null { }
      登錄后復(fù)制

      extends主要做了以下兩件事:

      • Object.setPrototypeOf(A, B)
      • Object.setPrototypeOf(A.prototype, B.prototype)

      如果父類是null, 則執(zhí)行Object.setPrototypeOf(C.prototype, null)

      上述代碼的第一和第二部分區(qū)別在于有沒有顯示聲明constructor, 那么這兩段代碼是否等價呢?答案是等價的。

      規(guī)范中就是這么定義的:

      代碼的第三部分是繼承了null, 它不會報語法錯誤,但是我們無法new一個C出來,原因是new的時候會調(diào)用null的constructor,而null沒有constructor。

      看到這里,ES6的class oop, 規(guī)范聲明都是使用原型來操作,所以我們是不是可以說class是原型的語法糖了?

      4. babel編譯后的class

      我們實際項目中多采用babel來編譯ES6、7的代碼,所以這節(jié)我們就來分析以下babel編譯后的代碼,其中會省略一些報錯、類型檢測的一些相關(guān)代碼來更好地呈現(xiàn)使用原型來實現(xiàn)OOP的主題。

      編譯前:

      class A extends B {}   console.log(new A)
      登錄后復(fù)制

      編譯后:

      "use strict";   function _getPrototypeOf(o) {   _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {     return o.__proto__ || Object.getPrototypeOf(o);   };   return _getPrototypeOf(o); }   function _inherits(subClass, superClass) {   if (typeof superClass !== "function" && superClass !== null) {     throw new TypeError("Super expression must either be null or a function");   }   subClass.prototype = Object.create(superClass && superClass.prototype, {     constructor: {       value: subClass,       writable: true,       configurable: true     }   });   if (superClass) _setPrototypeOf(subClass, superClass); }   function _setPrototypeOf(o, p) {   _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {     o.__proto__ = p;     return o;   };   return _setPrototypeOf(o, p); }   var A =   /*#__PURE__*/   function (_B) {     _inherits(A, _B);       function A() {         return _getPrototypeOf(A).apply(this, arguments);     }       return A;   }(B);   console.log(new A());
      登錄后復(fù)制

      我們重點看_inherits 方法,跟我們上述說的extends做的兩件事是一樣的:

      • Object.setPrototypeOf(subClass, superClass)
      • Object.setPrototypeOf(subClass.prototype, superClass.prototype)

      只不過它采用的是Object.create方法,這兩個方法的區(qū)別可以去MDN上查看。

      再看function A內(nèi)部,其實就是執(zhí)行了B的構(gòu)造器函數(shù)來達到super(arguments)的效果, 這個與規(guī)范:如果沒有顯示聲明constructor會自動加上constructor是一致的。

      5. 總結(jié)

      至此,我們終于理解了為什么class是原型的語法糖以及如何使用原型來實現(xiàn)class這一語法糖。

      但切記我們使用原型的目的并不是來模擬class oop的,prototype based的oop應(yīng)該用prototype去理解而不是class。

      ES6的class oop 是不完備的 ,例如abstract class 、interface、private等都還沒有,不過有些功能已經(jīng)在提案中了,大家可以擁抱它,或者TypeScript是個不錯的選擇,如果你的項目中使用到了TS, 歡迎你到評論區(qū)分享你的感受。

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號