前端面試之路二(javaScript基礎整理)

1、變量類型和計算

JS中使用typeof能獲得哪些類型

變量類型
  • 值類型:變量自己就是含有賦予給它的數值的,它的變量自己及保存的數據都存儲在棧的內存塊當中
  • 引用類型:引用類型固然是分配到堆上的對象或者數據變量,根據官方一點的解釋就是引用類型的變量只包括對其所表示的數據引用javascript

    • 對象、數組、函數
    • 無限擴展屬性,可能出現內存佔用比較大的狀況
typeof abc      //"undefined"
typeof NaN      //"number"
typeof null     //"object"
typeof console.log //"function"

typeof只能區分值類型,對引用類型無能爲力,只能區分函數function<br/>
NaN表示特殊的非數字值,null是空指針,並無指向任何一個地址<br/>
typeof能區分的五種基本類型:stringbooleannumberundefinedsymbol和函數functionhtml

變量計算

可能發生強制類型轉換的狀況:
  • 字符串拼接
  • == 運算符
100  ==  '100'  //true
0    ==  ""     //true
null ==  undefined  //true
  • if語句
var c = '';
    if(c){
        //....
    }
  • 邏輯運算
console.log(10 && 0);       //0
 console.log('' || 'abc');   //'abc'
 console.log(!window.abc);   //true
 
 
 //判斷一個變量會被當作true仍是false
 雙非判斷
 var a = 100;
 console.log(!!a);

在js邏輯運算中,0、NaN、""、null、false、undefined都會判爲false,其餘都爲true前端

var add_level = (add_step == 5 && 1)||(add_step == 10 && 2)||(add_step == 12 && 4)||(add_step==15 && 5 )|| 0;
var add_level = {'5':1,'10':2,'15':5,'12':4}[add_step]||0; //更精簡

什麼時候使用 === 什麼時候使用 ==

if(obj.a == null){
    //這裏至關於obj.a === null || obj.a === undefined,簡寫
    //這是jquery源碼中推薦的寫法,除此以外其餘全用 ===
    //主要是用於判斷這個屬性是否存在
}
//判斷函數參數是否存在
function (a,b){
    if(a == null){
        ...
    }
}
//這種寫法不能用
 if(xxx == null){
     //可能會報錯,這個參數未定義  not defined
 }

JS變量按照存儲方式區分爲哪些類型,並描述其特色

如何理解json

  • JSON是一個JS內置對象,經常使用兩個API
JSON.stringify({a:10,b:20})
 JSON.parse('{"a":10,"b":20}')
  • 同時也是一種數據格式

2、原型和原型鏈

原型規則

  • 全部的引用類型(數組、函數、對象)都具備對象特性,便可自由擴展屬性】
  • 全部的引用類型(數組、對象、函數)有一個__proto__ 屬性,屬性值是一個普通的對象
  • 全部的函數都有一個prototype屬性,屬性值也是一個普通的對象
  • 全部的引用類型(數組、對象、函數),__proto__屬性指向它的構造函數的prototype屬性
  • 當試圖獲得一個對象的某個屬性時,若是這個對象自己沒有這個屬性,那麼回去他的__proto__(即它的構造函數的prototype中尋找)

原型鏈

instanceof

instanceof:用於判斷引用類型屬於哪一個構造函數的方法

f instanceof Foo的判斷邏輯是:java

  • f的__proto__一層一層往上,可否對應到Foo.prototype
  • 再試着判斷f instance Object

如何準確判斷一個變量是不是數組類型

var arr = []
arr instanceOf Array //true
typeof arr //object,typeof是沒法判斷是不是數組的node

通用判斷方法:Object.prototype.toString.call(arr) === "[object Array]"jquery

寫一個原型鏈繼承的例子

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.innerHtml; 
    }
} 

Elem.prototype.on = function(type,fn){
    var elem = this.elem
    elem.addEventListener(type,fn)
}

var div1 = new Elem('content_wrapper')
//div1.html('<p>ds<p>')
//div1.on('click',function(){
//    alert('clicked')
//    }
//)
div1.html('<p>放大放大放大發范德薩大點的我請薩</p>').on('click',function(){
    alert('clicked');
}).html('<p>javascript</p>')

