摘要:你可以輕松為你的函數庫添加防沖突功能。系列系列目錄地址。如果有錯誤或者不嚴謹的地方,請務必給予指正,十分感謝。
防沖突
underscore 使用 _ 作為函數的掛載對象,如果頁面中已經存在了 _ 對象,underscore 就會覆蓋該對象,舉個例子:
var _ = {value: 1 } // 引入 underscore 后 console.log(_.value); // undefined
所以 underscore 提供了 noConflict 功能,可以放棄 underscore 的控制變量 _,返回 underscore 對象的引用。
var _ = {value: 1 } // 引入 underscore 后 // 放棄 "_",使用 "$" var $ = _.noConflict(); console.log(_.value); // 1 // 使用 underscore 的方法 $.each([1, 2, 3], alert);
那么 noConflict 函數是如何實現的呢?
首先,在 underscore 執行的時候,會儲存之前的 _ 對象,然后當執行 noConflict 函數的時候,再將之前儲存的 _ 對象賦給全局對象,最后返回 underscore 對象。這樣,我們就可以利用返回的 underscore 對象使用 underscore 提供的各種方法。
// 源碼一開始的時候便儲存之前的 _ 對象 var previousUnderscore = root._; _.noConflict = function() { root._ = previousUnderscore; return this; };
是的,就是這么簡單。你可以輕松為你的函數庫添加防沖突功能。
接下來我們看 underscore 中的一些功能函數。
_.identity_.identity = function(value) { return value; };
看起來匪夷所思的一個函數,傳入一個值,然后返回該值,為什么不直接使用該值呢?
還記得我們在《underscore 系列之內部函數 cb 和 optimizeCb》中接觸過這個函數嗎?
如果我們自己編寫了一個 _.map 函數:
_.map = function(arr, iteratee){ return arr.map(iteratee) }
然而當我們這樣使用 _.map([1, 2, 3]) 時便會報錯,因為我們沒有傳入 iteratee 函數,然而使用 underscore 卻沒有問題,結果是返回一個相同的新數組,原因就在于當 iteratee 為 undefined 的時候,underscore 視為傳入了 _.identity 函數。就相當于:
_.map = function(arr, iteratee){ if (!iteratee) iteratee = _.identity return arr.map(iteratee) }
簡而言之,如果我們想要復制一個數組:
var clonedArr = [1, 2, 3].map(_.identity) // [1, 2, 3]_.constant
_.constant = function(value) { return function() { return value; }; };
該函數傳入一個 value,然后返回一個返回該 value 的函數,這又有什么用呢?我們來看個 demo:
var value = 1; var getValue = _.constant(value); value = 2; getValue(); // 1 getValue(); // 1
這很容易讓人想到 ES6 的 const,我一開始以為就是用來表示 ES6 的 const ,后來看了這個函數起源的 issue,才發現并非如此,它其實像下面的 _.noop 函數一樣可以作為默認函數使用。
舉個例子:
_.select(collection, filterFunction || function() { return true; })
我們根據 filterFunction 篩選 collection 中符合條件的元素,如果沒有傳 filterFunction,我們就返回所有的元素,如果有 _.constant 函數,我們可以將其簡化為:
_.select(collection, filterFunction || _.constant(true))
盡管沒有什么大的改變,但是語義更加明確。
_.noop_.noop = function(){};
一個空函數,看起來依舊沒什么用……
noop 函數可以用于作為默認值,這樣就可以省去是否存在的判斷,舉個例子:
// 不使用 noop function a(value, callback){ // 每次使用 callback 都要判斷一次 _.isFunction(callback) && callback() } // 使用 noop function a(value, callback) { // 判斷一次 if(!_.isFunction(callback)) callback = _.noop; // 以后都可以直接使用 callback() }deepGet
var deepGet = function(obj, path) { var length = path.length; for (var i = 0; i < length; i++) { if (obj == null) return void 0; obj = obj[path[i]]; } return length ? obj : void 0; };
deepGet 用于獲得對象深層次的值。舉個例子:
var obj = { value: { deepValue: 2 } } console.log(deepGet(obj, ["value", "deepValue"]))
使用這個函數,可以避免深層次取值時,因為沒有其中的一個屬性,導致的報錯。
shallowPropertyvar shallowProperty = function(key) { return function(obj) { return obj == null ? void 0 : obj[key]; }; };
shallowProperty 也是用于獲取對象的屬性,也許你會好奇在開發中,直接使用. 不就可以獲取對象的屬性了,為什么還要寫成這樣呢?我們來舉個例子:
// 獲取 arr 所有元素的 name 屬性 var arr = [ { value: 1, name: "Kevin" }, { value: 2, name: "Daisy" } ] // 普通方式 var names = arr.map(function(item){ return item.name; }) // 使用 shallowProperty var names = arr.map(shallowProperty("name"))_.property
_.property = function(path) { if (!_.isArray(path)) { return shallowProperty(path); } return function(obj) { return deepGet(obj, path); }; };
_.property 結合了 deepGet 和 shallowProperty,可以獲取元素深層次的值。上面一個例子也可以寫成:
var names = arr.map(_.property("name"))_.propertyOf
_.propertyOf = function(obj) { if (obj == null) { return function(){}; } return function(path) { return !Array.isArray(path) ? obj[path] : deepGet(obj, path); }; };
_.property 返回一個函數,這個函數返回任何傳入的對象的指定屬性。
_.propertyOf 與 _.property 相反。需要一個對象,并返回一個函數,這個函數將返回一個提供的屬性的值。
我們寫個例子:
// 獲取 person 對象的所有屬性值 var person = { name: "Kevin", age: "18" }; // 普通方式 var values = Object.keys(person).map((key) => person[key]); // ["Kevin", "18"] // 使用 _.propertyOf var values = Object.keys(person).map(_.propertyOf(person)); // ["Kevin", "18"_.random
返回一個 min 和 max 之間的隨機整數。如果你只傳遞一個參數,那么將返回 0 和這個參數之間的整數。
_.random = function(min, max) { if (max == null) { max = min; min = 0; } return min + Math.floor(Math.random() * (max - min + 1)); };
注意:該隨機值有可能是 min 或 max。
underscore 系列underscore 系列目錄地址:https://github.com/mqyqingfeng/Blog。
underscore 系列預計寫八篇左右,重點介紹 underscore 中的代碼架構、鏈式調用、內部函數、模板引擎等內容,旨在幫助大家閱讀源碼,以及寫出自己的 undercore。
如果有錯誤或者不嚴謹的地方,請務必給予指正,十分感謝。如果喜歡或者有所啟發,歡迎 star,對作者也是一種鼓勵。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92136.html
摘要:所以它與其他系列的文章并不沖突,完全可以在閱讀完這個系列后,再跟著其他系列的文章接著學習。如何閱讀我在寫系列的時候,被問的最多的問題就是該怎么閱讀源碼我想簡單聊一下自己的思路。感謝大家的閱讀和支持,我是冴羽,下個系列再見啦 前言 別名:《underscore 系列 8 篇正式完結!》 介紹 underscore 系列是我寫的第三個系列,前兩個系列分別是 JavaScript 深入系列、...
摘要:直接來看例子一目了然,第一個參數是對象,第二個參數可以是一系列的值,也可以是數組數組中含,也可以是迭代函數,我們根據值,或者迭代函數來過濾中的鍵值對,返回新的對象副本。 Why underscore 最近開始看 underscore.js 源碼,并將 underscore.js 源碼解讀 放在了我的 2016 計劃中。 閱讀一些著名框架類庫的源碼,就好像和一個個大師對話,你會學到很多。...
摘要:所以經常會在一個源碼中看到寫法吧立即執行函數創建變量,保存全局根變量。 // ================立即執行函數================ // 使用(function(){}())立即執行函數,減少全局變量 // ----????----函數聲明 function (){} 與函數表達式 var funName = function(){}----????---- /...
摘要:提供如下函數,很是方便提供了常用的函數。建議使用,性能優異很多的實現。補充了缺少的對字符串的操作,不過有些其實原生就帶了。與配合使用無壓力。其他語言被移植到了其他語言,例如和。 underscore提供如下函數,很是方便: Underscore 提供了常用的函數。 Collections each map reduce reduceRight find filter whe...
摘要:是前端常用的庫,最近無意中發現原來它還有的移植。基本介紹絕大部分函數都移植過來了。用的是,可是這個在中已經用來表示了,所以改成了,雙下劃線。函數一覽絕大部分都移植過來了我自己更習慣寫原生。 underscore是前端常用的javascript庫,最近無意中發現原來它還有PHP的移植。 基本介紹 絕大部分函數都移植過來了。underscore.js用的是_,可是這個在PHP中已經用來...
閱讀 578·2023-04-25 21:29
閱讀 1104·2023-04-25 21:27
閱讀 1044·2021-11-25 09:43
閱讀 1077·2021-09-29 09:43
閱讀 3614·2021-09-03 10:30
閱讀 2854·2019-08-29 15:26
閱讀 2803·2019-08-29 12:52
閱讀 1741·2019-08-29 11:10