JAVAscript面試重點
什么是執行上下文
執行上下文就是當前 JavaScript 代碼被解析和執行時所在環境的抽象概念, JavaScript 中運行任何的代碼都是在執行上下文中運行
這是因為當函數執行的時候,首先會形成一個新的私有的作用域,然后依次按照如下的步驟執行
- 如果有形參,先給形參賦值
- 進行私有作用域中的預解釋,函數聲明優先級比變量聲明高,最后后者會被前者覆蓋,但是可以重新賦值
- 私有作用域中的代碼從上到下執行
閉包是什么
個人理解為,閉包就是函數中的函數,里面的函數可以訪問外面函數的變量,外面的變量是這個內部函數的一部分
閉包的作用
- 使用閉包可以訪問函數中的變量
- 可以長期保存在內存中,聲明周期比較長
- 注意:閉包不能亂用,否則會導致內存泄露,影響網頁的性能。閉包使用完之后,要立即釋放資源,將引用的變量指向null
閉包的主要應用
- 函數作為參數傳遞
- 函數作為返回值
異步和單線程
JS 需要異步的根本原因是 JS 是單線程運行的,即在同一時間只能做一件事,不能“一心二用”。為了利用多核CPU的計算能力,html5提出Web Worker標準,允許JavaScript腳本創建多個線程,但是子線程完全受主線程控制,且不得操作DOM。所以,這個新標準并沒有改變JavaScript單線程的本質。
一個 Ajax 請求由于網絡比較慢,請求需要 5 秒鐘。如果是同步,這 5 秒鐘頁面就卡死在這里啥也干不了了。異步的話,就好很多了,5 秒等待就等待了,其他事情不耽誤做,至于那 5 秒鐘等待是網速太慢,不是因為 JS 的原因
前端使用異步的場景
- setTimeout setInterval
- 網絡請求ajax,動態加載
- 事件綁定
原型和原型鏈
原型:在JavaScript中原型是一個prototype對象,用于表示類型之間的關系。
原型鏈:JavaScript萬物都是對象,對象和對象之間也有關系,并不是孤立存在的。對象之間的繼承關系,在JavaScript中是通過prototype對象指向父類對象,直到指向Object對象為止,這樣就形成了一個原型指向的鏈條,專業術語稱之為原型鏈。
var Person = function(){ this.name = '匿名', this.age = 18 } var Student = function(){} Student.prototype = new Person(); var s1 = new Student();
DOM操作
- 新增節點和移動節點
var div1 = document.getElementById('div1'); var p1 = document.creatElement('p'); //添加新節點 p1.innerHTML = "this is p1"; div1.AppendChild(p1); //添加新創建的元素 var p2 = document.getElementById('p2'); div1.appendChild(p2); //移動元素,這里的p2不加引號
- 獲取父元素
var div1 = document.getElementById('div1'); var par = div1.parentElement;
- 獲取子元素
var p2 = document.getElementById('p2'); var child = p2.childNodes; //返回子元素的標簽數組
DOM時間模型和事件流
DOM事件模型氛圍捕獲和冒泡。 一個事件發生后,會在子元素和父元素之間傳播,這種傳播分成三個階段
- 捕獲階段 事件從window對象自上而下向目標節點傳播的階段
- 目標階段 真正的目標節點正在處理事件的階段
- 冒泡階段 事件從目標節點自下而上向window對象傳播的階段
捕獲是從上到下,事件先從window對象,然后再到document對象,然后是html標簽,(通過document.documentElement獲取html標簽),然后是body標簽,(通過document.body獲取body標簽),然后按照普通的html結構一層一層往下傳,最后到達目標元素
阻止冒泡
ev.stopPropagation()
事件代理(事件委托)
由于事件會在冒泡的階段向上傳播到父節點,因此可以把子節點的監聽函數定義在父節點上,由父節點的監聽函數統一處理多個子元素的事件,這種方式叫做事件的代理
我們設定一種場景,一個div包含若干個a,而且還能繼續增加,那如何快捷方便的為所有a綁定事件呢
如果給每個a標簽都綁定一個事件,那對內存的消耗是非常巨大的,借助事件代理,我們只需要給父容器div綁定方法即可,
這樣不管是點擊的哪一個后代元素,都會根據冒泡傳播的傳遞機制,把父容器的click事件觸發,然后把對應的方法執行,根據事件源,
我們可以知道點擊的是誰,從而完成不同的事情
a標簽的各種屬性都可以獲取到,取需要的數據就可以了
使用代理的優點
- 代碼簡潔
- 減少瀏覽器的內存占用
BOM操作
BOM(瀏覽器對象模型)是瀏覽器本身的一些信息的設置和獲取,例如獲取瀏覽器的寬度、高度、設置讓瀏覽器跳轉哪個地址
- window.screen 對象,包含有關屏幕的信息
- window.location對象,用戶獲取當前地址的url,并把瀏覽器定向到新的頁面
- window.history對象,瀏覽歷史的前進后退
- window.navigator對象,常常用來獲取瀏覽器信息,是否移動端訪問
獲取屏幕的寬高
window.width window.height
獲取網址,協議,path,參數,hash等
// 例如當前網址是 https://juejin.im/timeline/frontend?a=10&b=10#some console.log(location.href) // https://juejin.im/timeline/frontend?a=10&b=10#some console.log(location.protocol) // https: consloe.log(location.pathname) //timeline/frontend consloe.log(location.search) //?a=10&b=10 consloe.log(location.hash) // #some
瀏覽器的前進后退
history.back() history.forward()
獲取瀏覽器的特性,然后識別客戶端,例如判斷是不是chrom瀏覽器
var ua = navigator.userAgent var isChrom = ua.indexOf('Chrom') console.log(isChrom)