Javascript學習筆記面試(二)js基礎部分

1、變量的類型和計算

1.變量類型

//值類型
let a = 200;
let b = a;
a = 100;
console.log(a, b)

// 引用類型
let a = { age: 24 };
let b = a;
b.age = 25;
console.log(a, b);
值類型和引用類型的區別?

值類型,值類型的複製就是複製棧裏的value
引用類型的複製複製的是堆的引用內存地址css

爲何?

值類型的佔據內存比較小,引用類型佔據的內存可能會很是大,不利於複製,從CPU和性能考慮把引用類型和值類型的複製的方式給分離出來。(js引擎)html

哪些是值類型?哪些是引用類型?
let a;// undefined
const b = "string";
const c = false;
const n = 100;
const s = Symbol('s');
const obj = { age: 24 };
const arr = ["1", "2", "3"];

const n = null; // 特殊的引用類型,指針指向的是空地址

// 特殊引用類型 不用於存儲數據,因此沒有拷貝,複製函數之說
function fn() { }
typeOf 類型判斷
全部的值類型,函數
引用類型只能到Object
手寫深拷貝

重點1:初始化result
重點2:使用遞歸webpack

obj1 = {
            name: "鬍子銀",
            level: "p0"
        };

        function deepClone(obj = {}) {
            if (typeof obj !== 'object' || typeof obj == null) {
                return obj;
            }
            // 初始化返回結果
            let result;
            if (obj instanceof Array) {
                result = []

            } else {
                result = {}
            }
            // 開始拷貝
            for (let key in obj) {
                if (obj.hasOwnProperty(key)) {
                    // 保證key 不是原型的屬性
                    // 遞歸調用
                    result[key] = deepClone(obj[key]);
                }
            }
            return result;
        }

2.變量計算

字符串拼接
const a =100+10 // 110
const b = 100 +'10' // '10010'
const c= true + '10' // 'true10'
==運算符
100 == '100' // true
0 == '' // true
0 == false // true
false =='' // true
null == undefined // true

總結: 除了null == 其餘都用===ios

if語句和邏輯運算

truely 變量與 falsely 變量 兩次取反es6

image.png

2、原型和原型鏈

面向對象

類的繼承:extends super 重寫web

隱式原型 與 顯式原型

instanceof 是否是它構建的。父類。Object是全部的父類面試

Student.__proto__ === People.ProtoType // true

隱式原型 :Student.proto
顯式原型:People.ProtoTypeajax

image.png

每一個class都有顯式原型,每一個實例都有隱式原型,實例的隱式原型指向類的顯式原型。json

原型鏈

image.png

instanceOfaxios

3、做用域和閉包

this 在不一樣場景下,如何取值?
手寫bind函數
閉包在實際開發場景中的應用
什麼是做用域?

變量的合法使用範圍。框裏面的均可以。

做用域:

全局做用域

函數做用域

塊級做用域 let const {}

什麼是閉包?閉包會被做用到哪裏?

做用域應用的特殊表現,有兩種狀況

  • 函數做爲參數被傳遞。
  • 函數做爲返回值被返回。

總之,函數定義的地方和執行的地方是不同的。

閉包:自由變量在函數定義的地方向上級做用域查找。而不是在執行的地方。

// 函數做爲返回值
function createFun() {
    const a = 100;
    return function () {
        console.log(100);
    }
}

const fn = createFun();

const a = 200;
fn();
// 函數做爲參數被傳遞
const a = 100;
function param() {
    console.log(a);
};

function close(param) {
    const a = 200;
    param();
};

// const clo = new close(param);

close(param);
this的幾種賦值狀況

函數在執行的時候決定。

箭頭函數 ==> 取的是上級做用域的值

bind call 的區別

function fn() {
    console.log(this);
}
const fnbind = fn.bind({ x: 200 },10,20,30);
fn();
fn.call({ x: 100 });
fnbind()

image.png

做用域相關的面試題
this的使用場景,console.log(this)

一、普通函數被調用 // window

二、做爲對象方法 指向對象

三、bind,call,apply 把this的指向做爲參數傳遞進去。(傳進去的就是this)

四、箭頭函數 this指向上一層做用域

五、在class中調用
手寫bind函數
JavaScript中的 Array.prototype.slice.call(arguments)能將有length屬性的對象轉換爲數組
Function.prototype.bind = function () {
    const args = Array.prototype.slice.call(arguments);
    // 獲取數組的第一項
    const t = args.shift();
    //此處this是fn1.bind()中的fn1
    const self = this;
    return function () {
        return self.apply(t, args);
    }
}
閉包中的應用

閉包: 自由變量在函數定義的地方向上級做用域查找。而不是在執行的地方。

閉包隱藏數據,只提供api,閉包中的數據,被隱藏,不被外界訪問。

建立緩存,set,get,調用get方法取到的變量是,而不是

