午夜精品人妻久久久-成年美女很黄的网站-在线看片免费人成视久网app-国产精品美女无遮挡一区二区-91精品国产综合久久久久-国产的免费视频又猛又爽又刺激-在线看片免费人成视久网app-久久香蕉国产精品视频-av一区二区三区高清

JavaScript高級(jí)技巧

var foo = (function foo(){if(a != b){return function(){console.log('aaa')}}else{return function(){console.log('bbb')}}})();
這里創(chuàng)建一個(gè)匿名,自執(zhí)行的函數(shù),用來確定應(yīng)該使用哪一個(gè)函數(shù)來實(shí)現(xiàn) 。
惰性函數(shù)的優(yōu)點(diǎn)就是只在第一次執(zhí)行分支時(shí)犧牲一點(diǎn)點(diǎn)性能
函數(shù)綁定
請(qǐng)使用fun.bind([, arg1[, arg2[, …]]])
當(dāng)綁定函數(shù)被調(diào)用時(shí) , 該參數(shù)會(huì)作為原函數(shù)運(yùn)行時(shí)的 this 指向 。當(dāng)使用new 操作符調(diào)用綁定函數(shù)時(shí),該參數(shù)無效
arg1,arg2,…
當(dāng)綁定函數(shù)被調(diào)用時(shí),這些參數(shù)將置于實(shí)參之前傳遞給被綁定的方法
返回
由指定的this值和初始化參數(shù)改造的原函數(shù)拷貝
一個(gè)例子
let person = {name: 'addone',click: function(e){console.log(this.name)}}let btn = document.getElementById('btn');EventUtil.addHandle(btn, 'click', person.click);
這里創(chuàng)建了一個(gè)對(duì)象js 判斷節(jié)點(diǎn)是否存在,然后將.click方法分配給DOM按鈕的事件處理程序 , 當(dāng)你點(diǎn)擊按按鈕時(shí),會(huì)打印出,原因是執(zhí)行時(shí)this指向了DOM按鈕而不是
解決方案: 將this強(qiáng)行指向
EventUtil.addHandle(btn, 'click', person.click.bind(person));
函數(shù)柯里化
函數(shù)柯里化是把接受多個(gè)參數(shù)的函數(shù)轉(zhuǎn)變成接受單一參數(shù)的函數(shù)
function add(num1, num2){return num1 + num2;}function curryAdd(num2){return add(1, num2);}add(2, 3) // 5curryAdd(2) // 3
【JavaScript高級(jí)技巧】這個(gè)例子用來方便理解柯里化的概念
下面是創(chuàng)建函數(shù)柯里化的通用方式
function curry(fn){var args = Array.prototype.slice.call(arguments, 1);return function(){let innerArgs = Array.prototype.slice.call(arguments);let finalArgs = args.concat(innerArgs);return fn.apply(null, finalArgs);}}
第一個(gè)參數(shù)是要進(jìn)行柯里化的函數(shù),其他參數(shù)是要傳入的值 。這里使用Array..slice.call(, 1)來獲取第一個(gè)參數(shù)后的所有參數(shù)(外部) 。在返回的函數(shù)中js 判斷節(jié)點(diǎn)是否存在,同樣調(diào)用Array..slice.call()讓來存放所有的參數(shù)(內(nèi)部),然后用將內(nèi)部外部參數(shù)組合,用apply傳遞給函數(shù)
function add(num1, num2){return num1 + num2;}let curryAdd1 = curry(add, 1);curryAdd1(2); // 3let curryAdd2 = curry(add, 1, 2);curryAdd2(); // 3
防篡改對(duì)象
中任何對(duì)象都可以被同一環(huán)境中運(yùn)行的代碼修改 , 所以開發(fā)人員有時(shí)候需要定義防篡改對(duì)象(-proof ) 來保護(hù)自己
不可擴(kuò)展對(duì)象
默認(rèn)情況下所有對(duì)象都是可以擴(kuò)展的(添加屬性和方法)
let person = { name: 'addone' };person.age = 20;
第二行為對(duì)象擴(kuò)展了age屬性 , 當(dāng)然你可以阻止這一行為,使用.()
let person = { name: 'addone' };Object.preventExtensions(person);person.age = 20;person.age // undefined
你還可以用.()來判斷對(duì)象是不是可擴(kuò)展的
let person = { name: 'addone' };Object.isExtensible(person); // trueObject.preventExtensions(person);Object.isExtensible(person); // false
請(qǐng)記住這是不可擴(kuò)展!!,即不能添加屬性或方法
密封的對(duì)象
密封對(duì)象不可擴(kuò)展,且不能刪除屬性和方法
let person = { name: 'addone' };Object.seal(person);person.age = 20;delete person.name;person.age // undefinedperson.name // addone
相對(duì)的也有.()來判斷是否密封
let person = { name: 'addone' };Object.isExtensible(person); // trueObject.isSealed(person); // falseObject.seal(person);Object.isExtensible(person); // falseObject.isSealed(person); // true
凍結(jié)的對(duì)象
這是最嚴(yán)格的防篡改級(jí)別 , 凍結(jié)的對(duì)象即不可擴(kuò)展,又密封,且不能修改
let person = { name: 'addone' };Object.freeze(person);person.age = 20;delete person.name;person.name = 'addtwo'person.age // undefinedperson.name // addone
同樣也有.來檢測(cè)
let person = { name: 'addone' };Object.isExtensible(person); // trueObject.isSealed(person); // falseObject.isFrozen(person); // falseObject.freeze(person);Object.isExtensible(person); // falseObject.isSealed(person); // trueObject.isFrozen(person); // true
以上三種方法在嚴(yán)格模式下進(jìn)行錯(cuò)誤操作均會(huì)導(dǎo)致拋出錯(cuò)誤
高級(jí)定時(shí)器
閱讀前提
大概理解的基本執(zhí)行機(jī)制和js事件機(jī)制
重復(fù)的定時(shí)器
當(dāng)你使用重復(fù)定義多個(gè)定時(shí)器的時(shí)候,可能會(huì)出現(xiàn)某個(gè)定時(shí)器代碼在代碼再次被添加到執(zhí)行隊(duì)列之前還沒有完成執(zhí)行,導(dǎo)致定時(shí)器代碼連續(xù)執(zhí)行多次 。
機(jī)智引擎解決了這個(gè)問題 , 使用()的時(shí)候,僅當(dāng)沒有該定時(shí)器的其他代碼實(shí)例時(shí),才會(huì)將定時(shí)器代碼添加到隊(duì)列中 。但這還會(huì)導(dǎo)致一些問題:
為了避免這個(gè)兩個(gè)問題,你可以使用鏈?zhǔn)?)調(diào)用
setTimeout(function(){TODO();setTimeout(arguments.callee, interval);}, interval)
.獲取了當(dāng)前執(zhí)行函數(shù)的引用,然后為其設(shè)置另外一個(gè)定時(shí)器,這樣就確保在下一次定時(shí)器代碼執(zhí)行前,必須等待指定的間隔 。
瀏覽器對(duì)長(zhǎng)時(shí)間運(yùn)行的腳本進(jìn)行了制約,如果代碼運(yùn)行超過特定的時(shí)間或者特定語句數(shù)量就不會(huì)繼續(xù)執(zhí)行 。
如果你發(fā)現(xiàn)某個(gè)循環(huán)占用了大量的時(shí)間 , 那么對(duì)于下面這兩個(gè)問題
如果你的兩個(gè)答案都是”否”,那么你可以使用一種叫做數(shù)組分塊(array ) 的技術(shù) 。基本思路是為要處理的項(xiàng)目創(chuàng)建一個(gè)隊(duì)列,然后使用定時(shí)器取出下一個(gè)要出處理的項(xiàng)目進(jìn)行處理,然后再設(shè)置另一個(gè)定時(shí)器 。
function chunk(array, process, context){setTimeout(function(){// 取出下一個(gè)項(xiàng)目進(jìn)行處理let item = array.shift();process.call(item);if(array.length > 0){setTimeout(arguments.callee, 100);}}, 100)}
這里接受三個(gè)參數(shù) , 要處理的數(shù)組,處理的函數(shù),運(yùn)行該函數(shù)的環(huán)境(可選) , 這里設(shè)置間隔100ms是個(gè)效果不錯(cuò)的選擇
如果你一個(gè)函數(shù)需要50ms以上時(shí)間完成,那么最好看看能否將任務(wù)分割成一系列可以使用定時(shí)器的小任務(wù)
函數(shù)節(jié)流()
節(jié)流的目的是防止某些操作執(zhí)行的太快 。比如在調(diào)整瀏覽器大小的時(shí)候會(huì)觸發(fā)事件,如果在其內(nèi)部進(jìn)行一些DOM操作,這種高頻率的更愛可能會(huì)使瀏覽器崩潰 。為了避免這種情況,可以采取函數(shù)節(jié)流的方式 。
function throttle(method, context){clearTimeout(method.tId);method.tId = setTimeout(function(){method.call(context);}, 100)}
這里接受兩個(gè)參數(shù),要執(zhí)行的函數(shù),執(zhí)行的環(huán)境 。執(zhí)行時(shí)先清除之前的定時(shí)器,然后將當(dāng)前定時(shí)器賦值給方法的tId,之后調(diào)用call來確定函數(shù)的執(zhí)行環(huán)境 。
一個(gè)應(yīng)用的例子
function resizeDiv(){let div = document.getElementById('div');div.style.height = div.offsetWidth + "px";}window.onresize = function(){throttle(resizeDiv);}
給個(gè) , 轉(zhuǎn)發(fā)謝謝
Java創(chuàng)建對(duì)象方式
深入理解Java內(nèi)存模型
Java線上% 問題排查
Java加密與解密之對(duì)稱加密DES
Java分布式事務(wù)實(shí)現(xiàn)
你不得不知道的七個(gè)小技巧
中使用Cache及的使用
jpa 實(shí)現(xiàn)讀寫分離
MVC 異步請(qǐng)求方式
本文到此結(jié)束,希望對(duì)大家有所幫助 。