摘要:靜態(tài)作用域與動(dòng)態(tài)作用域靜態(tài)作用域函數(shù)的作用域基于函數(shù)創(chuàng)建的位置。采用的是詞法作用域,也稱為靜態(tài)作用域??梢越俪终麄€(gè)對(duì)象,并返回一個(gè)新的對(duì)象。防誤觸延緩執(zhí)行立即執(zhí)行節(jié)流所謂節(jié)流,就是指連續(xù)觸發(fā)事件但是在秒中只執(zhí)行一次函數(shù)。
在這里記錄著每天自己遇到的一道印象深刻的前端問題,以及一道生活中隨處可見的小問題。
強(qiáng)迫自己形成積累的習(xí)慣,鞭撻自己不斷前行,共同學(xué)習(xí)。
Github 地址
2019/04/15 - 2019/04/21 1. 寫一個(gè)亂序函數(shù) ?遍歷數(shù)組元素,然后將當(dāng)前元素與以后隨機(jī)位置的元素進(jìn)行交換。
function shuffle(a) { for (let i = a.length; i; i--) { let j = Math.floor(Math.random() * i); // es6語(yǔ)法 [a[i - 1], a[j]] = [a[j], a[i - 1]]; } return a; }2. 什么是惰性函數(shù)?
惰性函數(shù)就是返回一個(gè)重寫函數(shù)。For example:
var foo = function() { var t = new Date(); foo = function() { return t; }; return foo(); }; foo();3. 靜態(tài)作用域與動(dòng)態(tài)作用域 ?
靜態(tài)作用域 —— 函數(shù)的作用域基于函數(shù)創(chuàng)建的位置。
動(dòng)態(tài)作用域 —— 函數(shù)的作用域基于函數(shù)的使用位置。
var value = 1; function foo() { console.log(value); } function bar() { var value = 2; foo(); } bar(); // 輸出 1 。JavaScript 采用的是詞法作用域,也稱為靜態(tài)作用域。相同的,動(dòng)態(tài)作用域此代碼應(yīng)該輸出 24. 手寫一個(gè) function call()函數(shù) ?
Function.prototype.call2 = function(context, ...args) { // 因?yàn)閭鬟M(jìn)來的 context 有可能是 null context = context || window; // Function.prototype this 為當(dāng)前運(yùn)行的函數(shù) // 讓 fn 的上下文為 context context.fn = this; const result = context.fn(...args); delete context.fn; return result; };5. Vue 組件中的 name 屬性的作用 ?
組件在全局用 Vue.component() 注冊(cè)時(shí),全局 ID 自動(dòng)作為組件的 name。
指定 name 選項(xiàng)的另一個(gè)好處是便于調(diào)試。有名字的組件有更友好的警告信息。另外,當(dāng)在有 vue-devtools,未命名組件將顯示成
hash 路由
hash 路由一個(gè)明顯的標(biāo)志是帶有#,我們主要是通過監(jiān)聽 url 中的 hash 變化來進(jìn)行路由跳轉(zhuǎn)。(window.addEventListener("hashchange", this.refresh, false);)
hash 的優(yōu)勢(shì)就是兼容性更好,在老版 IE 中都有運(yùn)行,問題在于 url 中一直存在#不夠美觀,而且 hash 路由更像是 Hack 而非標(biāo)準(zhǔn),相信隨著發(fā)展更加標(biāo)準(zhǔn)化的 History API 會(huì)逐步蠶食掉 hash 路由的市場(chǎng)。
history 路由
history 路由使用 History API 來實(shí)現(xiàn),具體有:
window.history.back(); // 后退 window.history.forward(); // 前進(jìn) window.history.go(-3); // 后退三個(gè)頁(yè)面
history.pushState用于在瀏覽歷史中添加歷史記錄, history.replaceState方法的參數(shù)與pushState方法一模一樣,區(qū)別是它修改瀏覽歷史中當(dāng)前紀(jì)錄,而非添加記錄,同樣不觸發(fā)跳轉(zhuǎn)。
7. Vue 的響應(yīng)式原理中 Object.defineProperty 有什么缺陷?為什么在 Vue3.0 采用了 Proxy,拋棄了 Object.defineProperty?Object.defineProperty 無法監(jiān)控到數(shù)組下標(biāo)的變化,導(dǎo)致通過數(shù)組下標(biāo)添加元素,不能實(shí)時(shí)響應(yīng);
Object.defineProperty 只能劫持對(duì)象的屬性,從而需要對(duì)每個(gè)對(duì)象,每個(gè)屬性進(jìn)行遍歷,如果,屬性值是對(duì)象,還需要深度遍歷。Proxy 可以劫持整個(gè)對(duì)象,并返回一個(gè)新的對(duì)象。
Proxy 不僅可以代理對(duì)象,還可以代理數(shù)組。還可以代理動(dòng)態(tài)增加的屬性。
2019/04/08 - 2019/04/14 4. 寫一個(gè)“終極類型”判斷函數(shù)?function type(obj) { var toString = Object.prototype.toString; var toType = {}; var typeArr = [ "Undefined", "Null", "Boolean", "Number", "String", "Object", "Array", "Function", "Date", "RegExp", "Error", "Arguments" ]; // 這里利用了object 對(duì)象toString() 后 值為 "[object Array]" 等情況進(jìn)行判斷 typeArr.map(function(item, index) { toType["[object " + item + "]"] = item.toLowerCase(); }); return typeof obj !== "object" ? typeof obj : toType[toString.call(obj)]; }2. 寫一個(gè)函數(shù),判斷各種類型的不同變量是否相等,即“終極等于”函數(shù)?
const equals = (a, b) => { if (a === b) return true; // 時(shí)間的判斷 if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime(); // 非 object 類型的判斷 if (!a || !b || (typeof a !== "object" && typeof b !== "object")) return a === b; if (a.prototype !== b.prototype) return false; if (Array.isArray(a) && Array.isArray(b)) a.sort(), b.sort(); let keys = Object.keys(a); if (keys.length !== Object.keys(b).length) return false; return keys.every(k => equals(a[k], b[k])); };3. mouseover 和 mouseenter 的區(qū)別 ?
mouseover:當(dāng)鼠標(biāo)移入元素或其子元素都會(huì)觸發(fā)事件,所以有一個(gè)重復(fù)觸發(fā),冒泡的過程。對(duì)應(yīng)的移除事件是 mouseout
mouseenter:當(dāng)鼠標(biāo)移除元素本身(不包含元素的子元素)會(huì)觸發(fā)事件,也就是不會(huì)冒泡,對(duì)應(yīng)的移除事件是 mouseleave
4. 一句話形容閉包?閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù),或者子函數(shù)在外調(diào)用,子函數(shù)所在的父函數(shù)的作用域不會(huì)被釋放。
一個(gè)閉包小栗子:
function f1(){ n = 999; function f2(){ console.log(n); } return f2; } var result = f1(); //返回的是f2函數(shù) result(); //999,讀取內(nèi)部變量5. js 的 new 操作符做了哪些事情 ?
new 操作符新建了一個(gè)空對(duì)象,這個(gè)對(duì)象原型指向構(gòu)造函數(shù)的 prototype,執(zhí)行構(gòu)造函數(shù)后返回這個(gè)對(duì)象。
6. 實(shí)現(xiàn)一個(gè)深拷貝 ?//所謂深度克隆,就是當(dāng)對(duì)象的某個(gè)屬性值為object或array的時(shí)候,要獲得一份copy,而不是直接拿到引用值 function deepClone1(origin, target) { //origin是被克隆對(duì)象,target是我們獲得copy var target = target || {}; //定義target for (var key in origin) { //遍歷原對(duì)象 if (origin.hasOwnProperty(key)) { if (Array.isArray(origin[key])) { //如果是數(shù)組 target[key] = []; deepClone1(origin[key], target[key]); //遞歸 } else if (typeof origin[key] === "object" && origin[key] !== null) { target[key] = {}; deepClone1(origin[key], target[key]); //遞歸 } else { target[key] = origin[key]; } } } return target; } // 第二個(gè)function function deepClone2(data) { if (!data || !(data instanceof Object) || typeof data === "function") { return data; } var constructor = data.constructor; var result = new constructor(); for (var key in data) { if (data.hasOwnProperty(key)) { result[key] = deepClone2(data[key]); } } return result; } // 第三個(gè)fuction function deepClone3(origin, target) { var target = target || {}, toStr = Object.prototype.toString; for (var prop in origin) { if (origin.hasOwnProperty(prop)) { //不能把原型鏈上的一起拷貝了 //判斷是元素類型還是引用類型 if (typeof origin[prop] == "object" && typeof origin[prop] !== "null") { target[prop] = toStr.call(prop) == "[object Array]" ? [] : {}; arguments.callee(origin[prop], target[prop]); //遞歸調(diào)用 } else { target[prop] = origin[prop]; //原始類型直接復(fù)制 } } } return target; } // 第四個(gè)function function deepClone4(obj) { //判斷是否是簡(jiǎn)單數(shù)據(jù)類型, if (typeof obj == "object") { //復(fù)雜數(shù)據(jù)類型 var result = obj.constructor == Array ? [] : {}; for (let i in obj) { result[i] = typeof obj[i] == "object" && obj[i] !== null ? deepClone4(obj[i]) : obj[i]; } } else { //簡(jiǎn)單數(shù)據(jù)類型 直接 == 賦值 var result = obj; } return result; }
推薦使用 deepClone2()
7. 函數(shù)的防抖與節(jié)流 ?防抖
所謂防抖,就是指觸發(fā)事件后在 n 秒內(nèi)函數(shù)只能執(zhí)行一次,如果在 n 秒內(nèi)又觸發(fā)了事件,則會(huì)重新計(jì)算函數(shù)執(zhí)行時(shí)間。(防誤觸)
// 延緩執(zhí)行 function debounce(func, wait) { var timeout; return function() { var context = this; var args = arguments; console.log(args); console.log(func); if (timeout) clearTimeout(timeout); timeout = setTimeout(function() { func.apply(context, args); }, wait); }; } // 立即執(zhí)行 function debounce(func, wait) { var timeout; return function() { var context = this; var args = arguments; if (timeout) clearTimeout(timeout); var callNow = !timeout; timeout = setTimeout(function() { timeout = null; }, wait); if (callNow) func.apply(context, args); }; }
節(jié)流
所謂節(jié)流,就是指連續(xù)觸發(fā)事件但是在 n 秒中只執(zhí)行一次函數(shù)。(限制流量)
// 時(shí)間戳 function throttle(func, wait) { var previous = 0; return function() { var now = Date.now(); var context = this; var args = arguments; if (now - previous > wait) { func.apply(context, args); previous = now; } }; } // 定時(shí)器 function throttle(func, wait) { var timeout; return function() { var context = this; var args = arguments; if (!timeout) { timeout = setTimeout(function() { timeout = null; func.apply(context, args); }, wait); } }; }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/114513.html
摘要:靜態(tài)作用域與動(dòng)態(tài)作用域靜態(tài)作用域函數(shù)的作用域基于函數(shù)創(chuàng)建的位置。采用的是詞法作用域,也稱為靜態(tài)作用域。可以劫持整個(gè)對(duì)象,并返回一個(gè)新的對(duì)象。防誤觸延緩執(zhí)行立即執(zhí)行節(jié)流所謂節(jié)流,就是指連續(xù)觸發(fā)事件但是在秒中只執(zhí)行一次函數(shù)。 在這里記錄著每天自己遇到的一道印象深刻的前端問題,以及一道生活中隨處可見的小問題。 強(qiáng)迫自己形成積累的習(xí)慣,鞭撻自己不斷前行,共同學(xué)習(xí)。 Github 地址 2019...
摘要:?jiǎn)柷岸说木彺嬗心男┒歼m用什么場(chǎng)景區(qū)別是什么參考回答前端緩存分為兩部分緩存瀏覽器緩存緩存強(qiáng)緩存強(qiáng)緩存主要是采用響應(yīng)頭中的和兩個(gè)字段進(jìn)行控制的值理解指定設(shè)置緩存最大的有效時(shí)間單位為指定響應(yīng)會(huì)被緩存,并且在多用戶間共享響應(yīng)只作為私有的緩存, 20190116問: 前端的緩存有哪些?都適用什么場(chǎng)景?區(qū)別是什么? 參考回答 前端緩存分為兩部分: http 緩存 瀏覽器緩存 http 緩存 強(qiáng)...
摘要:?jiǎn)柷岸说木彺嬗心男┒歼m用什么場(chǎng)景區(qū)別是什么參考回答前端緩存分為兩部分緩存瀏覽器緩存緩存強(qiáng)緩存強(qiáng)緩存主要是采用響應(yīng)頭中的和兩個(gè)字段進(jìn)行控制的值理解指定設(shè)置緩存最大的有效時(shí)間單位為指定響應(yīng)會(huì)被緩存,并且在多用戶間共享響應(yīng)只作為私有的緩存, 20190116問: 前端的緩存有哪些?都適用什么場(chǎng)景?區(qū)別是什么? 參考回答 前端緩存分為兩部分: http 緩存 瀏覽器緩存 http 緩存 強(qiáng)...
20190124問: 如何理解es6中的Proxy? 試題解析:對(duì)proxy的理解,可能會(huì)延伸到vue的雙向綁定 Proxy(代理) 定義 可以理解為為目標(biāo)對(duì)象架設(shè)一層攔截,外界對(duì)該對(duì)象的訪問,都必須通過這層攔截 簡(jiǎn)單示例: const obj = new Proxy({}, { get: (target, key, receiver) => { return JS ...
閱讀 2997·2023-04-25 21:23
閱讀 3037·2021-09-22 15:24
閱讀 866·2019-08-30 12:55
閱讀 2100·2019-08-29 18:42
閱讀 2611·2019-08-29 16:27
閱讀 953·2019-08-26 17:40
閱讀 2185·2019-08-26 13:29
閱讀 2612·2019-08-26 11:45