image.png

let構成了塊級做用域
image.png

4、異步

基礎
const imgUrl = "0000";
        function loadImg(src) {
            return new Promise((resolve, reject) => {

                const img = document.createElement('img');

                img.onload = () => {
                    return resolve(img);
                }
                img.onerror = () => {
                    return reject(new Error("圖片加載失敗"));
                }
                img.src = img;

            })
        }
        
loadImg(url).then((img) => {
            console.log(img.width);
            return img;

        }).then((img) => {
            console.log(img.height);
        })
進階

事件輪訓,事件循環

js是單線程,異步要基於回調實現,event Loop就是根據異步回調的實現原理

js是怎樣執行的?

image.png

image.png

call Stack:調用棧 用完就清空

web apis:如setTimeout dom bom等

callback queue:回調函數隊列

event loop:

總結:
同步代碼,一行一行放在Call Stack執行

遇到異步,會先「記錄」下,等待時機(定時、網絡請求等);

時機到了,就移到Callback Queue

如Call Stack爲空(即同步代碼執行完成)Event Loop開始工做

輪詢查找Callback Queue,若有則移到Call Stack 執行

而後繼續輪詢查找

dom事件也是基於Event Loop。

Promise

then 正常返回resolved ,裏面有報錯則返回rejected

catch 正常返回resolved,裏面有報錯則返回rejected

總結:

三種狀態,狀態和表現

then和catch對狀態的影響(重要)

then和catch的鏈式調用(常考) 只要是沒報錯,就是resolved。

async await

異步回調

promise也是基於回調。async-await完全消滅了回調。

async和promise的關係

image.png

- 執行async函數,返回的是Promise對象

- await至關於Promise的then (假如直接返回的數據,至關於 Promise.resolve(400))

- try...catch可捕獲異常,代替了Promise的catch

async await是語法糖 異步的本質仍是回調函數

仍是基於回調函數,仍是基於event Loop

for ...of

for...in(以及forEach for)是常規的同步遍歷 ????

for...of 經常使用於異步遍歷?????

宏任務與微任務

宏任務與微任務

  • 宏任務:setTimeout,setInterval,Ajax,DOM事件
  • 微任務:Promise,async/await
  • 微任務執行的時間要比宏任務執行的時間要早。

爲何微任務比宏任務的執行時間要早?

event Loop 與 DOM事件 渲染。js是單線程的。也就是說event Loop與Dom渲染共用同一個線程。

宏任務在DOM渲染後觸發,如setTimeout();

微任務,在DOM渲染後,如setTimeout();

image.png

爲何宏任務在DOM渲染後觸發,微任務在DOM渲染前觸發?

宏任務與微任務的根本區別

從event Loop解釋爲何微任務比宏任務的執行時間早。

微任務是瀏覽器規定的

宏任務是es6規定的

存放的地方不同。

總結:

5、JS-WEB-API

JS = ECMA (ECMA262標準)+DOM(w3c) +BOM (w3c)

W3C規定web-api,css,html,網絡請求的東西還挺多的。

5.1DOM

document object model

題目:

DOM是哪一種數據結構
DOM操做的經常使用API
attr和property的區別
一次性插入多個DOM節點,考慮性能

dom的本質

dom節點的操做

const div1 = document.getElementById("app1"); // 
const div2 = document.getElementsByClassName("appclass");
    
const divList = document.getElementsByTagName("div"); // list
const pList = document.querySelectorAll("p"); // 

console.log("div1:", div1);
console.log("div2", div2);
console.log("divList:", divList);
console.log("pList:", pList);

// property 形式 修改屬性值
console.log(pList[1].style.width);
console.log(pList[1]);

// attribute 形式 修改屬性
pList[1].setAttribute("data-name", "imook");
console.log(pList[1].getAttribute("data-name"));
pList[1].setAttribute("style", "font-size:50px");

打印出來的結果對比,直接獲取的dom節點,list的會有屬性
image.png

dom 結構操做

DOM性能

  • DOM操做很是昂貴,應該避免常常對DOM元素進行操做。
  • 對dom查詢作緩存。
  • 將頻繁操做改成一次性操做
const listNode = document.getElementById("app1");
const flagNode = document.createElement("ul");

for (let i = 0; i <= 5; i++) {
    const li = document.createElement("li");
    li.innerHTML = "innerHtml";
    flagNode.appendChild(li);
};

listNode.appendChild(flagNode);

5.2 BOM

題目

如何識別瀏覽器的類型?

ua

分析拆解url的各個部分。
// navigator
console.log(navigator.userAgent); // ua檢查方案

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

// location
console.log(location.href); // 整個網址
console.log(location.host) // 域名
console.log(location.search);  // 
console.log(location.hash); // 哈希 #
console.log(location.pathname); // 

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

5.3 事件 事件綁定和事件冒泡

