摘要:從源碼來看的用途表述該對象構造器是用于對某對象定義用戶自定義行為的。那么,這到底是什么意思呢我們下面直接來分析一下源碼中應用到對象的地方,來理解該對象構造器的作用。源碼講解該處定義了所允許的全局對象類型。
從vue源碼來看Proxy的用途
The Proxy object is used to define custom behavior for fundamental operations (e.g. property lookup, assignment, enumeration, function invocation, etc).MDN Proxy
MDN表述該對象構造器是用于對某對象定義用戶自定義行為的。那么,這到底是什么意思呢?我們下面直接來分析一下Vue源碼中應用到Proxy對象的地方,來理解該對象構造器的作用。
Proxy在Vue中的應用首先我們來看一看Vue源碼的 1430行
/* not type checking this file because flow doesn"t play well with Proxy */ var initProxy; { var allowedGlobals = makeMap( "Infinity,undefined,NaN,isFinite,isNaN," + "parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent," + "Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl," + "require" // for Webpack/Browserify ); var warnNonPresent = function(target, key) { warn( "Property or method "" + key + "" is not defined on the instance but " + "referenced during render. Make sure to declare reactive data " + "properties in the data option.", target ); }; var hasProxy = typeof Proxy !== "undefined" && Proxy.toString().match(/native code/); if (hasProxy) { var isBuiltInModifier = makeMap("stop,prevent,self,ctrl,shift,alt,meta"); config.keyCodes = new Proxy(config.keyCodes, { set: function set(target, key, value) { if (isBuiltInModifier(key)) { warn(("Avoid overwriting built-in modifier in config.keyCodes: ." + key)); return false } else { target[key] = value; return true } } }); } var hasHandler = { has: function has(target, key) { var has = key in target; var isAllowed = allowedGlobals(key) || key.charAt(0) === "_"; if (!has && !isAllowed) { warnNonPresent(target, key); } return has || !isAllowed } }; var getHandler = { get: function get(target, key) { if (typeof key === "string" && !(key in target)) { warnNonPresent(target, key); } return target[key] } }; initProxy = function initProxy(vm) { if (hasProxy) { // determine which proxy handler to use var options = vm.$options; var handlers = options.render && options.render._withStripped ? getHandler : hasHandler; vm._renderProxy = new Proxy(vm, handlers); } else { vm._renderProxy = vm; } }; }
首先,我們要明白一件事情,vue放棄了對ie9以下的支持。即使這樣,由于Proxy作為一個es6的新特性,支持度依然不高,作者也只是嘗試著使用了一下。下面我們來一步一步講解。
源碼講解var allowedGlobals = makeMap( "Infinity,undefined,NaN,isFinite,isNaN," + "parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent," + "Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl," + "require" // for Webpack/Browserify );
該處定義了所允許的全局對象類型。
var warnNonPresent = function(target, key) { warn( "Property or method "" + key + "" is not defined on the instance but " + "referenced during render. Make sure to declare reactive data " + "properties in the data option.", target ); };
該處定義了一個報警方法,傳入鍵名或方法名,log顯示一條警告
var hasProxy = typeof Proxy !== "undefined" && Proxy.toString().match(/native code/);
該處是對es6特性Proxy的檢測, 其檢測手段是確認Proxy是原生實現并未被用戶代碼所覆蓋。
var isBuiltInModifier = makeMap("stop,prevent,self,ctrl,shift,alt,meta"); config.keyCodes = new Proxy(config.keyCodes, { set: function set(target, key, value) { if (isBuiltInModifier(key)) { warn(("Avoid overwriting built-in modifier in config.keyCodes: ." + key)); return false } else { target[key] = value; return true } } });
該段代碼對config.keyCodes對象進行了代理,其意義在于禁止用戶修改Vue內建的一些按鍵值,這些按鍵值和按鍵名是對應的。如果用過Vue的用戶應該知道,Vue在事件對象上對一些常用按鍵和常用操作進行了內建(這個內建過程被用eval函數壓縮了,由一堆代碼段構成的,沒什么看頭),作者肯定不希望也不允許用戶修改配置的時候覆蓋了內建內容。于是,當我們做config.keyCodes["stop"] = xxx這樣的操作的時候,Vue就會告訴你說“你這個人,不老實,為什么想著改我東西”,直接打出禁止改寫內建配置的警告。如果非內建內容,那么可以直接設置上。
initProxy = function initProxy(vm) { if (hasProxy) { // determine which proxy handler to use var options = vm.$options; var handlers = options.render && options.render._withStripped ? getHandler : hasHandler; vm._renderProxy = new Proxy(vm, handlers); } else { vm._renderProxy = vm; } };
這句話就不再解釋了,類似上面。不過讀者可能會問has是什么? 那么下面我們來講解一下Proxy的各個參數
Proxy所需參數兩個, var b = new Proxy(a, { has: fn xxx, get: fn xxx, set: fn xxx .... })
target 被代理的對象
handler 處理器對象
用來定義我們對該對象的各種操作
完整的handler處理器對象內容:
{ get: "咋獲取", set: "咋設置", deleteProperty: "咋刪除", enumerate: "咋枚舉", ownKeys: "咋獲取所有該對象的屬性鍵 ", has: "問你有沒有, 比如 "xxx" in target", defineProperty: "如何defineProperty, 這個我們也是可以代理的", getOwnPropertyDescriptor: "獲取屬性描述的代理", getPrototypeOf: "找原型時候的代理", setPrototypeOf: "設置對象原型的時候的代理", isExtensible: "判斷對象是否可擴展的時候的代理", preventExtensions: "設置阻止對象擴展的時候的代理", apply: "執行調用操作的時候的代理", construct: "執行實例化的時候的代理" }
以上皆是函數~~
所以Proxy的作用是?攔截,預警,上報,擴展功能,統計,強化對象...能想得到的都能沾到點邊,這里Vue的代碼主要將代理運用于攔截。并且由于規范依然在發展,所以大家慎用。。。
資料MDN js Proxy Object
MDN Proxy Handler
sec-proxy-object-internal-methods-and-internal-slots
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81452.html
摘要:不同的代碼運行環境賦值的結果不同。當訪問的屬性不是類型或者屬性值在被代理的對象上不存在,則拋出錯誤提示,否則就返回該屬性值。該方法可以在開發者錯誤的調用屬性時,提供提示作用。只不過目前規范還沒有很完善,使用的時候要稍加注意。 前幾篇文章中,我們主要講了merge options的一些操作。今天我們回到init方法往下講。 if (process.env.NODE_ENV !== pro...
摘要:動態代理是語言中非常經典的一種設計模式,也是所有設計模式中最難理解的一種。本文將通過一個簡單的例子模擬動態代理實現,讓你徹底明白動態代理設計模式的本質,文章中可能會涉及到一些你沒有學習過的知識點或概念。 動態代理是Java語言中非常經典的一種設計模式,也是所有設計模式中最難理解的一種。本文將通過一個簡單的例子模擬JDK動態代理實現,讓你徹底明白動態代理設計模式的本質,文章中可能會涉及到...
摘要:本文主要學習的源碼的記錄。這里有一個的示例的數據會被插件生成器用來生成相應的項目文件。另一個遠程版本另外而是通過包獲取的版本。 本文主要學習vue-cli3.0的源碼的記錄。源碼地址: https://github.com/vuejs/vue-cli 主要對packages里面的@vue進行學習。如下圖 showImg(https://segmentfault.com/img/...
摘要:以上引用內容來自阮一峰的教程的章節原文地址請戳這里。最后本文最終實現代碼已經放在上,想要直接看效果的同學,可以上去直接,運行。 前言 如果你有讀過Vue的源碼,或者有了解過Vue的響應原理,那么你一定知道Object.defineProperty(),那么你也應該知道,Vue 2.x里,是通過 遞歸 + 遍歷 data對象來實現對數據的監控的,你可能還會知道,我們使用的時候,直接通過數...
摘要:在學習過程中,為加上了中文的注釋,希望可以對其他想學習源碼的小伙伴有所幫助。數據綁定原理前面已經講過數據綁定的原理了,現在從源碼來看一下數據綁定在中是如何實現的。 寫在前面 因為對Vue.js很感興趣,而且平時工作的技術棧也是Vue.js,這幾個月花了些時間研究學習了一下Vue.js源碼,并做了總結與輸出。文章的原地址:https://github.com/answershuto/le...
閱讀 1338·2021-11-15 11:37
閱讀 2218·2021-09-23 11:21
閱讀 1305·2019-08-30 15:55
閱讀 2111·2019-08-30 15:55
閱讀 2820·2019-08-30 15:52
閱讀 2823·2019-08-30 11:12
閱讀 1579·2019-08-29 18:45
閱讀 1893·2019-08-29 14:04