前端面試題集錦(5)-創(chuàng)新互聯(lián)

目錄

成都創(chuàng)新互聯(lián)公司專業(yè)提供成都主機(jī)托管四川主機(jī)托管成都服務(wù)器托管四川服務(wù)器托管,支持按月付款!我們的承諾:貴族品質(zhì)、平民價(jià)格,機(jī)房位于中國電信/網(wǎng)通/移動機(jī)房,四川移動機(jī)房托管服務(wù)有保障!

1、Promsie.all() 使用過嗎, 它是怎么使用的 ?

2、for in 和 for of 循環(huán)的區(qū)別 ?

3、 什么是事件流以及事件流的傳播機(jī)制 ?

4、token 一般存放在哪里 ? 為什么不存放在 cookie 內(nèi) ?

5、 數(shù)組方法 forEach 和 map 的區(qū)別 ?

6、 ES6 中 Set 和 Map 的區(qū)別??

7、 0.1 + 0.2 為什么不等于 0.3, 在項(xiàng)目中遇到要怎么處理 ?

8、 什么是模塊化思想 ?

9、 說說怎么用js 寫無縫輪播圖

10、 閉包的使用場景 ?

10.1 防抖:

10.2 節(jié)流:

10.3 迭代器:

10.4 緩存:

10.5?getter和setter:

10.6 函數(shù)的柯里化:

10.7?循環(huán)中綁定事件或執(zhí)行異步代碼:

10.8 單例模式:


1、Promsie.all() 使用過嗎, 它是怎么使用的 ?