描述建立一個對象的過程

  • 新生成了一個對象
  • 連接到原型
  • 綁定 this
  • 返回新對象
function create() {
    let obj = new Object()
    let Con = [].shift.call(arguments)
    obj.__proto__ = Con.prototype
    let result = Con.apply(obj, arguments)
    return typeof result === 'object' ? result : obj
}

zepto源碼中如何使用原型鏈

3、做用域和閉包

題目ios

  • 說一下對變量提高的理解
  • 說明this幾種不一樣的使用場景
  • 建立10個 < a>標籤,點擊的時候彈出對應的序號
  • 如何理解做用域
  • 實際開發中閉包的應用

執行上下文

  • 範圍:一段<script>或者一個函數
  • 全局:變量定義、函數聲明、一段<script>
  • 函數:變量定義、函數聲明、this、arguments
console.log(a)    //undefined
var a = 100
fn('zhangsan')    //'zhangsan' 20
function fn(name){
    age = 20
    console.log(name,age)
    var age
}
  • 函數聲明會被提出來,函數表達式會和變量同樣,以undefined佔位
  • 在函數執行以前,變量定義、函數聲明、thisarguments都要先提取出來

函數聲明函數表達式的區別

fn()                    //不會報錯
function fn(){
    //聲明
}
fn()                    //Uncaught TypeError:fn1 is not a function 
var a = function(){
    //表達式
}
  • 變量提高: var a ; undefined,並不知道是一個函數
  • 函數提高: 把函數聲明提早
fn('zhangsan')

function fn(name){
    //函數
    console.log(this)
    console.log(arguments)

    age = 20
    console.log(name,age)
    var age
    
    bar(100)
    function bar(num){
        console.log(num)
    }
}

說明this幾種不一樣的使用場景

  • 做爲構造函數執行
  • 做爲對象屬性執行
  • 做爲普通函數執行(window)
  • callapplybind
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

this要在執行的時候才能確認值面試

做用域

沒有塊級做用域
if(true){
    var name = 'zhangsan'
}
console.log(name)
函數做用域和全局做用域
var a = 100
function fn(){
    var a = 200
    console.log('fn',a)
}

console.log('global',a)

fn()

做用域鏈

如何理解做用域:
  • 自由變量
  • 做用域鏈,即自由變量的查找
  • 閉包的兩個場景
var a = 100
function fn(){
    var b = 200
    //當前做用域沒有定義的變量,即「自由變量」
    console.log(a)
    console.log(b)
}
fn()

自由變量做用域鏈,一直往父級做用域找,一直找到全局做用域ajax

var a = 100
function F1(){
    var b = 200
    function F2(){
        var c = 300
        console.log(a)   //a是自由變量
        console.log(b)     //b是自由變量
        console.log(c)
    }
    F2()
}
F1()

閉包

做用域是定義時的做用域,而不是執行時的做用域chrome

閉包的使用場景:

函數做爲返回值

function F1(){
    var a = 100
    //返回一個函數(函數做爲返回值)
    return function(){
        console.log(a)
    }
}

var f1 = F1()
var a = 200
f1()
函數做爲參數傳遞
function F1(){
    var a = 100
    return function(){
        console.log(a)   //自由變量,父做用域尋找
    }
}

var f1 = F1()

function F2(fn){
    var a = 200
    fn()
}

F2(f1)

面試題

題目一、說一下對變量提高的理解

在某一做用域中,聲明變量的語句會默認解析爲在該做用域的最開始就已經聲明瞭

題目二、說明this幾種不一樣的使用場景

https://blog.csdn.net/w_q_102...

題目三、建立10個 < a>標籤,點擊的時候彈出對應的序號

錯誤寫法
var i,a
for(i = 0;i<10;i++){
    a = document.createElement('a')
    a.innerHTMl = i + '<br>'
    a.addEventListener('click',function(e){
        e.preentDefault()
        alert(i)
    })
    document.body.appendChild(a)
}
正確寫法
var i,a
for(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)
}

題目四、如何理解做用域

  • 自由變量
  • 做用域鏈,即自由變量的查找
  • 閉包的兩個場景

題目五、實際開發中閉包的應用

//閉包實際應用中主要用於封裝變量,收斂權限

