从Vue.js源码中我学到的几个实用函数
大家好,我是若川。歡迎加我微信?ruochuan12,長期交流學習。今天推薦Vuejs源碼中幾個實用的方法。
如果想看Vuejs源碼,不知道如何下手,一般推薦配置Sourcemap,針對單個問題調試來看,如何調試Vuejs源碼,我的vuex源碼文章中寫了。
點擊下方卡片關注我、加個星標,或者查看源碼等系列文章。學習源碼整體架構系列、年度總結、JS基礎系列
話不多說,趕快試試尤大大教給我們的這幾個實用函數吧!在工作中肯定會用得到。
立即執行函數
頁面加載完成后只執行一次的設置函數。
(function?(a,?b)?{console.log(a,?b);?//?1,2 })(1,?2);通常,全局變量被作為一個參數傳遞給立即執行參數,這樣它在函數內部不使用window也可以被訪問到。
(function?(global)?{console.log(global);?//?Window對象 })(this);多層嵌套三目運算符
三目運算符嵌套的寫法,使得代碼可讀性差,簡單業務場景下可以試著使用。
var?a?=?1; var?b?=?0; a?==?1???(b?==?2???(b?=?3)?:?(b?=?1))?:?""; console.log(b);?//?1凍結對象
不可對指定對象增刪改。
var?emptyObject?=?Object.freeze({key:?"1", }); emptyObject.name?=?"maomin"; delete?emptyObject.key; emptyObject.key?=?"2"; console.log(emptyObject);密封對象
只能對指定對象進行更改,不可進行增加刪除操作。
var?sealObject?=?Object.seal({key:?3, }); sealObject.name?=?"maomin"; delete?sealObject.key; sealObject.key?=?4; console.log(sealObject);?//?4檢查是否是原始值
function?isPrimitive(value)?{return?(typeof?value?===?"string"?||typeof?value?===?"number"?||//?$flow-disable-linetypeof?value?===?"symbol"?||typeof?value?===?"boolean"); }快速檢測是否是對象
當我們知道原始值時,它主要用于將對象與原始值區分開來。
function?isObject(obj)?{return?obj?!==?null?&&?typeof?obj?===?"object"; } console.log(isObject(true));?//false檢測目標類型
var?_toString?=?Object.prototype.toString;function?toRawType(value)?{return?_toString.call(value).slice(8,?-1); } console.log(toRawType([]));?//?Array檢查目標是否是有效的數組索引
function?isValidArrayIndex(val)?{var?n?=?parseFloat(String(val));return?n?>=?0?&&?Math.floor(n)?===?n?&&?isFinite(val); }檢測是否是Promise對象
function?isDef(v)?{return?v?!==?undefined?&&?v?!==?null; } function?isPromise(val)?{return?(isDef(val)?&&typeof?val.then?===?"function"?&&typeof?val.catch?===?"function"); } var?promiseObj?=?new?Promise(function?(resolve,?reject)?{//?一段耗時的異步操作resolve("成功");?//?數據處理完成//?reject('失敗')?//?數據處理出錯 }).then((res)?=>?{console.log(res);},?//?成功(err)?=>?{console.log(err);}?//?失敗 ); console.log(isPromise(promiseObj));?//?true目標轉換為字符串
var?_toString?=?Object.prototype.toString; function?isPlainObject(obj)?{return?_toString.call(obj)?===?"[object?Object]"; } function?toString(val)?{return?val?==?null??"":?Array.isArray(val)?||?(isPlainObject(val)?&&?val.toString?===?_toString)??JSON.stringify(val,?null,?2):?String(val); } console.log(toString({?name:?1?}));?//?{"name":?1}轉化為數字
將輸入值轉換為數字以便持久化。如果轉換失敗,則返回原始字符串。
function?toNumber(val)?{var?n?=?parseFloat(val);return?isNaN(n)???val?:?n; }檢測key是否在創建的Map對象內
function?makeMap(str,?expectsLowerCase)?{var?map?=?Object.create(null);var?list?=?str.split(",");for?(var?i?=?0;?i?<?list.length;?i++)?{map[list[i]]?=?true;}return?expectsLowerCase??function?(val)?{return?map[val.toLowerCase()];}:?function?(val)?{return?map[val];}; } var?isBuiltInTag?=?makeMap("slot,component",?true); console.log(isBuiltInTag("component"));?//?true刪除簡單數組中某一項
function?remove(arr,?item)?{if?(arr.length)?{var?index?=?arr.indexOf(item);if?(index?>?-1)?{return?arr.splice(index,?1);}} } console.log(remove([1,?2],?1));?//?[1]檢測對象中是否有指定key
var?hasOwnProperty?=?Object.prototype.hasOwnProperty; function?hasOwn(obj,?key)?{return?hasOwnProperty.call(obj,?key); } console.log(hasOwn({?name:?1?},?"name"));?//true將類數組對象轉化為真實數組
function?toArray(list,?start)?{start?=?start?||?0;var?i?=?list.length?-?start;var?ret?=?new?Array(i);while?(i--)?{ret[i]?=?list[i?+?start];}return?ret; } console.log(toArray({?0:?42,?1:?52,?2:?63,?length:?3?}));?//?[42,?52,?63]將屬性混合到目標對象中
function?extend(to,?_from)?{for?(var?key?in?_from)?{to[key]?=?_from[key];}return?to; } console.log(extend({?name:?1?},?{?name1:?2?}));?//?{name:1,name1:2}將對象數組合并為單個對象
function?extend(to,?_from)?{for?(var?key?in?_from)?{to[key]?=?_from[key];}return?to; } function?toObject(arr)?{var?res?=?{};for?(var?i?=?0;?i?<?arr.length;?i++)?{if?(arr[i])?{extend(res,?arr[i]);}}return?res; } console.log(toObject([{?name:?1?},?{?name:?1?},?{?name:?2?},?{?name1:?3?}]));?//?{name:?2,?name1:?3}檢測指定項在數組(簡單數組、數組對象)中的索引
function?isObject(obj)?{return?obj?!==?null?&&?typeof?obj?===?"object"; } function?looseEqual(a,?b)?{if?(a?===?b)?{return?true;}var?isObjectA?=?isObject(a);var?isObjectB?=?isObject(b);if?(isObjectA?&&?isObjectB)?{try?{var?isArrayA?=?Array.isArray(a);var?isArrayB?=?Array.isArray(b);if?(isArrayA?&&?isArrayB)?{return?(a.length?===?b.length?&&a.every(function?(e,?i)?{return?looseEqual(e,?b[i]);}));}?else?if?(a?instanceof?Date?&&?b?instanceof?Date)?{return?a.getTime()?===?b.getTime();}?else?if?(!isArrayA?&&?!isArrayB)?{var?keysA?=?Object.keys(a);var?keysB?=?Object.keys(b);return?(keysA.length?===?keysB.length?&&keysA.every(function?(key)?{return?looseEqual(a[key],?b[key]);}));}?else?{/*?istanbul?ignore?next?*/return?false;}}?catch?(e)?{/*?istanbul?ignore?next?*/return?false;}}?else?if?(!isObjectA?&&?!isObjectB)?{return?String(a)?===?String(b);}?else?{return?false;} }function?looseIndexOf(arr,?val)?{for?(var?i?=?0;?i?<?arr.length;?i++)?{if?(looseEqual(arr[i],?val))?{return?i;}}return?-1; } console.log(looseIndexOf([{?name:?1?},?{?name:?2?}],?4));?//?-1 console.log(looseIndexOf([{?name:?1?},?{?name:?2?}],?{?name:?1?}));?//?0確保函數只調用一次
function?once(fn)?{var?called?=?false;return?function?()?{if?(!called)?{called?=?true;fn.apply(this,?arguments);}}; } var?callOnce?=?once(function?()?{console.log("javascript"); }); callOnce();?//?javascript callOnce();定義對象屬性
如果你想禁止一個對象添加新屬性并且保留已有屬性,就可以使用Object.preventExtensions(obj)。
function?def(obj,?key,?val,?enumerable)?{Object.defineProperty(obj,?key,?{value:?val,?//?對象定義屬性enumerable:?!!enumerable,?//?描述屬性是否會出現在for?in?或者?Object.keys()的遍歷中writable:?true,?//?是否可寫configurable:?true,?//?是否重新定義或者刪除}); } var?obj?=?{name:?1, }; def(obj,?"name1",?2,?true); obj.name1?=?3; console.log(obj);?//?{name:?1,?name1:?3}瀏覽器環境嗅探
var?inBrowser?=?typeof?window?!==?"undefined"; var?inWeex?=?typeof?WXEnvironment?!==?"undefined"?&&?!!WXEnvironment.platform; var?weexPlatform?=?inWeex?&&?WXEnvironment.platform.toLowerCase(); var?UA?=?inBrowser?&&?window.navigator.userAgent.toLowerCase();var?isIE?=?UA?&&?/msie|trident/.test(UA); var?isIE9?=?UA?&&?UA.indexOf("msie?9.0")?>?0; var?isEdge?=?UA?&&?UA.indexOf("edge/")?>?0; var?isAndroid?=?(UA?&&?UA.indexOf("android")?>?0)?||?weexPlatform?===?"android"; var?isIOS?=?(UA?&&?/iphone|ipad|ipod|ios/.test(UA))?||?weexPlatform?===?"ios"; var?isChrome?=?UA?&&?/chrome\/\d+/.test(UA)?&&?!isEdge; var?isPhantomJS?=?UA?&&?/phantomjs/.test(UA); var?isFF?=?UA?&&?UA.match(/firefox\/(\d+)/);JS構造函數內的方法與構造函數prototype屬性上方法的對比
定義在構造函數內部的方法,會在它的每一個實例上都克隆這個方法;定義在構造函數的 prototype 屬性上的方法會讓它的所有示例都共享這個方法,但是不會在每個實例的內部重新定義這個方法。如果我們的應用需要創建很多新的對象,并且這些對象還有許多的方法,為了節省內存,我們建議把這些方法都定義在構造函數的 prototype 屬性上。當然,在某些情況下,我們需要將某些方法定義在構造函數中,這種情況一般是因為我們需要訪問構造函數內部的私有變量。
function?A()?{this.say?=?function?()?{console.log(1);}; } var?a?=?new?A(); a.say(); function?B()?{} B.prototype.say?=?function?()?{console.log(2); }; var?b?=?new?B(); b.say(); var?c?=?new?B(); c.say();獲取標簽內容(包含標簽)
function?getOuterHTML(el)?{if?(el.outerHTML)?{return?el.outerHTML;}?else?{var?container?=?document.createElement("div");container.appendChild(el.cloneNode(true));return?container.innerHTML;} }字符串hash值
function?hash(str)?{var?hash?=?5381;var?i?=?str.length;while?(i)?{hash?=?(hash?*?33)?^?str.charCodeAt(--i);}return?hash?>>>?0; } console.log(hash("222sd"));//?164533792最近組建了一個江西人的前端交流群,如果你也是江西人可以加我微信 ruochuan12 拉你進群。
·················?若川出品?·················
今日話題
有時候付費學習,真的是能節省很多時間,時間也是資源,也是金錢。視頻學習和書籍學習都是很好的學習方式,相輔相成,當然,符合自己學習方式才是最重要的。書籍出版一般要經過嚴格審核流程,網上視頻的質量參差不齊。歡迎分享、收藏、點贊、在看我的公眾號文章~
一個愿景是幫助5年內前端人走向前列的公眾號
可加我個人微信 ruochuan12,長期交流學習
推薦閱讀
我在阿里招前端,我該怎么幫你?(現在還能加我進模擬面試群)
如何拿下阿里巴巴 P6 的前端 Offer
點擊上方卡片關注我、加個星標,或者查看源碼等系列文章。
學習源碼整體架構系列、年度總結、JS基礎系列
總結
以上是生活随笔為你收集整理的从Vue.js源码中我学到的几个实用函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件测试资源
- 下一篇: vue2 怎么用vite_vite快速入