🌻? promise.all()用于一個異步操作需要在幾個異步操作完成后再進(jìn)行時使用。 🌻? promise.all()接受一個 promise 對象組成的數(shù)組參數(shù),返回 promise 對象。 🌻? 當(dāng)數(shù)組中所有promise 都完成了,就執(zhí)行當(dāng)前 promise 對象的 then 方法,如果數(shù)組中有一個 promise 執(zhí)行失敗了,就執(zhí)行當(dāng)前promise 對象的 catch 方法。
2、for in 和 for of 循環(huán)的區(qū)別 ?
`for in` 用于遍歷對象的鍵 ( `key` ) , `for in` 會遍歷所有自身的和原型鏈上的可枚舉屬性。如果是數(shù)組,for in 會將數(shù)組的索引 (index) 當(dāng)做對象的 key 來遍歷,其他的 object 也是一樣的。
`for of` 是 `es6` 引入的語法,用于遍歷 所有迭代器 iterator ,其中包括 `HTMLCollection` , `NodeList` , `Array` , `Map` , `Set` , `String` , `TypedArray` , `arguments` 等 對象的值 ( `item` )
3、 什么是事件流以及事件流的傳播機(jī)制 ?
事件觸發(fā)后,從開始找目標(biāo)元素,然后執(zhí)行目標(biāo)元素的事件,再到離開目標(biāo)元素的整個過程稱之為事件流。 W3C 標(biāo)準(zhǔn)瀏覽器事件流的傳播分為 3 個階段:捕獲階段、目標(biāo)階段、冒泡階段 ? ? ? ? 🌻? 捕獲階段指找目標(biāo)元素的過程,這個找的過程,是從大的document 對象到 html ,再到body,......直到目標(biāo)元素。 ? ? ? ? 🌻? 找到目標(biāo)元素后,調(diào)用執(zhí)行他綁定事件時對應(yīng)的處理函數(shù),這個過程被稱之為目標(biāo)階段。 ? ? ? ? 🌻? 當(dāng)目標(biāo)元素的事件執(zhí)行結(jié)束后,再從目標(biāo)元素,到他的父元素。。。body 、 html 再到 document 的過程,是冒泡階段。
4、token 一般存放在哪里 ? 為什么不存放在 cookie 內(nèi) ?
🌻? token一般放在本地存儲中。 token 的存在本身只關(guān)心請求的安全性,而不關(guān)心 token 本身的安全,因?yàn)? token 是服務(wù)器端生成的,可以理解為一種加密技術(shù)。但如果存在cookie 內(nèi)的話,瀏覽器的請求默認(rèn)會自動在請求頭中攜帶cookie,所以容易受到 csrf 攻擊。
5、 數(shù)組方法 forEach 和 map 的區(qū)別 ?
🌻? forEach和 map 都是循環(huán)遍歷數(shù)組中的每一項(xiàng)。 forEach() 和 map() 里面每一次執(zhí)行匿名函數(shù)都支持 3 個參數(shù):數(shù)組中的當(dāng)前項(xiàng)item, 當(dāng)前項(xiàng)的索引 index, 原始數(shù)組 input 。匿名函數(shù)中的 this 都是指 Window 。只能遍歷數(shù)組。 🌻? 他們的區(qū)別是:forEach 沒有返回值,但 map 中要有返回值,返回處理后的所有新元素組成的數(shù)組。
6、 ES6 中 Set 和 Map 的區(qū)別??
🌻? Set 是無重復(fù)值的有序列表。根據(jù) `Object.is()` 方法來判斷其中的值不相等,以保證無重復(fù)。 Set 會自動移除重復(fù)的值,因此你可以使用它來過濾數(shù)組中的重復(fù)值并返回結(jié)果。 Set 并不是數(shù)組的子類型,所以你無法隨機(jī)訪問其中的值。但你可以使用`has()` 方法來判斷某個值是否存在于 Set 中,或通過 `size` 屬性來查看其中有多少個值。 Set 類型還擁有 `forEach()` 方法,用于處理每個值 🌻? Map 是有序的鍵值對,其中的鍵允許是任何類型。與 Set 相似,通過調(diào)用 `Object.is()` 方法來判斷重復(fù)的鍵,這意味著能將數(shù)值 5 與字符串 "5" 作為兩個相對獨(dú)立的鍵。使用 `set()` 方法能將任何類型的值關(guān)聯(lián)到某個鍵上,并且該值此后能用 `get()` 方法提取出來。 Map 也擁有一個 `size` 屬性與一個 `forEach()` 方法,讓項(xiàng)目訪問更容易
7、 0.1 + 0.2 為什么不等于 0.3, 在項(xiàng)目中遇到要怎么處理 ?
🌻? 計(jì)算機(jī)內(nèi)部存儲數(shù)據(jù)使用2 進(jìn)制存儲,兩個數(shù)字進(jìn)行的數(shù)學(xué)運(yùn)算,首先是將這兩個數(shù)字以 2 進(jìn)制形式,存儲在計(jì)算機(jī)內(nèi)部,然后在計(jì)算機(jī)內(nèi)部使用兩個2 進(jìn)制數(shù)字進(jìn)行計(jì)算,最后將計(jì)算結(jié)果的 2 進(jìn)制數(shù)字轉(zhuǎn)為 10 進(jìn)制展示出來。 🌻? 由于10 進(jìn)制的小數(shù)在轉(zhuǎn) 2 進(jìn)制的時候,規(guī)則是小數(shù)部分乘以 2 ,判斷是否得到一個整數(shù),如果得到整數(shù),轉(zhuǎn)換完成;如果沒有得到整數(shù),則繼續(xù)乘以2 判斷。所以, 0.1 和 0.2 在轉(zhuǎn)換 2 進(jìn)制的時候,其實(shí)是一個無限死循環(huán),也就是一直乘以2沒有得到整數(shù)的時候,但計(jì)算機(jī)內(nèi)部對于無線死循環(huán)的數(shù)據(jù),會根據(jù)一個標(biāo)準(zhǔn)保留 52 位。也就是說,計(jì)算機(jī)內(nèi)部在存儲0.1 和 0.2 的時候,本來就不精準(zhǔn),兩個不精準(zhǔn)的小數(shù)在計(jì)算后,距離精準(zhǔn)的結(jié)果是有一定誤差的。 🌻? 項(xiàng)目中碰到這種情況,有3 種處理方法:

🍀?將小數(shù)乘以10的倍數(shù),轉(zhuǎn)為整數(shù),然后計(jì)算,計(jì)算完成后,再縮小10的倍數(shù),例如:

var result = ((0.1 * 10) + (0.2 * 10)) / 10
// result === 0.3
🍀? 使用數(shù)字的toFixed 方法,強(qiáng)制保留小數(shù)點(diǎn)后多少位,例:
var result = (0.1 + 0.2).toFixed(2)
// result === 0.30
🍀? 自定義數(shù)字運(yùn)算方法,當(dāng)需要進(jìn)行數(shù)學(xué)運(yùn)算的時候,不直接進(jìn)行,調(diào)用自定義的方法進(jìn)行,例: (加法封裝)
function add(...args){
       var num = args.find(item =>{
           if(item != 0 && !item){
              throw new Error("數(shù)學(xué)運(yùn)算要使用數(shù)字")
           }
       })
       var arr = args.map(item =>{
           var index = (item+'').indexOf('.')
           if(index >= 0){
                return (item+'').split('.')[1].length
           }
       })
       arr = arr.filter(item =>item)
       if(arr.length){
          var max = Math.max(...arr)
          var data = args.map(item =>item * Math.pow(10, max))
          var data.reduce((a, b) =>a + b) / Math.pow(10, max)
       }else{
          var data = args
          return data.reduce((a, b) =>a + b)
       }
}

// 調(diào)用使用:
var num1 = add(0.1, 0.2)
console.log(num1); // 0.3

var num2 = add(1, 2)
console.log(num2); // 3

var num3 = add(1, 2.1)
console.log(num3); // 3.1
8、 什么是模塊化思想 ?
🌻? 就是JS 中將不同功能的代碼封裝在不同的文件中 , 再互相引用時不會發(fā)生命名沖突的一種思想 , 大多數(shù)情況下 , 一個文件就是一個模塊 🌻? 模塊化的實(shí)現(xiàn),有多種方案:

🍀?CommonJS:

CommonJS 是 nodejs 中使用的模塊化規(guī)范

在 nodejs 應(yīng)用中每個文件就是一個模塊,擁有自己的作用域,文件中的變量、函數(shù)都是私有的,與其他文件相隔離。模塊導(dǎo)出: module.exports=數(shù)據(jù) ,模塊導(dǎo)入: require('模塊文件路徑')

🍀?ES6的模塊化:

模塊功能主要由兩個命令構(gòu)成: export 和 import 。 export 命令用于規(guī)定模塊的對外接口, import 命令用于輸入其他模塊提供的功能。 一個模塊就是一個獨(dú)立的文件。該文件內(nèi)部的所有變量,外部無法獲取。如果你希望外部能夠讀取 模塊內(nèi)部的某個變量,就必須使用 export 關(guān)鍵字輸出該變量。下面是一個 JS 文件,里面使用 export 命令輸出變量。

🍀?AMD (Asynchronous Module Definition):

特點(diǎn) : 提倡依賴前置,在定義模塊的時候就要聲明其依賴的模塊:導(dǎo)入模塊 require([module],callback) ; 定義模塊: define(' 模塊名稱 ', 函數(shù) ) 。

🍀?CMD (Common Module Definition):