function isFirstLoad(){ 
    var _list = []; 
    return function(id){
        if(_list.indexOf(id) >= 0){
            return false; 
        }else{ 
            _list.push(id);
            return true;
        } 
    }}
    var firstLoad = isFirstLoad();
    firstLoad(10);

4、異步和單線程

題目:

  • 同步和異步的區別是什麼?分別舉一個同步和異步的例子
  • 一個關於setTimeout的筆試題
  • 前端使用異步的場景有哪些

知識點

  • 什麼是異步(對比同步)
  • 前端使用異步的場景
  • 異步和單線程

什麼是異步

是否阻塞程序的運行

什麼時候須要異步

在可能發生等待的狀況
  • 定時任務:setTimeout,setTimeInterval
  • 網絡請求:ajax請求,動態<img>加載
  • 事件綁定

等待過程當中不能像alert同樣阻塞程序運行

所以全部的「等待的狀況」都須要異步

異步和單線程

console.log(100)
setTimeout(function(){
    console.log(200)
},1000)
console.log(300)
  • 執行第一行,打印100
  • 執行setTimeout後,傳入setTimeout的函數會被暫存起來,不會當即執行(單線程特色,不能同時幹兩件事)
  • 執行最後一行,打印300
  • 待全部程序執行完,處於空閒狀態時,會立馬看有沒有暫存起來的要執行
  • 發現暫存起來的setTimeout中的函數無需等待時間,就當即來過來執行

面試題

筆試題1: 同步和異步的區別是什麼?分別舉一個同步和異步的例子

同步會阻塞代碼執行,而異步不會

筆試題2:一個關於setTimeout的筆試題

console.log(1)

setTimeout(function(){
    console.log(2)
},0)

console.log(3)

setTimeout(function(){
    console.log(4)
},1000)

console.log(5)

筆試題3:前端使用異步的場景有哪些

須要等待,由於js是單線程語言

5、常見對象

題目

  • 獲取2017-06-10格式的日期
  • 獲取隨機數,要求是長度一直的字符串格式
  • 寫一個能遍歷對象和數組的通用forEach函數

Date

Date.now() //獲取當前時間毫秒數
  
var dt = new Date()
dt.getTime()          //獲取毫秒數
dt.getFullYear()      //年
dt.getMonth()        //月(0-11)
dt.getDate()        //日(0-31)
dt.getHours()        //小時(0-23)
dt.getMinutes()        //分鐘(0-59)
dt.getSeconds()        //秒(0-59)

Math

Math.random():能夠用來清除緩存

Array

  • forEach 遍歷全部數據
  • every 判斷全部元素是否都符合條件
  • some 判斷是否有至少一個元素符合條件
  • sort 排序
  • map 對元素從新組裝,生成新數組>- 過濾符合條件的元素
array.forEach
arr.forEach( function(item,index){ 
    console.log(index,item); 
});
array.every
var arr = [1,2,3,4,5];
var result = arr.every(function(index,item){
//用來判斷全部的數組元素,都知足一個條件 
    if(item<6) 
        return true
});
    console.log(result);
array.some
var result = arr.some(function(index,item){ 
    if(item<5) 
        return true;
}); 
console.log(result);
arry.sort
var arr2 = arr.sort(function(a,b){ 
    //從小到大排序 return a-b; 
    //從大到小排序 
    //return b-a;
})
array.map
arr.map(function(item,index){
    return '<br>'+index+':'+item+'<br>'
})
array.filter
var arr2 = arr.filter(function (item,index){ 
    //經過某一個條件過濾數組 
    if(item >= 2) 
        return true
})

對象API

var obj = {
    x:100,
    y:200,
    z:300
}

var key

for(key in obj){
    if(obj.hasOwnProperty(key)){
        console.log(key,obj[key])
    }
}

面試題

解答1:獲取2016-06-10格式的日期

function formatDate(dt){
    if(!dt){
        dt = new Date()
    }

    var year  = dt.getFullYear()
    var month = dt.getMonth() + 1
    var date  = dt.getDate()

    if(month < 10){
        //強制類型轉換
        month = '0' + month 
    }

    if(date < 10){
        //強制類型轉換
        date = '0' + date
    }
    //強制類型轉換
    return year + '-' + month + '-' + date
}

var dt = new Date()
var formatDate = formatDate(dt)
console.log(formatDate)

