自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Vue源碼中值得學習的方法

開發(fā) 前端
最近在深入研究vue源碼,把學習過程中,看到的一些好玩的的函數(shù)方法收集起來做分享,希望對大家對深入學習js有所幫助。

最近在深入研究vue源碼,把學習過程中,看到的一些好玩的的函數(shù)方法收集起來做分享,希望對大家對深入學習js有所幫助。如果大家都能一眼看懂這些函數(shù),說明技術還是不錯的哦。

[[348906]]

1. 數(shù)據(jù)類型判斷

Object.prototype.toString.call()返回的數(shù)據(jù)格式為 [object Object]類型,然后用slice截取第8位到倒一位,得到結果為 Object

  1. var _toString = Object.prototype.toString; 
  2. function toRawType (value) { 
  3.   return _toString.call(value).slice(8, -1) 

運行結果測試

  1. toRawType({}) //  Object  
  2. toRawType([])  // Array     
  3. toRawType(true) // Boolean 
  4. toRawType(undefined) // Undefined 
  5. toRawType(null) // Null 
  6. toRawType(function(){}) // Function 

2. 利用閉包構造map緩存數(shù)據(jù)

vue中判斷我們寫的組件名是不是html內置標簽的時候,如果用數(shù)組類遍歷那么將要循環(huán)很多次獲取結果,如果把數(shù)組轉為對象,把標簽名設置為對象的key,那么不用依次遍歷查找,只需要查找一次就能獲取結果,提高了查找效率。

  1. function makeMap (str, expectsLowerCase) { 
  2.     // 構建閉包集合map 
  3.     var map = Object.create(null); 
  4.     var list = str.split(','); 
  5.     for (var i = 0; i < list.length; i++) { 
  6.       map[list[i]] = true; 
  7.     } 
  8.     return expectsLowerCase 
  9.       ? function (val) { return map[val.toLowerCase()]; } 
  10.       : function (val) { return map[val]; } 
  11. // 利用閉包,每次判斷是否是內置標簽只需調用isHTMLTag 
  12. var isHTMLTag = makeMap('html,body,base,head,link,meta,style,title') 
  13. console.log('res', isHTMLTag('body')) // true 

3. 二維數(shù)組扁平化

vue中_createElement格式化傳入的children的時候用到了simpleNormalizeChildren函數(shù),原來是為了拍平數(shù)組,使二維數(shù)組扁平化,類似lodash中的flatten方法。

  1. // 先看lodash中的flatten 
  2. _.flatten([1, [2, [3, [4]], 5]]) 
  3. // 得到結果為  [1, 2, [3, [4]], 5] 
  4.  
  5. // vue中 
  6. function simpleNormalizeChildren (children) { 
  7.   for (var i = 0; i < children.length; i++) { 
  8.     if (Array.isArray(children[i])) { 
  9.       return Array.prototype.concat.apply([], children) 
  10.     } 
  11.   } 
  12.   return children 
  13.  
  14. // es6中 等價于 
  15. function simpleNormalizeChildren (children) { 
  16.    return [].concat(...children) 

4. 方法攔截

vue中利用Object.defineProperty收集依賴,從而觸發(fā)更新視圖,但是數(shù)組卻無法監(jiān)測到數(shù)據(jù)的變化,但是為什么數(shù)組在使用push pop等方法的時候可以觸發(fā)頁面更新呢,那是因為vue內部攔截了這些方法。

  1. // 重寫push等方法,然后再把原型指回原方法 
  2.   var ARRAY_METHOD = [ 'push', 'pop', 'shift', 'unshift', 'reverse',  'sort', 'splice' ]; 
  3.   var array_methods = Object.create(Array.prototype); 
  4.   ARRAY_METHOD.forEach(method => { 
  5.     array_methods[method] = function () { 
  6.       // 攔截方法 
  7.       console.log('調用的是攔截的 ' + method + ' 方法,進行依賴收集'); 
  8.       return Array.prototype[method].apply(this, arguments); 
  9.     } 
  10.   }); 

運行結果測試

  1. var arr = [1,2,3] 
  2. arr.__proto__ = array_methods // 改變arr的原型 
  3. arr.unshift(6) // 打印結果: 調用的是攔截的 unshift 方法,進行依賴收集 

5. 繼承的實現(xiàn)

vue中調用Vue.extend實例化組件,Vue.extend就是VueComponent構造函數(shù),而VueComponent利用Object.create繼承Vue,所以在平常開發(fā)中Vue 和 Vue.extend區(qū)別不是很大。這邊主要學習用es5原生方法實現(xiàn)繼承的,當然了,es6中 class類直接用extends繼承。

  1. // 繼承方法  
  2.  function inheritPrototype(Son, Father) { 
  3.    var prototype = Object.create(Father.prototype) 
  4.    prototype.constructor = Son 
  5.    // 把Father.prototype賦值給 Son.prototype 
  6.    Son.prototype = prototype 
  7.  } 
  8.  function Father(name) { 
  9.    this.name = name 
  10.    this.arr = [1,2,3] 
  11.  } 
  12.  Father.prototype.getName = function() { 
  13.    console.log(this.name) 
  14.  } 
  15.  function Son(name, age) { 
  16.    Father.call(this, name) 
  17.    this.age = age 
  18.  } 
  19.  inheritPrototype(Son, Father) 
  20.  Son.prototype.getAge = function() { 
  21.    console.log(this.age) 
  22.  } 

運行結果測試

  1. var son1 = new Son("AAA", 23) 
  2. son1.getName()            //AAA 
  3. son1.getAge()             //23 
  4. son1.arr.push(4)           
  5. console.log(son1.arr)     //1,2,3,4 
  6.  
  7. var son2 = new Son("BBB", 24) 
  8. son2.getName()            //BBB 
  9. son2.getAge()             //24 
  10. console.log(son2.arr)     //1,2,3 

6. 執(zhí)行一次

once 方法相對比較簡單,直接利用閉包實現(xiàn)就好了

  1. function once (fn) { 
  2.   var called = false
  3.   return function () { 
  4.     if (!called) { 
  5.       called = true
  6.       fn.apply(this, arguments); 
  7.     } 
  8.   } 

7. 淺拷貝

簡單的深拷貝我們可以用 JSON.stringify() 來實現(xiàn),不過vue源碼中的looseEqual 淺拷貝寫的也很有意思,先類型判斷再遞歸調用,總體也不難,學一下思路。

  1. function looseEqual (a, b) { 
  2.   if (a === b) { return true } 
  3.   var isObjectisObjectA = isObject(a); 
  4.   var isObjectisObjectB = isObject(b); 
  5.   if (isObjectA && isObjectB) { 
  6.     try { 
  7.       var isArrayA = Array.isArray(a); 
  8.       var isArrayB = Array.isArray(b); 
  9.       if (isArrayA && isArrayB) { 
  10.         return a.length === b.length && a.every(function (e, i) { 
  11.           return looseEqual(e, b[i]) 
  12.         }) 
  13.       } else if (!isArrayA && !isArrayB) { 
  14.         var keysA = Object.keys(a); 
  15.         var keysB = Object.keys(b); 
  16.         return keysA.length === keysB.length && keysA.every(function (key) { 
  17.           return looseEqual(a[key], b[key]) 
  18.         }) 
  19.       } else { 
  20.         /* istanbul ignore next */ 
  21.         return false 
  22.       } 
  23.     } catch (e) { 
  24.       /* istanbul ignore next */ 
  25.       return false 
  26.     } 
  27.   } else if (!isObjectA && !isObjectB) { 
  28.     return String(a) === String(b) 
  29.   } else { 
  30.     return false 
  31.   } 
  32. function isObject (obj) { 
  33.   return obj !== null && typeof obj === 'object' 

 

責任編輯:趙寧寧 來源: segmentfault
相關推薦

2020-10-26 10:40:31

Axios前端攔截器

2022-06-06 07:50:55

PythonJSON

2025-02-25 08:51:19

2011-04-15 13:12:09

.NETMEF

2022-09-19 10:07:30

制造業(yè)IT領導者

2023-06-09 10:27:13

Vue開源

2022-06-28 09:44:21

DevOps軟件開發(fā)

2010-03-31 15:52:24

Oracle子查詢

2011-08-19 09:41:56

C++

2024-02-19 08:07:31

Go版本語言

2014-10-30 10:28:09

HTML5

2017-09-10 17:08:11

Java 9程序Oracle

2021-11-26 05:59:31

Vue3 插件Vue應用

2017-12-18 08:55:03

2025-02-28 09:52:19

2010-02-23 09:39:25

DB2 9.7

2015-06-10 09:17:48

數(shù)據(jù)中心規(guī)劃設計

2024-11-18 00:18:18

2018-05-10 17:32:03

機器學習人工智能入門方法

2021-12-31 07:48:58

Vue3 插件Vue應用
點贊
收藏

51CTO技術棧公眾號