摘要:事情的起因是在問答上看到一個朋友的提問,問的是阮一峰老師入門上關于關鍵字的一段代碼問題,下面是這個代碼的截圖這位樓主說他覺得的值不是,下面有網友說把代碼粘貼到控制臺一試就是這結果沒錯,后來樓主說是他想錯了。
事情的起因是在問答上看到一個朋友的提問,問的是阮一峰老師 ECMAScript 6 入門 上關于super關鍵字的一段代碼問題,下面是這個代碼的截圖:
這位樓主說他覺得 this.x 的值不是3,下面有網友說把代碼粘貼到 chrome 控制臺一試就是這結果沒錯,后來樓主說是他想錯了。我也順便把代碼粘貼到 chome 下執行后答案也確實是3。
本來這個事沒啥就結束了,正好我開著 WebStorm 準備寫代碼,順手粘貼到代碼文件里面,保存 > webpack打包 > 刷新瀏覽器,瞅了一眼 Console:
!這是神馬情況,輸出竟然是2!
問題分析為啥與 chrome 直接運行的結果不一致呢?想了想問題應該出在 Babel 轉碼上。馬上打開轉碼后的文件,定位到這段代碼的位置:
var B = function (_A) { _inherits(B, _A); function B() { _classCallCheck(this, B); var _this = _possibleConstructorReturn(this, (B.__proto__ || Object.getPrototypeOf(B)).call(this)); _this.x = 2; _set(B.prototype.__proto__ || Object.getPrototypeOf(B.prototype), "x", 3, _this); console.log(_get(B.prototype.__proto__ || Object.getPrototypeOf(B.prototype), "x", _this)); // undefined console.log(_this.x); // 3 return _this; } return B; }(A);
super.x = 3; 對應的是 _set(B.prototype.__proto__ || Object.getPrototypeOf(B.prototype), "x", 3, _this); 這里有個 _set() 函數,再看下這個 _set() 是啥:
var _set = function set(object, property, value, receiver) { var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent !== null) { set(parent, property, value, receiver); } } else if ("value" in desc && desc.writable) { desc.value = value; } else { var setter = desc.set; if (setter !== undefined) { setter.call(receiver, value); } } return value; };
仔細看看這個函數后,明白是怎么回事了。結合阮一峰老師的代碼和上面的轉碼可以看出,_set() 傳進來的第一個參數是 B.prototype.__proto__ -- 也就是A的原型對象 -- A.prototype,第一句代碼會先找 x屬性 的描述符,如果找不到繼續順著原型鏈找... 當然是找不到的了,所以相當于啥也沒執行,this.x 的值依然是2。
如果按照這個 _set() 函數的邏輯,在什么情況下 this.x 的值才會是3呢?要滿足兩個條件:
A.prototype 上必須有 x 屬性定義
這個 x 屬性定義上還必須定義 set 訪問器
比如像下面這樣:
Object.defineProperty(A.prototype, "x", { get: function () { return this._x; }, set: function (value) { this._x = value; } });
然后再跑一把,果然 this.x 的值是3了!等一下... 怎么 console.log(super.x); // undefined 這句的結果不是 undefined 也是3了呢?看下轉碼那里還有個 _get() 函數:
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
好吧,代碼走到最后 else 的 getter 那里了,自然 super.x 的讀取結果就是3了
目前還沒時間看為啥 Babel 要這么轉碼處理,如果你有答案了歡迎留言討論。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96042.html
一、前言通過CRA腳手架構建的項目,一般webpack配置是隱藏的,如果要修改,就要另外處理。想要修改webpack通常有兩種方式通過插件去增加或覆蓋webpack配置(方法一、方法二)或者釋放項目中的webpack配置,使之可見,然后可以修改(方法三)本來CRA腳手架將webpack等復雜的配置封裝在項目中,后續可以通過更新react-scripts來體驗版本升級帶來的新特性,但有些時候確實需要...
摘要:,是一個前端資源加載打包工具,現在版本已經到,今天的文章不支持介紹的及使用,而是對最近項目開發中使用打包時處理低版本及以下瀏覽器兼容問題做一次總結。 Webpack,Webpack 是一個前端資源加載/打包工具,現在版本已經 release 到 v2.6.1,今天的文章不支持介紹Webpack的API及使用,而是對最近項目開發中使用Webpack打包時處理IE低版本(IE8及以下)瀏覽...
小編寫這篇文章的主要目的,主要是對pandas做一個較為詳細的一個解答,pandas其實就是一個數據模型庫,里面的內容還是比較的多的,那么,怎么樣對海量的數據進行處理呢?處理的內容就是對超大的csv文件進行快速拆分,下面就給大家舉例驗證。 前言 本文介紹如何利用pandas對超大CSV文件進行快速拆分。 1.操作步驟 1.1安裝pandas pipinstallpandas 1.2...
摘要:我們將循環執行五次,每次將一個函數到數組中。只有當你理解了,才能給出正確的答案。讀者提到的兩個問題聲明的變量不是完全不可更改。不僅如此,而且有些最新的瀏覽器也還沒有支持。 譯者按: 使用let的確會比var安全很多。 原文: Why You Shouldn’t Use ‘var’ Anymore 譯者: Fundebug 為了保證可讀性,本文采用意譯而非直譯。 我已經使用ES2015(...
閱讀 2207·2021-11-22 11:56
閱讀 2650·2021-10-08 10:05
閱讀 7808·2021-09-22 15:53
閱讀 1918·2021-09-22 15:29
閱讀 2238·2021-09-08 09:35
閱讀 3359·2021-09-07 10:12
閱讀 1385·2019-08-30 13:11
閱讀 1978·2019-08-28 17:54