1. Js的基本數(shù)據(jù)類型
- null
- undefined
- string
- symbol
- bigint
- boolean
- number
- object
Es6 新增了symbol和bigint兩種類型谆级,symbol一般常用可以結(jié)合redux的action的type進(jìn)行使用;bigint是大數(shù)處理姥卢,一般除非項目中涉及到很大的數(shù)才會用到舶掖。
2. 數(shù)據(jù)類型檢測的方式有哪些
- typeof 矩欠, 但是在判斷Array null為object
- instanceof 靶庙, 通過prototype 判斷構(gòu)造函數(shù)
- construct,通過構(gòu)造函數(shù)來判斷
- Object.prototype.toString()
一般項目中常用的判斷方式可能是使用typeof剖张,typeof null === "object" 是一個歷史遺留問題.
3 null 和 undefined 區(qū)別
兩者都是基本數(shù)據(jù)類型
undefined 在 JavaScript 中不是一個保留字派阱,這意味著可以使用 undefined 來作為一個變量名诬留,但是這樣的做法是非常危險的,它會 影響對 undefined 值的判斷。我們可以通過一些方法獲得安全的 undefined 值文兑,比如說 void 0傀广。
但是現(xiàn)在大多數(shù)瀏覽器應(yīng)該是都無法使用undefined作為一個變量名。
5 intanceof 操作符的實(shí)現(xiàn)原理及實(shí)現(xiàn)
intanceof 是判斷構(gòu)造函數(shù)的prototype是否存在于對象的原型鏈上彩届,一直找到Object.prototype.
知道了原理伪冰,實(shí)現(xiàn)就很簡單了,就是無限循環(huán)遞歸
function myInstanceOf(left:object, right:object) {
// Object.getPrototypeOf() 返回對象的原型
const leftPrototype = Object.getPrototypeOf(left);
const rightPrototype = right.prototype;
while(leftPrototype) {
if(leftPrototype === rightPrototype) return true;
if(!rightPrototype) return false;
leftPrototype = Object.getPrototypeOf(leftPrototype);
}
return fasle;
}
6 Object.is() 與比較操作符 “===”樟蠕、“==” 的區(qū)別?
=== 判斷兩邊類型和值都相等才返回true
== 會進(jìn)行隱士類型轉(zhuǎn)換贮聂,轉(zhuǎn)換之后才判斷,項目中不推薦==進(jìn)行判斷
Object.is() 基本上和===使用類似寨辩,這兩者的區(qū)別在于如何判斷+0和-0吓懈,以及NaN的處理
console.log(+0 === -0); //true
console.log(Object.is(+0, -0)); //false
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); //true
console.log(Number.NaN === Number.NaN); // false
console.log(Object.is(Number.NaN, Number.NaN)); // true
console.log(NaN === Number.NaN); // false
console.log(Object.is(NaN, Number.NaN)); // true
7 什么是BigInt
JavaScript 中 Number.MAX_SAFE_INTEGER 表示最大安全數(shù)字,計算 結(jié)果是 9007199254740991靡狞,即在這個數(shù)范圍內(nèi)不會出現(xiàn)精度丟失(小 數(shù)除外)耻警。
8 如何判斷一個對象是一個空對象
function isEmptyObject(obj={}) {
return Object.keys(obj).length > 0;
}
console.log(isEmptyObject({}));
console.log(isEmptyObject({'a':1}));
9 new 一個類的時候發(fā)生了什么?
- 創(chuàng)建一個對象
- 把該對象的proto指向類的原型
- 使用apply執(zhí)行構(gòu)造函數(shù)甸怕,如果返回是一個對象就返回甘穿,如果不是就返回剛才創(chuàng)建的對象。
10 Proxy 可以實(shí)現(xiàn)什么功能
在 Vue3.0 中通過 Proxy 來替換原本的 Object.defineProperty 來實(shí)現(xiàn)數(shù)據(jù)響應(yīng)式梢杭。
之所以 Vue3.0 要使用 Proxy 替換原本的 API 原因在于 Proxy 無需一層層遞歸為每個屬性添加代理温兼,一次即可完成以上操作,性能上更好武契,并且原本的實(shí)現(xiàn) 有一些數(shù)據(jù)更新不能監(jiān)聽到募判,比如數(shù)組的push和pop等,但是 Proxy 可以完美監(jiān)聽到任何方式的數(shù)據(jù)改變咒唆,唯一缺陷就是瀏覽器的兼容性不好届垫。
Proxy是Es6中添加的,基本使用如下:
const target1 = {
message1: "hello",
message2: "everyone"
};
const handler2 = {
// target 原始對象全释,這里是指target1装处,prop傳入的屬性,receiv // er表示是接受的對象恨溜,這里是handle2
get(target, prop, receiver) {
return "world";
}
};
const proxy2 = new Proxy(target1, handler2);
11 Js 文件延遲加載方法有哪些符衔?
- defer:js文件下載會和瀏覽器的解析同時執(zhí)行,當(dāng)瀏覽器解析完畢后糟袁,然后再執(zhí)行js文件。
- async:js文件下載會和瀏覽器的解析同時執(zhí)行躺盛,當(dāng)js文件下載完畢后项戴,會立即執(zhí)行js文件。
- 如果沒有defer和async槽惫,文件會立即下載和立即執(zhí)行周叮,并且會阻塞瀏覽器的解析辩撑。
12 ES6 模塊與 CommonJS 模塊的區(qū)別
相同點(diǎn):
ES6和CommonJS都可以對引入的對象內(nèi)部重新賦值
不同點(diǎn):
CommonJS模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用仿耽;
也就是說ComonnJS是引用的一個值的拷貝合冀,如果當(dāng)我們引入之后,修改了原來文件的內(nèi)容项贺,我們引用的值不會改變君躺,比如下面的例子,test.js中輸出的值都是3,3
// lib.js
let counter = 3;
function incCounter() {
counter++;
}
module.exports = {
counter: counter,
incCounter: incCounter,
};
// test.js
const mod = require("./lib");
console.log(mod.counter); // 3
mod.incCounter();
console.log(mod.counter); // 3
ES6是導(dǎo)入的引用开缎,有點(diǎn)類似指針棕叫,所以當(dāng)引入的文件內(nèi)容改變后,會跟著改變奕删。
可以看下下面的例子
// lib.js
export let counter = 3;
export function incCounter() {
counter++;
}
// test.js
export let counter = 3;
export function incCounter() {
counter++;
}
13 for...in 和 for...of 的區(qū)別
for...of 是 ES6 新增的遍歷方式俺泣,允許遍歷一個含有 iterator 接口 的數(shù)據(jù)結(jié)構(gòu)(數(shù)組、對象等)并且返回各項的值
for...in 主要是遍歷對象完残,并且會沿著原型鏈向上查找
for... in 遍歷數(shù)組的時候伏钠,返回的是數(shù)組下標(biāo)
for... of 遍歷數(shù)組的時候,返回的是數(shù)組的值
例子如下:
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
const iterable = [3, 5, 7];
iterable.foo = 'hello';
for (const i in iterable) {
// logs "0", "1", "2", "foo", "arrCust om", "objCustom"
console.log(i);
}
for (const i in iterable) {
if (Object.hasOwn(iterable, i)) {
// logs "0", "1", "2", "foo"
console.log(i);
}
}
for (const i of iterable) {
// logs 3, 5, 7
console.log(i);
}
for...of 不能遍歷對象谨设,如果想要遍歷對象贝润,可以使用如下代碼
const obj = {
a: 1,
b: 2,
};
for (let [key, value] of Object.entries(obj)) {
console.log(key, value);
}
14 原型和原型鏈的經(jīng)典圖
15 this的理解
- 當(dāng)一個函數(shù)不是一個對象的屬性時,直接作為函數(shù)來調(diào)用時铝宵,this 指向全局對象打掘。
- 如果一個函數(shù)作為一個對象的方法來調(diào)用時, this 指向這個對象鹏秋。
- 如果一個函數(shù)用 new 調(diào)用時尊蚁,函數(shù)執(zhí)行 前會新創(chuàng)建一個對象,this 指向這個新創(chuàng)建的對象侣夷。
- apply 横朋、 call 和 bind 調(diào)用模式, 這三個方法都可以顯示的指定調(diào)用函數(shù)的 this 指向。其中 apply 方法接收兩個參數(shù): 一個是 this 綁定的對象百拓,一個是參數(shù)數(shù)組琴锭。call 方法接收的參數(shù), 第一個是 this 綁定的對象衙传,后面的其余參數(shù)是傳入函數(shù)執(zhí)行的參數(shù)决帖。 也就是說,在使用 call() 方法時蓖捶,傳遞給函數(shù)的參數(shù)必須逐個列舉出來地回。bind 方法通過傳入一個對象,返回一個 this 綁定了傳入對 象的新函數(shù)。這個函數(shù)的 this 指向除了使用 new 時會被改變刻像,其 他情況下都不會改變畅买。
- 箭頭函數(shù)的this指向定義的時候,最外層的this
16 內(nèi)存泄露的情況
- 全局變量
- 閉包
- dom元素的引用细睡,當(dāng)dom被刪除后谷羞,引用沒有清空。
本文由mdnice多平臺發(fā)布