摘要:可以是數(shù)字或者是字符串如果是數(shù)字則表示屬性名前加上空格符號(hào)的數(shù)量,如果是字符串,則直接在屬性名前加上該字符串。
最后更新于2019年1月13日
前端常用代碼片段(一) 點(diǎn)這里
前端常用代碼片段(二) 點(diǎn)這里
前端常用代碼片段(三) 點(diǎn)這里
前端常用代碼片段(四) 點(diǎn)這里
前端常用代碼片段(五) 點(diǎn)這里
前端常用代碼片段(六) 點(diǎn)這里
function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1) + min) } export function shuffle(arr) { let _arr = arr.slice() for (let i = 0; i < _arr.length; i++) { let j = getRandomInt(0, i) let t = _arr[i] _arr[i] = _arr[j] _arr[j] = t } return _arr }
擴(kuò)展:
1.取[10,100) 的隨機(jī)整數(shù)方法Math.floor(Math.random()*90+10);2.取[10,100] 的隨機(jī)整數(shù)方法
function randomBy(under, over){ switch(arguments.length){ case 1: return parseInt(Math.random()*under+1); case 2: return parseInt(Math.random()*(over-under+1) + under); default: return 0; } } randomBy(10, 100);
//隨機(jī)返回一個(gè)范圍的數(shù)字 randomNumber(n1, n2) { //randomNumber(5,10) //返回5-10的隨機(jī)整數(shù),包括5,10 if (arguments.length === 2) { return Math.round(n1 + Math.random() * (n2 - n1)); } //randomNumber(10) //返回0-10的隨機(jī)整數(shù),包括0,10 else if (arguments.length === 1) { return Math.round(Math.random() * n1) } //randomNumber() //返回0-255的隨機(jī)整數(shù),包括0,255 else { return Math.round(Math.random() * 255) } }3.利用sort()
我們先產(chǎn)生個(gè)數(shù)組
var arr=[]; for(var i=0;i<10;i++){ arr.push(i) } console.log(arr) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
我們以前的正常排序是這樣的:
arr.sort(function(a,b){ return b-a });
接下來我們來打亂它:
arr.sort(()=>{ return Math.random() - 0.5 }) // [1, 0, 2, 3, 4, 6, 8, 5, 7, 9]
第二種打亂方法:
arr.sort((a,b)=>{ return a > Math.random()*10; }) // [1, 2, 0, 6, 4, 3, 8, 9, 7, 5]
解析:
先說正常的排序:2.函數(shù)節(jié)流(throttle)和 函數(shù)去抖(debounce)
a,b表示數(shù)組中的任意兩個(gè)元素,若return > 0 ,b前a后;若reutrn < 0 則a前b后;當(dāng)a=b時(shí),則存在瀏覽器兼容 ;
a-b輸出從小到大排序,b-a輸出從大到小排序。
然后再說我們打亂的方法:
創(chuàng)建數(shù)組不用說,接下來就是用js的sort方法 來實(shí)現(xiàn),Math.random()實(shí)現(xiàn)一個(gè)隨機(jī)0-1之間的小數(shù) 然后再減去0.5,這時(shí)就會(huì)根據(jù)return比較后得到的值排序,所以說就會(huì)生成不是正常從大到小或者從小到大的排序。
函數(shù)節(jié)流 和 函數(shù)去抖 都是為了項(xiàng)目?jī)?yōu)化而出現(xiàn)的,官方是沒有具體定義的,他們的出現(xiàn)主要是為了解決一些短時(shí)間內(nèi)連續(xù)執(zhí)行的事件帶來性能上的不佳和內(nèi)存的消耗巨大等問題;像這類事件一般像 scroll keyup mousemove resize等等,短時(shí)間內(nèi)不斷的觸發(fā),在性能上消耗是非常大的,尤其是一些改變DOM結(jié)構(gòu)的操作;
節(jié)流[throttle]與防抖[debounce]非常相似,都是讓上述這類事件里定義的代碼 從不斷的執(zhí)行 更改成為 規(guī)定的時(shí)間內(nèi)執(zhí)行多少次;
函數(shù)節(jié)流(throttle) 應(yīng)用場(chǎng)景函數(shù)節(jié)流(throttle),例如實(shí)現(xiàn)一個(gè)拖拽功能,需要一路監(jiān)聽 mousemove 事件,在回調(diào)中獲取元素當(dāng)前位置,然后重置 dom 的位置(樣式改變)。如果我們不加以控制,每移動(dòng)一定像素而觸發(fā)的回調(diào)數(shù)量是會(huì)非常驚人的,回調(diào)中又伴隨著 DOM 操作,繼而引發(fā)瀏覽器的重排與重繪,性能差的瀏覽器可能就會(huì)直接假死,這樣的用戶體驗(yàn)是非常糟糕的。我們需要做的是降低觸發(fā)回調(diào)的頻率,比如讓它 500ms 觸發(fā)一次,或者 1000ms,這個(gè)閾值不能太大,太大了拖拽就會(huì)失真,也不能太小,太小了低版本瀏覽器可能就會(huì)假死,這樣的解決方案就是函數(shù)節(jié)流。函數(shù)節(jié)流的核心是,讓一個(gè)函數(shù)不要執(zhí)行得太頻繁,減少一些過快的調(diào)用來節(jié)流。
函數(shù)節(jié)流有哪些應(yīng)用場(chǎng)景?哪些時(shí)候我們需要間隔一定時(shí)間觸發(fā)回調(diào)來控制函數(shù)調(diào)用頻率?
DOM 元素的拖拽功能實(shí)現(xiàn)(mousemove)
射擊游戲的 mousedown/keydown 事件(單位時(shí)間只能發(fā)射一顆子彈)
計(jì)算鼠標(biāo)移動(dòng)的距離(mousemove)
Canvas 模擬畫板功能(mousemove)
搜索聯(lián)想(keyup)
監(jiān)聽滾動(dòng)事件判斷是否到頁面底部自動(dòng)加載更多:給 scroll 加了 debounce 后,只有用戶停止?jié)L動(dòng)后,才會(huì)判斷是否到了頁面底部;如果是 throttle 的話,只要頁面滾動(dòng)就會(huì)間隔一段時(shí)間判斷一次
節(jié)流通俗來解釋就比如我們水龍頭放水,閥門一打開,水嘩嘩的往下流,這個(gè)秉著勤儉節(jié)約的優(yōu)良傳統(tǒng)美德,我們要把水龍頭關(guān)小點(diǎn),最好是如我們心意按照一定規(guī)律在某個(gè)時(shí)間間隔內(nèi)一滴一滴的往下滴,這,,,好吧這就是我們節(jié)流的概念;換成函數(shù)來說,使用setTimeout方法,給定兩個(gè)時(shí)間,后面的時(shí)間減去前面的時(shí)間,到達(dá)我們給定的時(shí)間就去觸發(fā)一次這個(gè)事件,這么說太籠統(tǒng)的,我們看下面的函數(shù),這里我們以【scroll】為例;
/** 樣式我就順便寫了 **/ ------------------------ /** 先給定DOM結(jié)構(gòu);**/------------------------ /**主要看js,為了簡(jiǎn)單我用JQ去寫了**/
或
export function throttle(delay, action){ let last = return function(){ let curr = +new Date() if (curr - last > delay){ action.apply(this, arguments) last = curr } } }函數(shù)去抖(debounce) 應(yīng)用場(chǎng)景
寫代碼之前,我們先清楚一下防抖的概念,不知道大家有沒有做過電腦端兩邊懸浮廣告窗口的這么一個(gè)東西,當(dāng)我們拖動(dòng)滾動(dòng)條的時(shí)候,兩邊的廣告窗口會(huì)因?yàn)闈L動(dòng)條的拖動(dòng),而不斷的嘗試著去居于中間,然后你就會(huì)看到這兩個(gè)窗口,不停的抖啊抖;
一般這種就叫抖動(dòng)了,我們要做的就是防止這種抖動(dòng),稱為防抖[debounce ];
那這里防抖思想就是當(dāng)我們拖動(dòng)完成之后,兩邊的窗口位置再重新去計(jì)算,這樣,就會(huì)顯得很平滑,看著很舒服了,最主要的操作DOM結(jié)構(gòu)的次數(shù)就大大減少了;
優(yōu)化了頁面性能,降低了內(nèi)存消耗,不然你像IE這種比較老點(diǎn)版本的瀏覽器,說不定就直接給你蹦了
用書面一點(diǎn)的說法就是,在某個(gè)事件沒有結(jié)束之前,函數(shù)不會(huì)執(zhí)行,當(dāng)結(jié)束之后,我們給定延時(shí)時(shí)間,然他在給定的延時(shí)時(shí)間之后再去執(zhí)行這個(gè)函數(shù),這就是防抖函數(shù);
來看代碼:
//將上面案例的throttle函數(shù)替換為debounce函數(shù); function debounce(method,time){ var timer = null ; return function(){ var context = this; //在函數(shù)執(zhí)行的時(shí)候先清除timer定時(shí)器; clearTimeout(timer); timer = setTimeout(function(){ method.call(context); },time); } }
思路就是在函數(shù)執(zhí)行之前,我們先清除定時(shí)器,如果函數(shù)一直執(zhí)行,就會(huì)不斷的去清除定時(shí)器中的方法,知道我們操作結(jié)束之后,函數(shù)才會(huì)執(zhí)行;
或
export function debounce(func, delay) { let timer return function(...args) { if (timer) { clearTimeout(timer) } timer = setTimeout(() => { func.apply(this, args) }, delay) } }
用途
當(dāng)我們做keyup像后臺(tái)請(qǐng)求檢驗(yàn)的時(shí)候,可以使用防抖函數(shù),不然我們每按一次鍵盤就請(qǐng)求一次,請(qǐng)求太頻繁,這樣當(dāng)我們結(jié)束按鍵盤的時(shí)候再去請(qǐng)求,請(qǐng)求少很多了,性能自然不用說;
resize 窗口大小調(diào)整的時(shí)候,我們可以采用防抖技術(shù)也可以使用節(jié)流;
mousemove 鼠標(biāo)移動(dòng)事件我們既可以采用防抖也可以使用節(jié)流;
scroll 滾動(dòng)條觸發(fā)的事件,當(dāng)然既可以采用防抖也可以采用節(jié)流;
連續(xù)高頻發(fā)的事件都可以采用這兩種方式去解決,優(yōu)化頁面性能;
具體的采用哪一種更較為合適,主要還是看你的業(yè)務(wù)需求
區(qū)分
節(jié)流說白了就是每ms執(zhí)行一次函數(shù),防抖就是 最后一次觸發(fā)后ms后執(zhí)行一次回調(diào)函數(shù)。
節(jié)流就是擰緊水龍頭,讓水滴一滴一滴流,而去抖則是按壓一個(gè)彈簧,不松手則彈簧不會(huì)觸發(fā)函數(shù)節(jié)流和去抖都是限制基于DOM事件執(zhí)行的javascript數(shù)量的方法,都是為了提高JS性能,但是兩者是有區(qū)別的。
推薦閱讀
函數(shù)節(jié)流和去抖之間的區(qū)別
本小節(jié)引用
avaScript 函數(shù)節(jié)流...
JavaScript 高級(jí)系列...
這個(gè)是網(wǎng)上一個(gè)網(wǎng)友提的問題,自己未曾遇到也為實(shí)驗(yàn),先保存在這
源代碼:
原因:
圖片的比例不是1:1(圖片縱橫比不為1)
解決方法:(待驗(yàn)證)
或
border-radius:100%4.如何優(yōu)雅的實(shí)現(xiàn)金錢格式化:1234567890 --> 1,234,567,890
用正則魔法實(shí)現(xiàn):
var test1 = "1234567890" var format = test1.replace(/B(?=(d{3})+(?!d))/g, ",") console.log(format) // 1,234,567,890
非正則的優(yōu)雅實(shí)現(xiàn):
function formatCash(str) { return str.split("").reverse().reduce((prev, next, index) => { return ((index % 3) ? next : (next + ",")) + prev }) } console.log(formatCash("1234567890")) // 1,234,567,8905.如何最佳的讓兩個(gè)整數(shù)交換數(shù)值
常規(guī)辦法:
var a=1,b=2; a += b; b = a - b; a -= b;
缺點(diǎn)也很明顯,整型數(shù)據(jù)溢出,對(duì)于32位字符最大表示數(shù)字是2147483647,如果是2147483645和2147483646交換就失敗了。
黑科技辦法:
a ^= b; b ^= a; a ^= b;
es6:
[b,a] = [a,b]6.實(shí)現(xiàn)標(biāo)準(zhǔn)JSON的深拷貝
var a = { a: 1, b: { c: 1, d: 2 } } var b=JSON.parse(JSON.stringify(a))
不考慮IE的情況下,標(biāo)準(zhǔn)JSON格式的對(duì)象蠻實(shí)用,不過對(duì)于undefined和function的會(huì)忽略掉。
7.在str前添加一個(gè)?號(hào),+str會(huì)強(qiáng)制轉(zhuǎn)Number不用Number、parseInt和parseFloat和方法把"88"字符串轉(zhuǎn)換成數(shù)字
var str="88"; console.log(+str) // 88 //或者 console.log(str - 0) // 88 //但是如果是混合類型的字符串,則會(huì)轉(zhuǎn)為NaN var b="1606e"; console.log(+b) // NaN8.數(shù)組去重
方法1:最短的代碼實(shí)現(xiàn)es6
[...new Set([1, "1", 2, 1, 1, 3])]
function uniqueArray(arr){ return Array.from(new Set(arr)); }
方法2:使用filter + indexOf
如下代碼所示:
removeRepeatArray(arr) { return arr.filter(function (item, index, self) { return self.indexOf(item) === index; }); }
方法3:使用splice
如下代碼所示:
function uniqueArray(arr){ for(var i = 0; i < arr.length - 1; i++){ for(var j = i + 1; j < arr.length; j++){ if(arr[j] === arr[i]){ arr.splice(j--, 1); } } } return arr; }
方法4:只用Array
如下代碼所示:
function uniqueArray(arr){ var retArray = []; for(var i = 0; i < arr.length; i++){ if(retArray.indexOf(arr[i]) < 0){ retArray.push(arr[i]); } } return retArray; }
方法5:Object.keys(對(duì)象)
let a = ["1", "2", "3", 1,NaN,NaN,undefined,undefined,null,null, "a", "b", "b"]; const unique = arr => { var obj = {} arr.forEach(value => { obj[value] = 0;//這步新添加一個(gè)屬性,并賦值,如果不賦值的話,屬性會(huì)添加不上去 }) return Object.keys(obj);//`Object.keys(對(duì)象)`返回這個(gè)對(duì)象可枚舉屬性組成的數(shù)組,這個(gè)數(shù)組就是去重后的數(shù)組 } console.log(unique(a));//["1", "2", "3", "NaN", "undefined", "null", "a", "b"]
注意:
這個(gè)方法會(huì)將 number,NaN,undefined,null,變?yōu)樽址问?,因?yàn)閷?duì)象的屬性名就是一個(gè)字符串
Array(6).fill(8)10.取出一個(gè)數(shù)組中的最大值和最小值
var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411]; var maxInNumbers = Math.max.apply(Math, numbers); // 或 Math.max(...arr) var minInNumbers = Math.min.apply(Math, numbers); // 或 Math.min(...arr)11.將argruments對(duì)象轉(zhuǎn)換成數(shù)組
var argArray = Array.prototype.slice.call(arguments);
或者ES6:
var argArray = Array.from(arguments)12.短路表達(dá)式
條件判斷
var a = b && 1 // 相當(dāng)于 if (b) { a = 1 } else { a = b }
var a = b || 1 // 相當(dāng)于 if (b) { a = b } else { a = 1 }13.RGB to Hex
function toHEX(rgb){ return ((1<<24) + (rgb.r<<16) + (rgb.g<<8) + rgb.b).toString(16).substr(1); }14.JSON.stringify()妙用
1 語法
JSON.stringify(value[, replacer[, space]])
一般用法:
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; JSON.stringify(user); "{"name":"andy","isDead":false,"age":11,"addr":"shanghai"}"
2 擴(kuò)展用法
2.1 replacer
replacer可以是函數(shù)或者是數(shù)組。
功能1: 改變屬性值
將isDead屬性的值翻譯成0或1,0對(duì)應(yīng)false,1對(duì)應(yīng)true
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; JSON.stringify(user, function(key, value){ if(key === "isDead"){ return value === true ? 1 : 0; } return value; }); //"{"name":"andy","isDead":0,"age":11,"addr":"shanghai"}"
功能2:刪除某個(gè)屬性
將isDead屬性刪除,如果replacer的返回值是undefined,那么該屬性會(huì)被刪除。
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; JSON.stringify(user, function(key, value){ if(key === "isDead"){ return undefined; } return value; }); //"{"name":"andy","age":11,"addr":"shanghai"}"
功能3: 通過數(shù)組過濾某些屬性
只需要name屬性和addr屬性,其他不要。
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; JSON.stringify(user, ["name", "addr"]); //"{"name":"andy","addr":"shanghai"}"
2.2 space
space可以是數(shù)字或者是字符串, 如果是數(shù)字則表示屬性名前加上空格符號(hào)的數(shù)量,如果是字符串,則直接在屬性名前加上該字符串。
功能1: 給輸出屬性前加上n個(gè)空格
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; JSON.stringify(user, null, 4);
"{ "name": "andy", "isDead": false, "age": 11, "addr": "shanghai" }"
功能2: tab格式化輸出
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; JSON.stringify(user, null, " ");
"{ "name": "andy", "isDead": false, "age": 11, "addr": "shanghai" }"
功能3: 搞笑
JSON.stringify(user, null, "good");
"{ good"name": "andy", good"isDead": false, good"age": 11, good"addr": "shanghai" }"
2.3 深拷貝
var user = {name: "andy", isDead: false, age: 11, addr: "shanghai"}; var temp = JSON.stringify(user); var user2 = JSON.parse(temp);
3 其他
JSON.parse() 其實(shí)也是支持第二個(gè)參數(shù)的。功能類似于JSON.stringify的第二個(gè)參數(shù)的功能。
console.log("$",$.fn.jquery) //$ 3.2.116.img異步加載圖片
在開發(fā)中,我們經(jīng)常有異步加載圖片的請(qǐng)求,然后在圖片加載成功后做一些操作,一般我們通過onload方法來實(shí)現(xiàn).網(wǎng)上有兩種寫法,大家可以先看一下(注:logo.jpg是張本地圖片):
例子1:
var img = new Image(); img.src = "logo.jpg"; img.onload = function () { alert("image is loaded"); }; document.body.appendChild(img);
例子2:
var img = new Image(); img.onload = function () { alert("image is loaded"); }; img.src = "logo.jpg"; document.body.appendChild(img);
發(fā)現(xiàn)什么了沒有?上面兩個(gè)例子最大的差別就在于onload和src賦值的先后順序.那么onload和src賦值的先后順序會(huì)在實(shí)際中產(chǎn)生什么差別呢?
產(chǎn)生這個(gè)問題的原因很簡(jiǎn)單,就是因?yàn)閘ogo.jpg是本地圖片,導(dǎo)致瀏覽器加載起來非???幾乎在給img賦值src的時(shí)候,圖片就已經(jīng)加載完成,同時(shí)觸發(fā)了onload事件,代碼中為onload賦值的語句就相當(dāng)于在onload事件發(fā)生后,這時(shí)候已經(jīng)晚了.
將src寫到了onload的前面,會(huì)導(dǎo)致onload來不及賦值就被執(zhí)行了,所以正確的寫法應(yīng)該是第2個(gè)例子.既在給圖片分配地址前,先綁定好它的onload事件,這樣就不用擔(dān)心錯(cuò)過時(shí)機(jī)的問題了.
正確的例子:
var img = new Image(); // 如果文檔裝入完成后加載用window load //window.addEventListener("load" , function(){ // document.body.appendChild(img); //} , false); // 如果圖片加載完畢用 img load img.addEventListener("load", function(){ document.body.appendChild(img); } , false); img.src = "test.png";17.幾個(gè)常用的console用法
1.console.log(): 進(jìn)行標(biāo)準(zhǔn)輸出流的輸出(stdout)
console.group("mounted 掛載結(jié)束狀態(tài)===============》"); console.log("%c%s", "color:green","data : " + this.$data)
2.console.error(): 進(jìn)行標(biāo)準(zhǔn)錯(cuò)誤流的輸出用法與console.log()一樣.
3.console.dir(): 查看一個(gè)對(duì)象的內(nèi)容,并把對(duì)象信息輸出到控制臺(tái).
// a.js var person = { age: 38, name: "kobe", job: function(){ return "player" } }; console.log(person); // node a.js { age: 38, name: "kobe", job: [Function: job] }
4.console.time()與console.timeEnd() : 可以用來統(tǒng)計(jì)一段代碼的執(zhí)行時(shí)間
// a.js console.time("loop"); for(var i =0;i < 10000;i++){ ; } console.timeEnd("loop"); // node a.js loop: 0.283ms
好玩的console.log()
console.log("%c3"," text-shadow: 0 1px 0 #ccc,0 2px 0 #c9c9c9,0 3px 0 #bbb,0 4px 0 #b9b9b9,0 5px 0 #aaa,0 6px 1px rgba(0,0,0,.1),0 0 5px rgba(0,0,0,.1),0 1px 3px rgba(0,0,0,.3),0 3px 5px rgba(0,0,0,.2),0 5px 10px rgba(0,0,0,.25),0 10px 10px rgba(0,0,0,.2),0 20px 20px rgba(0,0,0,.15);font-size:6em;line-height:60px;") console.log("%c2"," text-shadow: 0 1px 0 #ccc,0 2px 0 #c9c9c9,0 3px 0 #bbb,0 4px 0 #b9b9b9,0 5px 0 #aaa,0 6px 1px rgba(0,0,0,.1),0 0 5px rgba(0,0,0,.1),0 1px 3px rgba(0,0,0,.3),0 3px 5px rgba(0,0,0,.2),0 5px 10px rgba(0,0,0,.25),0 10px 10px rgba(0,0,0,.2),0 20px 20px rgba(0,0,0,.15);font-size:4em;line-height:60px;") console.log("%c1"," text-shadow: 0 1px 0 #ccc,0 2px 0 #c9c9c9,0 3px 0 #bbb,0 4px 0 #b9b9b9,0 5px 0 #aaa,0 6px 1px rgba(0,0,0,.1),0 0 5px rgba(0,0,0,.1),0 1px 3px rgba(0,0,0,.3),0 3px 5px rgba(0,0,0,.2),0 5px 10px rgba(0,0,0,.25),0 10px 10px rgba(0,0,0,.2),0 20px 20px rgba(0,0,0,.15);font-size:2em;line-height:60px;") console.log("%c南京熱還是東京熱.", "color: #fff; background: #f40; font-size: 24px;border-radius:0 15px 15px 0;padding:10px;"); console.log("%c ","background-image:-webkit-gradient( linear, left top, right top, color-stop(0, #f22), color-stop(0.15, #f2f), color-stop(0.3, #22f), color-stop(0.45, #2ff), color-stop(0.6, #2f2),color-stop(0.75, #2f2), color-stop(0.9, #ff2), color-stop(1, #f22) );color:transparent;-webkit-background-clip: text;font-size:5em;width:1px;height:40px;padding:2px;") console.log("%c 熱 熱 熱", "color:red;font-size:30px;font-weight:bolder;padding:50px 420px;line-height:10px;background:url("http://img.zcool.cn/community/0127c0577e00620000012e7e12da0e.gif") repeat-x;background-size:contain;");18. !!強(qiáng)制轉(zhuǎn)布爾值boolean
根據(jù)當(dāng)前需要判斷的值是真值還是假值來判斷,真值返回true,假肢返回false,那么這樣的話,除了假值,剩下的也都是真值了。
假值有:0 、 “” 、 null 、 undefined 、 false 、NaN
除了這 6 個(gè)外,其它均為“真” ,包括對(duì)象、數(shù)組、正則、函數(shù)等。
注意: "0"、"null"、"false"、{}、[]也都是真值 。
那么下面我們來看看!!是如何轉(zhuǎn)布爾值的。
例如:
首先我們聲明3個(gè)變量,x為null,y為空字符串,str為字符串,下面看看他們添加了"!!"后會(huì)有什么結(jié)果。
var x=null; var y=""; var str="abcd"; console.log(!!x) // false; console.log(!!y) // false; console.log(!!str) // true; 如上所說,假值返回false,真值返回true。19. 不可靠的undefined 可靠的void 0
在JavaScript中,假設(shè)我們想判斷一個(gè)是否是 undefined,那么我們通常會(huì)這樣寫:
if(a === undefined){ dosomething..... }
因?yàn)樵趈avascript中,undefined是不可靠的
例如:
當(dāng)undefined被放在在function函數(shù)內(nèi),我們把它當(dāng)成一個(gè)局部變量,它是可以賦上值的,下面我們來試試。
function foo2(){ var undefined=1; console.log(undefined) } foo2(); // 1;
但是當(dāng)在函數(shù)內(nèi)定義一個(gè)全局變量,并不能給賦上值
var undefined; function foo2(){ undefined=1; console.log(undefined) } foo2() // undefined
那么我們?cè)囋囉胿oid 0或者 void (0)來代替:
先聲明一個(gè)變量a,賦值為undefined,接下來我們用void 0來判斷一下。
var a=undefined; //用void 0來判斷一下 if(a===void 0){ console.log("true") } // true //再用void (0)來判斷一下 if(a===void (0)){ console.log("true") } // true //最后我們打印一下這兩個(gè)的返回值 console.log(void 0,void (0)) // undefined undefined
我們現(xiàn)在可以通過void 0 運(yùn)算來獲得 undefined;那在以后需要判斷值為undefined的時(shí)候,可以直接用void 0或者void (0),而且這兩個(gè)值的直接返回值就是undefined,所以說非??煽颗?!
20.用typeof來判斷對(duì)象的潛在陷阱問:使用 typeof bar === "object" 來確定 bar 是否是對(duì)象的潛在陷阱是什么?如何避免這個(gè)陷阱?
盡管 typeof bar === "object" 是檢查 bar 是否對(duì)象的可靠方法,令人驚訝的是在JavaScript中 null 也被認(rèn)為是對(duì)象!
因此,令大多數(shù)開發(fā)人員驚訝的是,下面的代碼將輸出 true 控制臺(tái):
var bar = null; console.log(typeof bar === "object"); // logs true!
只要清楚這一點(diǎn),同時(shí)檢查 bar 是否為 null,就可以很容易地避免問題:
console.log( (bar !== null) && (typeof bar === "object") ); // logs false
要答全問題,還有其他兩件事情值得注意:
首先,上述解決方案將返回 false,當(dāng) bar 是一個(gè)函數(shù)的時(shí)候。在大多數(shù)情況下,這是期望行為,但當(dāng)你也想對(duì)函數(shù)返回 true 的話,你可以修改上面的解決方案為:
console.log( (bar !== null) && ((typeof bar === "object") || (typeof bar === "function")) );
第二,上述解決方案將返回 true,當(dāng) bar 是一個(gè)數(shù)組(例如,當(dāng) var bar = [];)的時(shí)候。
在大多數(shù)情況下,這是期望行為,因?yàn)閿?shù)組是真正的對(duì)象,但當(dāng)你也想對(duì)數(shù)組返回 false 時(shí),你可以修改上面的解決方案為:
console.log( (bar !== null)&& (typeof bar === "object") && (toString.call(bar) !== "[object Array]") );
或者,如果你使用jQuery的話:
console.log( (bar !== null)&& (typeof bar === "object") && (! $.isArray(bar)) );
或者 數(shù)組和函數(shù)返回false,但對(duì)于對(duì)象則為true:
console.log((bar !== null) && (bar.constructor === Object));
參考:
1.這些JavaScript編程黑科技...
2.圖片的異步加載與onload函數(shù)
3.原生js的常用方法整理
4.ec-do-2.0.0.js
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/88518.html
摘要:本文總結(jié)的代碼片段六持續(xù)更新前端常用代碼片段一點(diǎn)這里前端常用代碼片段二點(diǎn)這里前端常用代碼片段三點(diǎn)這里前端常用代碼片段四點(diǎn)這里前端常用代碼片段五點(diǎn)這里前端常用代碼片段六點(diǎn)這里多彩的傳入和變量本節(jié)參考文章多彩的版本號(hào)比較和和本節(jié)參考文章 本文總結(jié)的代碼片段(六)--持續(xù)更新 前端常用代碼片段(一) 點(diǎn)這里前端常用代碼片段(二) 點(diǎn)這里前端常用代碼片段(三) 點(diǎn)這里前端常用代碼片段(四) 點(diǎn)...
摘要:兩個(gè)數(shù)組內(nèi)的元素相加第二種考慮兼容一個(gè)數(shù)組插入到另一個(gè)數(shù)組通過方法將一個(gè)數(shù)組插入到另外一個(gè)數(shù)組數(shù)字排序的函數(shù)在默認(rèn)情況下使用字母數(shù)字字符串碼點(diǎn)排序。它們具有不同的引用,無法用相比較。 最后更新于2019年1月13日 前端常用代碼片段(一) 點(diǎn)這里前端常用代碼片段(二) 點(diǎn)這里前端常用代碼片段(三) 點(diǎn)這里前端常用代碼片段(四) 點(diǎn)這里前端常用代碼片段(五) 點(diǎn)這里前端常用代碼片段(六)...
摘要:盡量避免使用表達(dá)式又稱動(dòng)態(tài)屬性。使用計(jì)算數(shù)組中的重復(fù)項(xiàng)如果你想計(jì)算數(shù)組中的每個(gè)值有多少重復(fù)值,也可以快速幫到你。 前端常用代碼片段(一) 點(diǎn)這里前端常用代碼片段(二) 點(diǎn)這里前端常用代碼片段(三) 點(diǎn)這里前端常用代碼片段(四) 點(diǎn)這里前端常用代碼片段(五) 點(diǎn)這里前端常用代碼片段(六) 點(diǎn)這里 1.簡(jiǎn)述一下你對(duì)HTML語義化的理解?并寫出一段語義化的HTML? 語義化是指根據(jù)內(nèi)容的結(jié)...
最后更新于2019年1月13日 前端常用代碼片段(一) 點(diǎn)這里前端常用代碼片段(二) 點(diǎn)這里前端常用代碼片段(三) 點(diǎn)這里前端常用代碼片段(四) 點(diǎn)這里前端常用代碼片段(五) 點(diǎn)這里前端常用代碼片段(六) 點(diǎn)這里 大部分需要引入 jquery-1.9.1.min.js(兼容ie8) 1.回車觸發(fā)事件的代碼 $(function(){ $(#username).focus(...
摘要:當(dāng)運(yùn)行時(shí),如果不為,則將超時(shí)函數(shù)推送到事件隊(duì)列,并且函數(shù)退出,從而使調(diào)用堆棧清零。因此,該方法從頭到尾不經(jīng)過直接遞歸調(diào)用即可處理,因此調(diào)用堆棧保持清晰,無論迭代次數(shù)如何。 前端常用代碼片段(一) 點(diǎn)這里前端常用代碼片段(二) 點(diǎn)這里前端常用代碼片段(三) 點(diǎn)這里前端常用代碼片段(四) 點(diǎn)這里 1.tap事件點(diǎn)透問題? 問題點(diǎn)擊穿透問題:點(diǎn)擊蒙層(mask)上的關(guān)閉按鈕,蒙層消失后發(fā)現(xiàn)觸...
閱讀 3325·2021-11-12 10:36
閱讀 2483·2021-11-02 14:43
閱讀 2156·2019-08-30 14:23
閱讀 3470·2019-08-30 13:08
閱讀 928·2019-08-28 18:09
閱讀 3141·2019-08-26 12:22
閱讀 3154·2019-08-23 18:24
閱讀 2024·2019-08-23 18:17