解答2:獲取隨機數,要求是長度一致的字符串格式

var random = Math.random() + '0000000000';
var random = random.slice(0,10);

解答3:寫一個能遍歷對象和數組的通用forEach函數

function forEach(obj,fn){
    var key
    if(obj instanceof Array){
        //準備判斷是否是數組
        obj.forEach(function(item,index){
            fn(index,item)
        })
    }else{
        //不是數組就是對象
        for(key in obj){
            fn(key,obj[k])
        }
    }
}

5、JS-Web-API:

知識點:

  • js基礎知識:ECMA262標準
  • JS-Web-API:W3C標準

W3C標準中關於JS的規定有:

  • DOM操做
  • BOM操做
  • 事件綁定
  • ajax請求(包括http協議)
  • 存儲

DOM操做

DOM的本質
DocumentObjectModel
瀏覽器把拿到的html代碼,結構化一個瀏覽器可以識別而且js可操做的一個模型而已

DOM的節點操做

  • 獲取DOM節點
  • Attribute 和 properity
  • attribute:是HTML標籤上的某個屬性,如id、class、value等以及自定義屬性,它的值只能是字符串,關於這個屬性一共有三個相關的方法,setAttribute、getAttribute、removeAttribute;

注意:在使用setAttribute的時候,該函數必定接收兩個參數,setAttribute(attributeName,value),不管value的值是什麼類型都會編譯爲字符串類型。在html標籤中添加屬性,本質上是跟在標籤裏面寫屬性時同樣的,因此屬性值最終都會編譯爲字符串類型。

  • property:是js獲取的DOM對象上的屬性值,好比a,你能夠將它看做爲一個基本的js對象。這個節點包括不少property,好比value,className以及一些方法onclik等方法。

一個js對象有不少property,該集合名字爲properties,properties裏面有其餘property以及attributies,attributies裏面有不少attribute。
而經常使用的attribute,id、class、name等通常都會做爲property附加到js對象上,能夠和property同樣取值、賦值

DOM結構操做

面試題1:DOM是那種基本的數據結構?

面試題2:DOM操做的經常使用API有哪些?

  • 獲取DOM節點,以及節點的propertyAttribute
  • 獲取父節點,獲取子節點
  • 新增節點,刪除節點

面試題3:DOM節點的attr和property有何區別

property只是一個JS對象的屬性的修改

Attribute是對html標籤屬性的修改

BOM操做

問題:

  • 如何檢測瀏覽器的類型
  • 拆解URL各部分

知識點

  • navigator
  • screen
  • location
  • history

navigator & screen

//navigator
var ua = navigator.userAgent
var isChrome = ua.indexOf('chrome')
console.log(isChrome)

//screen
console.log(screen.width)
console.log(screen.height)

//location
console.log(location.href)
console.log(location.protocol)
console.log(location.pathname)
console.log(location.search)    //?以後的參數
console.log(location.hash)      //#號以後

//history
history.back()          
history.forward()

6、事件

題目:

  • 編寫一個通用的事件監聽函數
  • 描述時間冒泡流程
  • 對於一個無限下拉加載圖片的頁面,如何給每一個圖片綁定事件

知識點:

  • 通用事件綁定
  • 事件冒泡
  • 代理

知識點

通用事件綁定

var btn = document.getElementById('btn1')
btn.addEventListener('click', function(event) {
    console.log('clicked')
})

function bindEvent(elem, type, fn) {
    elem.addEventListener(type, fn)
}

var a = document.getElementById('link1')
bindEvent(a, 'click', function(e) {
    e.preventDefault(); //阻止默認行爲
    alert('clicked')
})
關於IE低版本的兼容性
  • IE低版本使用attachEvent綁定事件,和W3C標準不同
  • IE低版本使用量已很是少,不少網站早已不支持
  • 建議對IE低版本的兼容性:瞭解便可,無須深究
  • 若是遇到對IE低版本要求苛刻的面試,果斷放棄

事件冒泡

e.stopPropatation() //取消冒泡

代理

<div id="div1">
    <a href = "#">a1</a>
    <a href = "#">a2</a>
    <a href = "#">a3</a>
    <a href = "#">a4</a>
    <!--會隨時新增更多 a 標籤-->
</div>