CMD 規(guī)范是國內(nèi) SeaJS 的推廣過程中產(chǎn)生的。提倡就近依賴(按需加載),在用到某個模塊的時候 再去 require 。定義模塊: define(function (require, exports, module) {}) ,使用模塊: seajs.use() 9、 說說怎么用js 寫無縫輪播圖
🌻? 將所有需要輪播的內(nèi)容動態(tài)復(fù)制一份,放在原本的容器中,加定時器讓整個容器中的內(nèi)容滾動輪播,當(dāng)內(nèi)容輪播到left值為原本的內(nèi)容寬度時,快速將內(nèi)容切換到 left 值為 0 的狀態(tài)。
10、 閉包的使用場景 ?
🌻? 一個函數(shù)被當(dāng)作值返回時,也就相當(dāng)于返回了一個通道,這個通道可以訪問這個函數(shù)詞法作用域中的變量,即函數(shù)所需要的數(shù)據(jù)結(jié)構(gòu)保存了下來,數(shù)據(jù)結(jié)構(gòu)中的值在外層函數(shù)執(zhí)行時創(chuàng)建,外層函數(shù)執(zhí)行完畢時理因銷毀,但由于內(nèi)部函數(shù)作為值返回出去,這些值得以保存下來。而且無法直接訪問,必須通過返回的函數(shù)。這也就是私有性。 🌻? 本來執(zhí)行過程和詞法作用域是封閉的,這種返回的函數(shù)就好比是一個蟲洞,開了掛。 🌻? 閉包的形成很簡單,在執(zhí)行過程完畢后,返回函數(shù),或者將函數(shù)得以保留下來,即形成閉包。
10.1 防抖:
function debounce(fn, interval) {
    let timer = null; // 定時器
    return function() {
        // 清除上一次的定時器
        clearTimeout(timer);
        // 拿到當(dāng)前的函數(shù)作用域
        let _this = this;
        // 拿到當(dāng)前函數(shù)的參數(shù)數(shù)組
        let args = Array.prototype.slice.call(arguments, 0);
        // 開啟倒計(jì)時定時器
        timer = setTimeout(function() {
           // 通過apply傳遞當(dāng)前函數(shù)this,以及參數(shù)
           fn.apply(_this, args);
           // 默認(rèn)300ms執(zhí)行
        }, interval || 300)
    }
}
10.2 節(jié)流:
function throttle(fn, interval) {
    let timer = null; // 定時器
    let firstTime = true; // 判斷是否是第一次執(zhí)行
    // 利用閉包
    return function() {
       // 拿到函數(shù)的參數(shù)數(shù)組
       let args = Array.prototype.slice.call(arguments, 0);
       // 拿到當(dāng)前的函數(shù)作用域
       let _this = this;
       // 如果是第一次執(zhí)行的話,需要立即執(zhí)行該函數(shù)
       if(firstTime) {
          // 通過apply,綁定當(dāng)前函數(shù)的作用域以及傳遞參數(shù)
          fn.apply(_this, args);
          // 修改標(biāo)識為null,釋放內(nèi)存
          firstTime = null;
       }
       // 如果當(dāng)前有正在等待執(zhí)行的函數(shù)則直接返回
       if(timer) return;
       // 開啟一個倒計(jì)時定時器
       timer = setTimeout(function() {
          // 通過apply,綁定當(dāng)前函數(shù)的作用域以及傳遞參數(shù)
          fn.apply(_this, args);
          // 清除之前的定時器
          timer = null;
          // 默認(rèn)300ms執(zhí)行一次
       }, interval || 300)
   }
}
10.3 迭代器:
var arr =['aa','bb','cc'];
function incre(arr){
     var i=0;
     return function(){
        //這個函數(shù)每次被執(zhí)行都返回?cái)?shù)組arr中 i下標(biāo)對應(yīng)的元素
        return arr[i++] || '數(shù)組值已經(jīng)遍歷完';
     }
}
var next = incre(arr);
console.log(next());//aa
console.log(next());//bb
console.log(next());//cc
console.log(next());//數(shù)組值已經(jīng)遍歷完
10.4 緩存:
var fn=(function(){
        var cache={};//緩存對象
        var calc=function(arr){//計(jì)算函數(shù)
            var sum=0;
            //求和
            for(var i=0;i
10.5?getter和setter:
function fn(){
       var name='hello'
       setName=function(n){
          name = n;
       }
       getName=function(){
           return name;
       }

       //將setName,getName作為對象的屬性返回
       return {
           setName:setName,
           getName:getName
       }
}
var fn1 = fn();//返回對象,屬性setName和getName是兩個函數(shù)
console.log(fn1.getName());//getter
fn1.setName('world');//setter修改閉包里面的name
console.log(fn1.getName());//getter
10.6 函數(shù)的柯里化:
function curryingCheck(reg) {
     return function(txt) {
        return reg.test(txt)
     }
}

var hasNumber = curryingCheck(/\d+/g)
var hasLetter = curryingCheck(/[a-z]+/g)

hasNumber('test1') // true
hasNumber('testtest') // false
hasLetter('21212') // false
10.7?循環(huán)中綁定事件或執(zhí)行異步代碼:
var p1 = "ss";
var p2 = "jj";
function testSetTime(para1,para2){
    return (function(){
         console.log(para1 + "-" + para2);
    })
}
var test = testSetTime(p1, p2);
setTimeout(test, 1000);
setTimeout(function(){
      console.log(p1 + "-" + p2)
},1000)
10.8 單例模式:
var Singleton = (function () {
    var instance;

    function createInstance() {
         return new Object("I am the instance");
    }

    return {
        getInstance: function () {
            if (!instance) {
                instance = createInstance();
            }
            return instance;
        }
    };
})();

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁題目:前端面試題集錦(5)-創(chuàng)新互聯(lián)
當(dāng)前URL:http://muchs.cn/article20/dpgcco.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站網(wǎng)頁設(shè)計(jì)公司、小程序開發(fā)、定制網(wǎng)站、用戶體驗(yàn)建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)