1窖逗、ES6版本引入了哪些特性金砍?(全部跟著寫一遍局蚀,理解)
1.1let 和 const 關鍵字。
1.2箭頭函數(shù)以及默認參數(shù)恕稠。
1.3模板字符串琅绅。
1.4解構賦值。
1.5Promise
1.6模塊化
1.7擴展運算符
1.8Set 和 Map
1.1let 和 const 關鍵字
//let 和 const 關鍵字鹅巍。
const name = '劉玉潔'
let sex = '女'
1.2箭頭函數(shù)以及默認參數(shù)
//箭頭函數(shù)以及默認參數(shù)
const fnOne = (age=19) => {
return `姓名: ${name},性別: ${sex},年齡${age}`
}
fnOne() // 姓名: 劉玉潔,性別: 女,年齡19
1.3模板字符串
//多行字符串 \n\換行
`
姓名:劉玉潔\n\
性別:女\n\
年齡:25
`
//輸出:
//姓名:劉玉潔
//性別:女
//年齡:25
1.4解構賦值
//解構賦值
// 從數(shù)組中提取值并賦給變量
let [a,b,c] = [1,2,3];
console.log(a) // 1
console.log(b) // 2
console.log(c) // 3
// 交換變量的值
var x = 1;
var y = 2;
[x, y] = [y, x];
console.log(x); // 輸出 2
console.log(y); // 輸出 1
// 從對象中提取值并賦給變量
var {name, age} = {name: "Alice", age: 25};
console.log(name); // 輸出 "Alice"
console.log(age); // 輸出 25
// 為變量指定新的名稱
var {name: n, age: s} = {name: "Alice", age: 25};
console.log(n); // 輸出 "Alice"
console.log(s); // 輸出 25
1.5Promise
const promise = new Promise((resolve,reject)=>{
if(true){
resolve('成功')
}else{
reject('失敗')
}
})
promise.then(res=>{
// 成功回調
console.log(res)
},(reason)=>{
// 失敗回調, 執(zhí)行當前失敗回調,catch回調將不會執(zhí)行
console.log('reason: '+reason)
}).catch(reject=>{
// 失敗回調
console.log(reject)
}).finally(()=>{
// promise 成功或失敗都會執(zhí)行finally回調
console.log('finally')
})
//Promise.all方法:
//接受一個Promise數(shù)組作為參數(shù)千扶,并返回一個新的Promise。當所有的Promise都變?yōu)槌晒顟B(tài)時昆著,新的Promise的狀態(tài)才會變?yōu)槌晒Α? const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('1')
}, 500);
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('2')
}, 2000);
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('3')
}, 1000);
})
var promises = [promise1, promise2, promise3];
Promise.all(promises).then(function (values) {
console.log(values)
// 處理所有Promise的成功狀態(tài) 只要有一個promise沒有返回县貌,或者報錯就不會返回
}).catch(function (reason) {
console.log('reason'+reason)
// 處理第一個Promise的失敗狀態(tài)
});
//Promise.race方法:接受一個Promise數(shù)組作為參數(shù),并返回一個新的Promise凑懂。當任意一個Promise變?yōu)槌晒蚴顟B(tài)時,新的Promise的狀態(tài)就會變?yōu)橄鄳臓顟B(tài)梧宫。
// 注意:1.如果同時有一個成功一個失敗接谨,會返回成功狀態(tài)
Promise.race(promises).then(function (value) {
console.log(value)
// 處理第一個Promise的狀態(tài)
}).catch(function (reason) {
console.log('reason',reason)
// 處理第一個Promise的狀態(tài)
}).finally(() => {
// promise 成功或失敗都會執(zhí)行finally回調(返回第一個)
console.log('finally')
})
1.6模塊化 export import
// init.js文件聲明方法
const time = ()=>{
return new Date()
}
export default time
// vue 導入使用
import time from './init.js'
time()
1.7擴展運算符
//JavaScript中的擴展運算符(spread operator)可以用于展開數(shù)組或對象。它使用三個點(...)作為語法塘匣,可以將數(shù)組或對象的元素展開為獨立的參數(shù)或屬性脓豪。
在數(shù)組中使用擴展運算符可以將一個數(shù)組展開為多個獨立的元素,例如:
const arr1 = [1, 2, 3]; const arr2 = [...arr1, 4, 5, 6]; console.log(arr2); // [1, 2, 3, 4, 5, 6]
在對象中使用擴展運算符可以將一個對象的屬性展開到另一個對象中忌卤,例如:
const obj1 = { a: 1, b: 2 }; const obj2 = { ...obj1, c: 3, d: 4 }; console.log(obj2); // { a: 1, b: 2, c: 3, d: 4 }
1.8Set 和 Map(注:Set和Map都是可迭代的扫夜,可以使用for...of循環(huán)遍歷它們的元素)
//Set是一種類似于數(shù)組的數(shù)據(jù)結構,它的成員是唯一且無序的驰徊。Set中的元素不會重復笤闯,可以用來去除數(shù)組中的重復元素。Set提供了一些常用的方法棍厂,如add颗味、delete、has等牺弹。
const set = new Set();
set.add(1).add(2).add(3).add(4).add(2).add(3).add(1)
console.log([...set]) // [1.2.3.4]
//Map是一種鍵值對的數(shù)據(jù)結構浦马,它類似于對象,但鍵可以是任意類型张漂。Map提供了一些常用的方法晶默,如set、get航攒、has等磺陡。
const map = new Map(); map.set('name', 'John'); map.set('age', 25);
console.log(map.get('name')); // John
console.log(map.has('age')); // true
map.delete('age');
console.log(map); // Map { 'name' => 'John' }
2、var、const 和 let 的主要區(qū)別是什么仅政?(變量提升垢油,作用域,重復聲明圆丹,變量賦值滩愁,聲明時初始化代碼走一遍)
變量提升:var聲明的變量存在變量提升,即在聲明之前就可以使用變量辫封。而const和let聲明的變量不存在變量提升硝枉,必須在聲明之后才能使用變量。
作用域:var聲明的變量存在函數(shù)作用域倦微,即在函數(shù)內(nèi)部聲明的變量在函數(shù)外部是不可訪問的妻味。而const和let聲明的變量存在塊級作用域,即在塊(如if語句欣福、for循環(huán)等)內(nèi)部聲明的變量在塊外部是不可訪問的责球。
重復聲明:var可以重復聲明同一個變量,而const和let不允許重復聲明同一個變量拓劝。
變量賦值:var和let聲明的變量可以重新賦值雏逾,而const聲明的變量是常量,不允許重新賦值郑临。
聲明時初始化:var聲明的變量和let聲明的變量可以不進行初始化栖博,而const聲明的變量必須進行初始化。
3.什么是promise和 async-await
Promise是JavaScript中用于處理異步操作的對象厢洞。它可以將異步操作封裝成一個Promise對象仇让,通過then方法來處理異步操作的結果。Promise對象有三種狀態(tài):pending(進行中)躺翻、fulfilled(已成功)和rejected(已失斏ミ础)。當異步操作完成時获枝,Promise對象的狀態(tài)會從pending變?yōu)閒ulfilled或rejected蠢正,并調用相應的回調函數(shù)。
async/await是ES8中新增的用于處理異步操作的語法糖省店。它基于Promise嚣崭,可以使異步代碼看起來像同步代碼,更加易讀和易寫懦傍。async函數(shù)是一個返回Promise對象的函數(shù)雹舀,可以在函數(shù)內(nèi)部使用await關鍵字來等待一個Promise對象的狀態(tài)變?yōu)閒ulfilled,并返回異步操作的結果粗俱。
async function fn() {
const data = await new Promise(function (resolve, reject) {
setTimeout(() => {
console.log('111111111')
}, 1000);
})
console.log('22222222')
}
fn() // 一秒后輸出 111111 2222222
注意:
1.await 只能在申明了async 的函數(shù)里面使用
2.await 后面必須跟隨一個promise 如果跟隨不是promise 會被自動轉換為立即執(zhí)行resolved的Promise對象说榆,并將相應的值作為結果返回。
4.什么是閉包?
1.閉包可以理解為一個函數(shù)和其相關的引用環(huán)境的組合
2.閉包的作用:閉包可以用來創(chuàng)建私有變量和方法签财,實現(xiàn)模塊化的編程串慰。
3.閉包的弊端:內(nèi)存泄漏,因為閉包會持有外部函數(shù)的變量和引用唱蒸,導致這些變量無法被垃圾回收邦鲫。因此,在使用閉包時需要注意內(nèi)存的管理神汹。
5. BOM 是什么庆捺?
BOM,也稱為瀏覽器對象模型屁魏,用作瀏覽器的交互介質滔以。默認對象是窗口,所有函數(shù)都可以直接調用氓拼,也可以通過指定窗口來調用你画。History、Screen桃漾、location撬即,是 Window 的不同屬性。
console.log(window)
6. DOM 是什么呈队?
Document Object Model,俗稱DOM唱歧,代表HTML文檔宪摧,它用于更改 HTML 文檔的內(nèi)容。
console.log(document)
7.js數(shù)據(jù)克隆方法
//1.JSON.parse(JSON.stringify(obj));
const copyobj = JSON.parse(JSON.stringify(obj)); // 函數(shù)不能clone
//2....運算符
const copyobj = { ...obj }; // 只能clone 第一層
//3.structuredClone方法
const copyobj = window.structuredClone(obj); // 函數(shù)不能clone
//4.創(chuàng)建一個函數(shù)克隆所有元素
function clone(obj) {
var o;
if (typeof obj == "object") {
if (obj === null) {
o = null;
} else {
if (obj instanceof Array) {
o = [];
for (var i = 0, len = obj.length; i < len; i++) {
o.push(clone(obj[i]));
}
} else {
o = {};
for (var j in obj) {
o[j] = clone(obj[j]);
}
}
}
} else {
o = obj;
}
return o;
}
8.如何判斷數(shù)據(jù)類型
8.1 typeof:用于判斷基本數(shù)據(jù)類型颅崩,返回字符串類型的值
typeof undefined; // "undefined"
typeof true; // "boolean"
typeof 123; // "number"
typeof "hello"; // "string"
typeof BigInt(123); // "bigint"
typeof Symbol("foo"); // "symbol"
typeof {}; // "object"
typeof []; // "object"
typeof null; // "object"
8.2 instanceof:用于判斷對象的類型几于,返回布爾值。
const arr = [1, 2, 3];
arr instanceof Array; // true
const obj = { name: "Tom" };
obj instanceof Object; // true
function Person(name) {
this.name = name;
}
const person = new Person("Jack");
person instanceof Person; // true
8.3Object.prototype.toString.call():可以判斷所有的類型沿后,返回字符串類型的值沿彭。
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call(123); // "[object Number]"
Object.prototype.toString.call("hello"); // "[object String]"
Object.prototype.toString.call(BigInt(123)); // "[object BigInt]"
Object.prototype.toString.call(Symbol("foo")); // "[object Symbol]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call([]); // "[object Array]"
9.數(shù)組的常用方法
const list = [1,2,3 ,4];
// 數(shù)組后面新增
list.push(1)
console.log(list) // [1, 2, 3, 4, 1]
// 刪除數(shù)組最后面一個
list.pop()
console.log(list) // [1, 2, 3]
//數(shù)組前面新增
list.unshift(5,34)
console.log(list) // [5,34,1, 2, 3, 4]
//刪除數(shù)組最前面一個元素
list.shift()
console.log(list) // [ 2, 3, 4]
// splice 改變原數(shù)組 , 下標為0開始,截取長度為1,其余參數(shù)都為新增參數(shù)
list.splice(0,1,5)
console.log(list) //[5,1,2,3]
// slice 原數(shù)組不變 , 下標1開始(包括),截取到下標3(不包括)
const newList = list.slice(1,3)
console.log(newList) //[2, 3]
// reverse 改變元數(shù)組 反轉數(shù)組
list.reverse()
console.log(list) //[4, 3, 2, 1]
// join 數(shù)組轉字符串
const newList = list.join(',');
console.log(newList) //1,2,3,4
// forEach 循環(huán)
list.forEach((item,index)=>{
list[index] = ++item
})
console.log(list) //[2, 3, 4, 5]
// map 不改變原數(shù)組,生成新數(shù)組
const newList = list.map((item, index) => ++item)
console.log(newList) //[2, 3, 4, 5]
// filter 過濾返回匹配的所有項生成數(shù)組
const newList = list.filter(item => item > 3)
console.log(newList) //[4]
// find 返回匹配的第一項
const newList = list.find(item => item > 2)
console.log(newList) //3
// every 數(shù)組元素全部滿足條件返回true
const newList = list.every(item => item >=1)
console.log(newList) //true
// some 數(shù)組元素有一個滿足條件返回true
const newList = list.some(item => item >=1)
console.log(newList) //true
// reduce 累加器,傳入一個函數(shù)和初始值
// 函數(shù)里面有兩個值
// preValue 累加后的值
// curValue 每一項
const newList = list.reduce((preValue, curValue) =>{
return preValue+curValue
},10)
console.log(newList) //20
10.數(shù)組去重的幾種方法
10.1 new Set 去重
const list = [1, 2, 3, 4, 1, 2, 3, 4, 5];
// new Set 去重
const oneList = [...new Set(list)];
console.log(oneList);
10.2 filter 去重
const list = [1, 2, 3, 4, 1, 2, 3, 4, 5];
// filter 去重
const newList = list.filter((item, index, array) => {
return array.indexOf(item) === index;
});
console.log(newList);
10.3 reduce+includes 去重
const twoList = list.reduce((array, b) => {
return array.includes(b) ? [...array] : [...array, b];
}, []);
console.log(twoList);
10.4 reduce+indexOf 去重
const twoList = list.reduce((array, b) => {
const bol = !!~array.indexOf(b);
return bol ? [...array] : [...array, b];
}, []);
console.log(twoList);
10.5 reduce 去重數(shù)組對象
const list = [
{ a: 1, b: 2 },
{ a: 1, b: 2 },
{ a: 1, b: 3 },
];
const twoList = list.reduce((array, b) => {
const bol = !!~JSON.stringify(array).indexOf(JSON.stringify(b));
return bol ? [...array] : [...array, b];
}, []);
console.log(twoList); // [ { a: 1, b: 2 }, { a: 1, b: 3 }]
11.bind、call尖滚、apply 區(qū)別
總結:
bind 方法返回一個新的函數(shù)喉刘,并可以預先綁定上下文和參數(shù)。
call 方法立即調用函數(shù)漆弄,并傳遞指定的上下文和參數(shù)作為參數(shù)睦裳。
apply 方法立即調用函數(shù),并傳遞指定的上下文以及參數(shù)數(shù)組作為參數(shù)撼唾。
11.1 bind 方法會創(chuàng)建一個新函數(shù)廉邑,將其綁定到指定的對象,并返回這個新函數(shù)。新函數(shù)可以在之后的調用中作為普通函數(shù)被調用蛛蒙,也可以作為構造函數(shù)使用(使用 new 運算符)糙箍。bind 方法可以傳遞參數(shù)給原函數(shù),這些參數(shù)會預先傳入到新函數(shù)中牵祟。 例如:
const obj = { name: 'John' };
function getName() {
console.log(this.name);
}
const boundGetName = getName.bind(obj);
boundGetName(); // 輸出:John
11.2 call 方法和 apply 方法都可以立即調用一個函數(shù)深夯,并且可以顯式地設置函數(shù)執(zhí)行時的上下文(this 值)。唯一的區(qū)別在于傳遞參數(shù)的方式不同课舍。
11.2.1call 方法接受一個指定的上下文對象和一系列參數(shù)作為參數(shù)塌西,并將函數(shù)立即執(zhí)行。 例如:
const obj = { name: 'Sarah' };
function sayHello(message) {
console.log(`${message}, ${this.name}!`);
}
sayHello.call(obj, 'Hello'); // 輸出:Hello, Sarah!
11.2.2 apply 方法也接受一個指定的上下文對象和一個參數(shù)數(shù)組作為參數(shù)筝尾,并將函數(shù)立即執(zhí)行捡需。不同的是,參數(shù)被傳遞為數(shù)組筹淫。 例如:
const obj = { name: 'Emily' };
function sayHello(message) {
console.log(`${message}, ${this.name}!`);
}
sayHello.apply(obj, ['Hello']); // 輸出:Hello, Emily!
12 什么是js執(zhí)行上下文
JavaScript 執(zhí)行上下文(Execution Context)是 JavaScript 引擎在執(zhí)行代碼時創(chuàng)建的一個環(huán)境站辉。每當 JavaScript 代碼執(zhí)行時,都會創(chuàng)建一個執(zhí)行上下文损姜,并且這些執(zhí)行上下文被組織為一個執(zhí)行上下文棧(Execution Context Stack)饰剥。
每個執(zhí)行上下文包含了三個重要的組成部分:
1.變量對象(Variable Object):用于存儲變量和函數(shù)聲明。變量對象可以看作是當前上下文中的作用域鏈的一部分摧阅。在全局執(zhí)行上下文中汰蓉,變量對象被稱為全局對象(Global Object)。
2.作用域鏈(Scope Chain):用于解析變量和函數(shù)的訪問權限棒卷。它是由當前執(zhí)行上下文的變量對象以及其上層執(zhí)行上下文的變量對象構成的鏈式結構顾孽。
3.this 值(This Value):指向當前執(zhí)行上下文所屬的對象。
JavaScript 的執(zhí)行上下文可以包括全局執(zhí)行上下文(Global Execution Context)比规、函數(shù)執(zhí)行上下文(Function Execution Context)和 eval 函數(shù)執(zhí)行上下文若厚。
全局執(zhí)行上下文是最頂層的執(zhí)行上下文,它在代碼開始執(zhí)行時創(chuàng)建蜒什,全局變量和函數(shù)聲明都會被添加到全局執(zhí)行上下文的變量對象中测秸。
函數(shù)執(zhí)行上下文,在調用函數(shù)時創(chuàng)建灾常,每次函數(shù)調用都會創(chuàng)建一個新的函數(shù)執(zhí)行上下文霎冯,函數(shù)參數(shù)、局部變量和內(nèi)部函數(shù)都會被添加到函數(shù)執(zhí)行上下文的變量對象中岗憋。
eval 函數(shù)執(zhí)行上下文是通過 eval 函數(shù)執(zhí)行代碼時創(chuàng)建的肃晚,只有在代碼含有 eval 函數(shù)調用時才會生成 eval 函數(shù)執(zhí)行上下文。
當 JavaScript 引擎執(zhí)行代碼時仔戈,它會根據(jù)執(zhí)行上下文棧(Execution Context Stack)的順序依次執(zhí)行各個執(zhí)行上下文关串,當前執(zhí)行上下文執(zhí)行完成后拧廊,會彈出執(zhí)行上下文棧,并開始執(zhí)行上一個執(zhí)行上下文晋修,直到最后一個執(zhí)行上下文執(zhí)行完畢吧碾,整個代碼執(zhí)行過程結束。
通過理解和管理執(zhí)行上下文墓卦,我們可以更好地理解 JavaScript 代碼的執(zhí)行過程倦春,并且能夠正確地訪問和修改變量、了解作用域規(guī)則以及正確理解 this 的指向落剪。