(十三)真题模拟【告诉你答案是什么】
生活随笔
收集整理的這篇文章主要介紹了
(十三)真题模拟【告诉你答案是什么】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
真題模擬
- 面試真題
- 講解前提示
- 何為變量提升
- var和let const的區別
- typeof返回哪些類型
- 列舉強制類型轉換和隱式類型轉換
- 手寫深度比較 isEqual
- 手寫深度比較,模擬lodash isEqual
- split() 和join()的區別
- 數組pop push unshift shift分別做什么
- 數組的API,有哪些是純函數
- 你是否真的會用數組map
- 數組slice和splice的區別
- [10,20,30].map(parseInt)返回結果是什么
- ajax請求get和post的區別
- 再學閉包
- 函數call和apply的區別
- 事件代理(委托)是什么
- 閉包是什么?有什么特效?有什么負面影響
- 回顧DOM操作和優化
- 如何阻止時間冒泡和默認行為
- 查找、添加、刪除、移動DOM節點的方法
- 如何減少DOM操作
- jsonp本質是ajax嗎
- 解釋jsonp的原理,為何它不是真正的ajax
- document load和ready的區別
- 兩等和三等的不同
- 是否用過Object.create()
- 函數聲明和函數表達式的區別
- new Object() 和 Object.create()的區別
- 關于this的場景題
- 常見的正則表達式
- 關于作用域和自由變量的場景題 - 1
- 判斷字符串以字母開頭,后面字母數字下劃線,長度6-30
- 關于作用域和自由變量的場景題 - 2
- 如何獲取最大值
- 手寫字符串trim方法,保證瀏覽器兼容性
- 如何獲取多個數字中的最大值
- 如何用JS實現繼承
- 解析url參數
- 如何捕獲JS程序中的異常
- 什么是JSON
- 獲取當前頁面url參數
- 數組去重有幾種方式
- 將url參數解析為JS對象
- 手寫數組flatern,考慮多層級
- 數組去重
- 是否用過requestAnimationFrame
- 手寫深拷貝
- 介紹一下RAF requestAnimationFrame
- 前端性能如何優化?一般從哪幾個方面考慮?
面試真題
- 搜集網上的高頻JS初級面試題
- 驗證和復習之前學過的知識
- 補充其他技能,如正則表達式、數組API
講解前提示
- 題目沒有按照知識點或者難度排序,即混排
- 只篩選了初級面試題,即本課程知識體系之內的
- 如您遇到了其他未講到的面試題,歡迎提供,讓課程更完善
何為變量提升
var和let const的區別
- var是ES5語法,let const是ES6語法,var有變量提升
- var和let是變量,可修改;const是常量,不可修改
- let const有塊級作用域,var沒有
typeof返回哪些類型
- undefined string number boolean symbol
- object(注意,typeof null === ‘object’)
- function
列舉強制類型轉換和隱式類型轉換
- 強制:parseInt parseFloat toString等
- 隱式:if、邏輯運算、==、+拼接字符串
手寫深度比較 isEqual
手寫深度比較,模擬lodash isEqual
// 判斷是否是對象或數組 function isObject(obj) {return typeof obj === 'object' && obj !== null } // 全相等(深度) function isEqual(obj1, obj2) {if (!isObject(obj1) || !isObject(obj2)) {// 值類型(注意,參與 equal 的一般不會是函數)return obj1 === obj2}if (obj1 === obj2) {return true}// 兩個都是對象或數組,而且不相等// 1. 先取出 obj1 和 obj2 的 keys ,比較個數const obj1Keys = Object.keys(obj1)const obj2Keys = Object.keys(obj2)if (obj1Keys.length !== obj2Keys.length) {return false}// 2. 以 obj1 為基準,和 obj2 一次遞歸比較for (let key in obj1) {// 比較當前 key 的 val —— 遞歸!!!const res = isEqual(obj1[key], obj2[key])if (!res) {return false}}// 3. 全相等return true }// 測試 const obj1 = {a: 100,b: {x: 100,y: 200} } const obj2 = {a: 100,b: {x: 100,y: 200} } // console.log( obj1 === obj2 ) console.log( isEqual(obj1, obj2) )const arr1 = [1, 2, 3] const arr2 = [1, 2, 3, 4]split() 和join()的區別
'1-2-3'.split('-') //[1,2,3] [1,2,3].join('-')數組pop push unshift shift分別做什么
// const arr = [10, 20, 30, 40]// // pop // const popRes = arr.pop() // console.log(popRes, arr) 40 [10, 20, 30]// // shift // const shiftRes = arr.shift() // console.log(shiftRes, arr) 10 [20, 30, 40]// // push // const pushRes = arr.push(50) // 返回 length // console.log(pushRes, arr) 5 [10, 20, 30, 40, 50]// // unshift // const unshiftRes = arr.unshift(5) // 返回 length // console.log(unshiftRes, arr) 5 [5, 10, 20, 30, 40]數組的API,有哪些是純函數
// // 純函數:1. 不改變源數組(沒有副作用);2. 返回一個數組 // const arr = [10, 20, 30, 40]// // concat // const arr1 = arr.concat([50, 60, 70]) // // map // const arr2 = arr.map(num => num * 10) // // filter // const arr3 = arr.filter(num => num > 25) // // slice // const arr4 = arr.slice()// // 非純函數 // // push pop shift unshift // // forEach // // some every // // reduce你是否真的會用數組map
數組slice和splice的區別
- 功能區別(slice - 切片,splice - 剪接)
- 參數和返回值
- 是否純函數
[10,20,30].map(parseInt)返回結果是什么
- map的參數和返回值
- parseInt參數和返回值
ajax請求get和post的區別
- get一般用于查詢操作,post一般用戶提交操作
- get參數拼接在url上,post放在請求體內(數據體積可更大)
- 安全性:post易于防止CSRF
再學閉包
函數call和apply的區別
fn.call(this,p1,p2,p3) fn.apply(this,arguments)事件代理(委托)是什么
閉包是什么?有什么特效?有什么負面影響
- 回顧作用域和自由變量
- 回顧閉包應用場景:作為參數被傳入,作為返回值被返回
- 回顧:自由變量的查找,要在函數定義的地方(而非執行的地方)
- 影響:變量會常駐內存,得不到釋放,閉包不要亂用
回顧DOM操作和優化
如何阻止時間冒泡和默認行為
event.stopProppagation() event.preventDefault()查找、添加、刪除、移動DOM節點的方法
基礎中的基礎,不再演示,可回顧之前的章節
如何減少DOM操作
- 緩存DOM查詢結果
- 多次DOM操作,合并到一次插入
jsonp本質是ajax嗎
解釋jsonp的原理,為何它不是真正的ajax
- 瀏覽器的同源策略(服務端沒有同源策略)和跨域
- 哪些html標簽能繞過跨域
- jsonp的原理
document load和ready的區別
兩等和三等的不同
- 兩等會嘗試類型轉換
- 三等嚴格相等
- 哪些場景才用兩等?
是否用過Object.create()
函數聲明和函數表達式的區別
- 函數聲明function fn(){…}
- 函數表達式 const fn = function(){…}
- 函數聲明會在代碼執行前預加載,而函數表達式不會
new Object() 和 Object.create()的區別
- {}等同于new Object(),原型Object.prototype
- Object.create(null)沒有原型
- Object.create({…})可指定原型
關于this的場景題
const User = {count:1,getCount:function(){return this.count;} } console.log(User.getCount()) //1 const func = User.getCount console.log(func()) //undefined,this指window常見的正則表達式
關于作用域和自由變量的場景題 - 1
let i; for(i=1;i<=3;i++){setTimeout(function(){console.log(i)},0) }判斷字符串以字母開頭,后面字母數字下劃線,長度6-30
const reg = /^[a-zA-Z]\w{5, 29}$/ 學習正則表達式的規則 手寫常見的正則表達式 // 郵政編碼 /\d{6}/// 小寫英文字母 /^[a-z]+$/// 英文字母 /^[a-zA-Z]+$/// 日期格式 2019.12.1 /^\d{4}-\d{1,2}-\d{1,2}$/// 用戶名 /^[a-zA-Z]\w{5, 17}$/// 簡單的 IP 地址匹配 /\d+\.\d+\.\d+\.\d+/https://deerchao.cn/tutorials/regex/regex.htm
關于作用域和自由變量的場景題 - 2
let a = 100 function test(){alert(a) //100a = 10alert(a) //10 } test() alert(a) //10如何獲取最大值
手寫字符串trim方法,保證瀏覽器兼容性
String.prototype.trim = function(){return this.replace(/^\s+/,'').replace(/\s+$/,'') } //原型、this、正則表達式如何獲取多個數字中的最大值
//方式一 function max(){const nums = Array.prototype.slice.call(arguments) //變為數組let max = 0nums.forEach(n => {if(n > max){max = n}})return max } //方式二 Math.max(10,30,20,40) //以及Math.min如何用JS實現繼承
- class繼承
- prototype繼承
解析url參數
如何捕獲JS程序中的異常
try{//todo }catch(ex){console.log.error(ex) //手動捕獲catch }finally{//todo } //自動捕獲 window.onerror = function(message,source,lineNum,colNum,error){//第一,對跨域的js,如CDN的,不會有詳細的報錯信息//第二,對于壓縮的js,還要配合sourceMap反查到未壓縮代碼的行、列 }什么是JSON
- json是一種數據格式,本質是一段字符串
- json格式和JS對象結構一致,對JS語言更友好
- window.JSON是一個全局對象:JSON.stringify JSON.parse
key和value必須用雙引號(除非是bool或者數字)
獲取當前頁面url參數
- 傳統方式,查找location.search
- 新API,URLSearchParams
數組去重有幾種方式
將url參數解析為JS對象
//傳統方式,分析search function queryToObj(){const res = {}const search = location.search.substr(1) //去掉前面的?號search.split('&').forEach(paramStr => {const arr = paramStr.split('=')const key = arr[0]const val = arr[1]res[key] = val})return res } //使用URLSearchParams function queryToObj(){const res = {}const pList = new URLSearchParams(location.search)pList.forEach((val,key) => {res[key] = val})return res }手寫數組flatern,考慮多層級
function flat(arr) {// 驗證 arr 中,還有沒有深層數組 [1, 2, [3, 4]]const isDeep = arr.some(item => item instanceof Array)if (!isDeep) {return arr // 已經是 flatern [1, 2, 3, 4]}const res = Array.prototype.concat.apply([], arr)return flat(res) // 遞歸 }const res = flat( [1, 2, [3, 4, [10, 20, [100, 200]]], 5] ) console.log(res) //[1,2,3,4,10,20,100,200,5]數組去重
- 傳統方式,遍歷元素挨個比較、去重
- 使用Set
- 考慮計算效率
是否用過requestAnimationFrame
手寫深拷貝
/*** 深拷貝* @param {Object} obj 要拷貝的對象*/ function deepClone(obj = {}) {if (typeof obj !== 'object' || obj == null) {// obj 是 null ,或者不是對象和數組,直接返回return obj}// 初始化返回結果let resultif (obj instanceof Array) {result = []} else {result = {}}for (let key in obj) {// 保證 key 不是原型的屬性if (obj.hasOwnProperty(key)) {// 遞歸調用!!!result[key] = deepClone(obj[key])}}// 返回結果return result } const obj1 = {age: 20,name: 'xxx',address: {city: 'beijing'},arr: ['a', 'b', 'c'] }const obj2 = deepClone(obj1) obj2.address.city = 'shanghai' obj2.arr[0] = 'a1' console.log(obj1.address.city) console.log(obj1.arr[0]) //注意Object.assign不是深拷貝 const obj = {a:10,b:20,c:30} Object.assign(obj,{d:40}) {a:10,b:20,c:30,d:40} console.log(obj) //{a:10,b:20,c:30,d:40}const obj1 = Object.assign({},obj,{e:50}) console.log(obj) //{a:10,b:20,c:30,d:40} console.log(obj1) //{a:10,b:20,c:30,d:40,e:50} obj.a = 100 console.log(obj1) //{a:10,b:20,c:30,d:40,e:50} const obj = {a:10,{x:100,y:100}} const obj1 = Object.assign({},obj,{c:30}) console.log(obj) //{a:10,{x:100,y:100}} console.log(obj1) //{a:10,{x:100,y:100},c:30} obj.a = 100 console.log(obj) //{a:100,{x:100,y:100}} nsole.log(obj1) //{a:10,{x:100,y:100},c:30} obj.b.x = 101 console.log(obj1.b.x) //101介紹一下RAF requestAnimationFrame
- 要想動畫流暢,更新頻率要60幀/s,即16.67ms更新一次視圖
- setTimeout要手動控制頻率,而RAF瀏覽器會自動控制
- 后臺標簽或隱藏iframe中,RAF會暫停,而setTimeout依然執行
前端性能如何優化?一般從哪幾個方面考慮?
- 原則:多使用內存、緩存,減少計算、減少網絡請求
- 方向:加載頁面,頁面渲染,頁面操作流暢度
總結
以上是生活随笔為你收集整理的(十三)真题模拟【告诉你答案是什么】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软推出语音合成模型 NaturalSp
- 下一篇: (二)面试前的准备【要知己知彼,不打无准