JavaScript 面試
JS基礎(chǔ)篇
變量類型和計(jì)算
- JS中使用typeof能得到哪些類型
-undefinded- string
- number
- boolean
- object
- function
- 何時使用 === 何時用 ==
if (obj.a == null) {
// 這里相當(dāng)于obj.a === null || obj.a === undefined
}
- JS中有哪些內(nèi)置函數(shù)
- Array
- Object
- RegExp
- Date
- Error
- Function
- Boolean
- String
- umber
- JS變量按照存儲方式區(qū)分為哪些類型泞遗,并描述其特點(diǎn)
區(qū)分為值類型栏渺、引用類型。值類型的值復(fù)制之后不會相互干涉山析,引用類型的值復(fù)制是變量指針的復(fù)制箭跳,并不是真正的值的拷貝
- 如何理解JSON
JSON只不過是JS對象
原型和原型鏈
JS三座大山之一
- 如何準(zhǔn)確判斷一個變量是數(shù)組類型
instanceof。用于判斷引用類型屬于哪個構(gòu)造函數(shù)的方法
- 寫一個原型繼承的例子
function Elem(id) {
this.elem = document.getElementById(id)
}
Elem.prototype.html = function (val) {
var elem = this.elem
if (val) {
elem.innerHtml = val
return this
} else {
return elem.html()
}
}
Elem.prototype.on = function (type, fn) {
var elem = this.elem
elem.addEventListener(type, fn)
return this
}
var fuck = new Elem('fuck')
fuck.html('<p>hello</p>').on('click', function () {
alert('clicked!')
})
- 描述new一個對象的過程
- 創(chuàng)建一個新對象
- this指向這個新對象
- 執(zhí)行代碼萌狂,即對this賦值
- 返回this
- zepto源碼中如何使用原型鏈
作用域和閉包
- 說下對變量提升的理解
變量定義函數(shù)聲明都會提前定義
- 說明this幾種不同的使用場景
- 作為構(gòu)造函數(shù)執(zhí)行
- 作為對象屬性執(zhí)行
- 作為普通函數(shù)執(zhí)行
- call apply bind
- 創(chuàng)建10個<a>標(biāo)簽,點(diǎn)擊時彈出對應(yīng)的序號
for (var i = 0; i < 10; i++) {
(function (i) {
var a = document.createElement('a')
a.innerHTML = i + '<br>'
a.addEventListener('click', function (e) {
e.preventDefault()
alert(i)
})
document.body.appendChild(a)
})(i)
}
- 如何理解作用域
- 自由變量
- 作用域鏈
- 閉包的兩個場景 (函數(shù)作為值返回怀泊,函數(shù)作為參數(shù)傳遞)
- 實(shí)際開發(fā)中閉包的應(yīng)用
封裝變量茫藏,收斂權(quán)限
function isFirstLoad() {
var _list = []
// 保護(hù)了_list變量
return function (id) {
if (_list.indexOf(id) >= 0) {
return false
} else {
_list.push(id)
return true
}
}
}
var firstLord = isFirstLoad()
firstLord(10) // true
firstLord(10) // false
firstLord(20) // true
異步和單線程
- 同步和異步的區(qū)別是什么
同步會阻塞代碼執(zhí)行,異步不會
- 一個關(guān)于setTimeout的筆試題
- 前端使用異步的場景有哪些
- 定時任務(wù):setTimeout霹琼、setInterval
- 網(wǎng)絡(luò)請求:ajax加載刷允、動態(tài)<img>加載
- 事件綁定
其他
- 獲取2017-06-10格式的日期
function formateDate(dt) {
if (!dt) {
dt = new Date()
}
var year = dt.getFullYear()
var month = dt.getMonth()
var date = dt.getDate()
if (month < 10) {
month = '0' + month
}
if (date < 10) {
date = '0' + date
}
return year + '-' + month + '-' + date
}
- 獲取隨機(jī)數(shù),要求是長度一致的字符串格式
- 寫一個能遍歷對象和數(shù)組的通用forEach函數(shù)
function forEach(obj, fn) {
var key
if (obj instanceof Array) {
obj.forEach(function (item, index) {
fn(item, index)
})
} else {
for (key in obj) {
fn(key, obj[key])
}
}
}
webAPI
DOM操作
- DOM是哪種數(shù)據(jù)結(jié)構(gòu)
樹
- DOM操作的常用API有哪些
- 獲取DOM節(jié)點(diǎn)碧囊,以及節(jié)點(diǎn)的property和attribute
- 獲取父節(jié)點(diǎn)树灶,獲取子節(jié)點(diǎn)
- 新增節(jié)點(diǎn),刪除節(jié)點(diǎn)
- DOM節(jié)點(diǎn)的attr和property有何區(qū)別
- property只是一個JS對象的屬性的修改
- attribute是對html標(biāo)簽的修改
BOM操作
- 如何檢測瀏覽器的類型
var ua = navigator.userAgent
var isChrome = ua.indexOf('Chrome')
console.log(isChrome)
- 拆解url的各部分
location....
事件
- 編寫一個通用的事件監(jiān)聽函數(shù)
function bindEvent(elem, type, selector, fn) {
if (fn == null) {
fn = selector
selector = null
}
elem.addEventListener(type, function (e) {
var target
if (selector) {
target = e.target
if (target.matches(selector)) {
fn.call(target, e)
}
} else {
fn(e)
}
})
}
- 描述事件冒泡流程
- DOM樹形結(jié)構(gòu)
- 事件冒泡
- 阻止冒泡
- 冒泡的應(yīng)用 ==> 事件代理
- 對于無限下拉加載圖片的頁面糯而,如何給每個圖片綁定事件
事件代理:代碼簡介天通、減小瀏覽器的壓力
項(xiàng)目運(yùn)行環(huán)境
頁面加載
- 從輸入url到得到html的詳細(xì)過程
- 瀏覽器根據(jù)DNS服務(wù)器得到域名的IP地址
- 向這個IP的機(jī)器發(fā)送http請求
- 服務(wù)器收到、處理并返回http請求
- 瀏覽器得到返回的內(nèi)容
- window.onload和DOMContentLoaded的區(qū)別
- window.onload是等
待全部資源都加載完畢才會執(zhí)行熄驼,包括圖片像寒、視頻 - DOMContentLoaded是當(dāng)DOM結(jié)構(gòu)渲染完成即執(zhí)行,此時圖片瓜贾、視頻可能沒有加載完成
- window.onload是等
性能優(yōu)化
- 多使用內(nèi)存诺祸、緩存或者其他方法
- 減少CPU計(jì)算、減少網(wǎng)絡(luò)
安全性
Snippets
發(fā)生類型轉(zhuǎn)換的場景
- 字符串拼接
- == 運(yùn)算符
- if語句
- 邏輯運(yùn)算
原型規(guī)則
原型規(guī)則是學(xué)習(xí)原型鏈的基礎(chǔ)
- 所有的引用類型都具有對象的特性祭芦,即可用自由擴(kuò)展屬性('null'除外)
- 所有的引用類型都有一個proto屬性(隱式原型)筷笨,屬性值是一個普通對象
- 所有的函數(shù)都有一個prototype屬性(顯式原型),屬性值是一個普通對象
- 所有引用類型的proto屬性值指向它的構(gòu)造函數(shù)的prototype屬性值
- 當(dāng)試圖得到一個對象的某個屬性時龟劲,如果這個對象本身沒有這個屬性胃夏,那么會去它的proto(即它的構(gòu)造函數(shù)的prototype)中尋找
執(zhí)行上下文
- 范圍:一段<script>或者一個函數(shù)
- 全局:變量定義、函數(shù)聲明
- 函數(shù):變量定義昌跌、函數(shù)聲明仰禀、this、arguments
this
this要在執(zhí)行時才能確定值蚕愤,定義時無法確認(rèn)
var a = {
name: 'A',
fn: function () {
console.log(this.name)
}
}
a.fn() // this ==> a
a.fn.call({name: 'B'}) // this ==> {name: 'B'}
var fn1 = a.fn
fn1() // this ==> window
作用域
- 沒有塊級作用域
- 只有函數(shù)和全局作用域
- 自由變量:當(dāng)前作用域未定義的變量
linux命令
- mkdir 創(chuàng)建新文件夾
- ls 查看當(dāng)前文件夾內(nèi)容
- pwd 查看當(dāng)前文件夾路徑
- rm -rf a 刪除文件夾
- cp 拷貝文件
- mv 移動文件
- rm 刪除文件
- vim 創(chuàng)建并編輯文件
- cat 查看文件內(nèi)容
- head 查看文件前部內(nèi)容
- tail 查看文件末尾內(nèi)容
加載資源的形式
- 輸入url(或跳轉(zhuǎn)頁面)加載html
- 加載html中的靜態(tài)資源
加載資源的過程
- 瀏覽器根據(jù)DNS服務(wù)器得到域名的IP地址
- 向這個IP的機(jī)器發(fā)送http請求
- 服務(wù)器收到答恶、處理并返回http請求
- 瀏覽器得到返回的內(nèi)容
瀏覽器渲染頁面的過程
- 根據(jù)HTML結(jié)構(gòu)生成DOM tree
- 根據(jù)CSS生成CSSOM
- 將DOM和CSSOM整合成RenderTree
- 根據(jù)將DOM和CSSOM整合成RenderTree開始渲染和展示
- 遇到script時,會執(zhí)行并阻塞渲染
加載資源優(yōu)化
- 靜態(tài)資源合并壓縮
- 靜態(tài)資源緩存
- 使用CDN讓資源加載更快(不同區(qū)域的網(wǎng)絡(luò)優(yōu)化)
- 使用SSR后端渲染萍诱,數(shù)據(jù)直接輸出到HTML中
渲染優(yōu)化
- CSS放錢悬嗓、JS放后面
- 懶加載(圖片懶加載,下拉加載更多)
- 減少DOM查詢砂沛,對DOM查詢做緩存
- 減少DOM操作烫扼,多個操作盡量合并在一起執(zhí)行
- 事件節(jié)流
- 盡早執(zhí)行操作