var div1 = document.getElementById('div1')
div1.addEventListener('click',function(e){
    var target = e.target
    if(target.nodeName === 'A'){
        alert(target.innerHTMl)
    }
})

完整寫法

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)
        }
    })
}

//使用代理
var div1 = document.getElementById('div1')
bindEvent(div1, 'click', 'a', function(e) {
    console.log(this.innerHTML)
})

//不使用代理
var a = document.getElementById('a1')
bindEvent(div1, 'click', function(e) {
    console.log(a.innerHTML)
})

面試題

面試題1:編寫一個通用的事件監聽函數

面試題2:描述事件冒泡流程

  • DOM樹形結構
  • 事件冒泡
  • 組織冒泡
  • 冒泡的應用

面試題3:對於一個無限下拉加載圖片的頁面,如何給每一個圖片綁定事件

  • 使用代理
  • 知道代理的兩個優勢

7、Ajax

題目:

  • 手動寫一個ajax,不依賴第三方庫
  • 跨域的幾種實現(原理)

知識點:

  • xmlHttpRequest
  • 狀態碼說明
  • 跨域

XMLHttpRequest

var xhr = new XMLHttpRequest()

xhr.open("GET","/api",false)

xhr.onreadystatechange = function(){
    //這裏的函數異步執行,可參考以前JS基礎中的異步模塊
    if(xhr.readyState == 4){
        if(xhr.status == 200){
            alert(xhr.responseText)
        }
    }
}

xhr.send(null)
IE兼容性問題
  • IE低版本使用ActiveXObject,和W3C標準不同
  • IE低版本使用量已經很是少,不少網站早已不支持
  • 建議對IE低版本的兼容性:瞭解便可,無需深究
  • 若是遇到對IE低版本要求苛刻的面試,果斷放棄

.

狀態碼說明
  • 0 - (未初始化)     還沒調用send()方法
  • 1 - (載入)            已調send() 方法,正在發送請求
  • 2 - (載入完成)     send()方法執行完成,已經接收到所有相應內容
  • 3 - (交互)            正在解析響應內容
  • 4 - (完成)            響應內容解析完成,能夠在客戶端調用了

.

status說明

  • 2XX - 表示成功處理請求。如200
  • 3XX - 須要重定向,瀏覽器直接跳轉
  • 4XX - 客戶端請求錯誤,如404
  • 5XX - 服務器端錯誤

跨域

什麼是跨域
  • 瀏覽器有同源策略,不容許ajax訪問其餘域的接口
  • 跨域條件:協議、域名、端口,有一個不一樣就算跨域

 

能夠跨域的三個標籤
  • <img src=''>
  • <script src=''>
  • <link href=''>

 

三個標籤的場景
  • <img>用於打點統計,統計網站多是其餘域(並且沒有任何兼容性問題)
  • <link> <script>可使用CDN,CDN也是其餘域
  • <script>能夠用於JSONP

 

跨越注意的問題
  • 全部的跨域請求都必須通過信息提供方容許
  • 若是未經容許便可獲取,那是瀏覽器同源策略出現漏洞

 

JSONP實現原理
  • 加載 http://coding.xxx.com/classin...
  • 不必定服務器端真正有一個classindex.html文件
  • 服務器能夠根據請求,動態生成一個文件,返回
  • 通理於<script src="http://coding.xxxxx.com/api.js">
//例如你的網站要跨域訪問xx網的一個接口
//給你一個地址 http://coding.xxxx.com/api.js
//返回內容格式 callback({x:100,y:200})

<script>
window.callback = function(data){
    //這是咱們跨域獲得信息
    console.log(data)
}
</script>
<script src="http://coding.m.xxxxx.com/api.js"></script>
服務器端設置http header

cookiesessionStoragelocalStorage的區別

  • 容量
  • 是否會攜帶到ajax中
  • API易用性
ios safari隱藏模式下,localStorage.getItem會報錯,建議統一用try-catch封裝



面試全家桶

HTML+CSS 面試整理                                --------------------------------> 點這裏

前端高級面試整理(三大框架等深刻知識) --------------------------------> 點這裏

javascript性能優化                                      --------------------------------> 點這裏

javascript設計模式                                      --------------------------------> 點這裏

HTTP相關面試                                            -------------------------------->點這裏

相關文章
相關標籤/搜索