通用的事件綁定函數

<button id="btn1">點擊</button>
<script>
    var btn = document.getElementById("btn1");

    function bindEvent(ele, type, fn) {
        ele.addEventListener(type, fn);
    };

    btn.bindEvent("click", e => {
        // 阻止默認行爲
        e.proventDefault();
        // e.target
        console.log(e.target);
        console.log("事件綁定");
    })
</script>

事件冒泡

事件代理

把事件綁定到父元素上,點擊子元素,彈出子元素的interhtml

代碼簡潔,減小瀏覽器的內存使用,可是不要濫用。

5.4 AJAX

GET

const xhr = new XMLHttpRequest();

xhr.open("GET", "./data.json", true);

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        if (xhr.status === 200) {
            console.log(JSON.parse(xhr.responseText));
            alert(xhr.responseText);
        } else {
            console.log(xhr.responseText);
        }
    }
}
xhr.send(null);

POST

const xhr = new XMLHttpRequest();

xhr.open("POST", "./login", true);

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
        if (xhr.status === 200) {
            console.log(JSON.parse(xhr.responseText));
            alert(xhr.responseText);
        } else {
            console.log(xhr.responseText);
        }
    }
}
const postData = {
    "name": "狂徒張三"
}
xhr.send(JSON.stringify(postData));

image.png

image.png

301 永久重定向
302 臨時重定向
304 資源有,重複,瀏覽器用本身的。事關性能優化
404 地址錯了
403 沒有權限

瀏覽器的同源策略

什麼是跨域(同源策略)?
JSONP
CORS(服務端支持)

image.png

image.png

image.png

image.png

image.png

jsonp的主要內容有兩點:
一、script能夠跨域
二、服務器拿到url能夠動態的返回一些內容

cors
是服務端設置請求頭,容許哪些進行訪問。

實際項目中ajax的經常使用插件

jqyery.ajax()

fetch()

axios
xmlhttprequest

5.5sessionStorage與localStorage的區別

題目:描述cookie localStorage sessionStorage 的區別

  • cookie
cookie的價值不在於本地存儲,而在於與服務端的通訊。是被借用來做爲本地存儲的工具。因爲每次請求都須要帶着cookie,因此會增長請求的數據量,並且cookie的最大的存儲空間是4kb,只能經過document.cookie來修改。過於簡陋。

修改的方式:相同的key,覆蓋,不一樣的key,追加
  • sessionStorage與localStorage
localStorage數據會永久存儲,除非代碼或者手動刪除

sessionStorage數據只存在於當前會話,當瀏覽器關閉就清空

六、HTTP

6.1 http的幾個面試題

常見的狀態碼:
301 永久重定向
302 臨時重定向,
舉例1:在百度檢索了一個css教程,hover上去的連接點擊之後,先是訪問百度的url而後瀏覽器的location再跳轉到真正的目的連接地址、。
舉例2:還有短鏈
304:瀏覽器已經請求過了,可使用本地的,本地的沒過時
403:沒權限
404:地址錯誤
5 **:服務端

關於協議和規範:就是一個約定和規範

6.2 http method

傳統method

get
post

如今的method

get 查
post 建立新的
patch
delete

restful API
  • 一種新的API設計方法(早已推廣使用)
  • 傳統API設計:把每一個url當作一個功能
  • Reatful API設計:把每一個url當作一個惟一的資源標識

儘可能不要使用參數,使用method做爲類型
image.png

image.png

6.3 http 常見headers

image.png

Request Headers

image.png

image.png

image.png

Request Headers

image.png

image.png

緩存相關的Headers

image.png

6.4 http爲何須要緩存?

關於緩存的介紹

網絡請求加載比較慢,cpu計算比較快。性能優化的主要瓶頸就在於網絡請求,當部分不須要被重複請求的資源被緩存,就能夠減小http請求,從而優化性能。

哪些資源能夠被緩存?靜態資源,(js,css,圖片,與webpack打包加的hash有關,只有內容改變了,纔會再次更改)

http緩存策略(強制緩存+協商緩存)

一、強制緩存
cache-contral 強制緩存,控制強制緩存的邏輯

cache-control:max-age=2592000 (秒)

image.png

max-age:過時時間

no-cache : 本地不作緩存

no-store:本地不緩存,服務器端也不緩存。

關於Expires

二、協商緩存(對比緩存)

Last-Modified: 最後一次修改的時間
Etag: 人類的指紋,惟一的標識,字符串

二者共存,會優先使用Etag,Etag會更加精準。

總結: 就是請求服務端,問問服務端本地的能不能用。

image.png

image.png

image.png

刷新操做方式 對緩存的影響

正常操做:url的前進後退; 都有效

手動刷新:強制緩存失效,協商緩存有效

強制緩存:contral + command + 2 都失效

相關文章
相關標籤/搜索