我們將深入探討以下主題:
這是一種 JavaScript 機制,其中變量和函數的聲明在代碼執行之前被移動到其作用域的頂部。
console.log(a) // undefined
var a = 10;
console.log(a) // 引用錯誤,時間死區。
let a = 10;
console.log(getNum());
function getNum(){
return 2*2;
}
console.log(getNum()); // 引用錯誤,getNum2 未定義:對 let 也一樣,TDZ
const getNum = () => {
return 2*2;
}
console.log(getNum4()); // 型別錯誤:getNum4 不是一個函數
var getNum4 = () => {
return 2*2;
}
以上僅變量被提升,而不是函數。
這是變量被定義和初始化之間的作用域/區塊的期間。
何時發生?
函數聲明 (Function Dec.):使用 function 關鍵字定義的函數。
函數表達式 (Function Exp.):當一個函數被賦值給一個變量。
當您需要在作用域的任何地方訪問函數時,使用函數聲明。<br>
當需要更好地控制函數的使用時,使用函數表達式。
淺拷貝 (Shallow Copy):僅複製頂層屬性,對於嵌套對象則傳遞引用。
let obj1 = { name: "Jayant", address: { city: "Delhi" } };
let obj2 = {...obj1};
obj2.address.city = "Gurugram";
console.log(obj1);
console.log(obj2);
// 兩者輸出相同
// {
// "name": "Jayant",
// "address": {
// "city": "Gurugram"
// }
// }
淺拷貝的其他方法
Object.assign()
展開運算子
切片運算子
[新的陣列在嵌套對象的情況下將包含引用]連接運算子
深拷貝 (Deep Copy):複製所有屬性。
let obj1 = { name: "Jayant", address: { city: "Delhi" } };
// 創建深拷貝
let obj2 = JSON.parse(JSON.stringify(obj1));
obj2.address.city = "Mumbai"; // ✅ 只改變 obj2
console.log(obj1); // { name: "Jayant", address: { city: "Delhi" } }
console.log(obj2); // { name: "Jayant", address: { city: "Mumbai" } }
深拷貝的其他方法
基於遞歸的自定義深拷貝函數
Object.assign()
這是一個 JavaScript 方法,用於將一個或多個對象的屬性複製到另一個對象中。
我們可以使用展開運算子來做相同的事情
。
// 語法:創建淺拷貝
Object.assign(<target>,...sources)
// 示例
let obj1 = {
name:"Jayant"
}
let obj2 = {
status:"single"
}
// 如果兩個對象有相同的屬性,最後一個對象的值將覆蓋先前的值。
let obj3 = Object.assign({},obj1,obj2);
切片 (Slice) 用於提取陣列的一部分。<br>
切片會創建淺拷貝
。<br>
插入 (Splice) 用於添加/移除陣列中的元素。
// 切片:arr.slice(start,end);
// 結尾是排除的,不會包含
const arr = [1,2,3,4,5,6,7];
const newArray = arr.slice(1,4);
console.log(newArray); // [2,3,4 ]
console.log(arr.slice(-2)); // [6,7] , 獲取最後 2 個元素
// 插入:arr.splice(start,deleteCount,...items);
const itemsToAdd = [2,3,4,5,6,7];
const newArr = [1,2,3,4,5,6,7];
console.log(newArr.splice(1,7,...itemsToAdd)); //[2,3,4,5,6,7]
console.log(newArr); // [1,2,3,4,5,6,7];
const newArr2 = [1,2,3,4,5,6,7];
console.log(newArr2.splice(-2)); // [6,7] // 移除最後 2 個元素
console.log(newArr2); // [1,2,3,4,5]
ForEach 和 Map 不支持提前返回,如果您想提前返回,可以使用 some、every、reduce 或 for of 迴圈。
[1,2,3,4,5,6,7].forEach((el)=>{
if(!el){
break; // 這會報錯,對於 Map 也是如此
}
console.log(el)
})
這是一個代碼執行的環境。<br>
它有 2 種類型:<br>
1) 全局執行上下文 (Global EC)
2) 函數執行上下文 (Function EC)
全局執行上下文
- 當 JS 文件運行時,首先運行的執行上下文。它包含全局變量和函數以及詞法環境。當程序停止時將被移除。
這是編寫代碼以使舊瀏覽器兼容新功能的行為。
舊版瀏覽器(如 Internet Explorer)不支持 Array.includes()。為了添加這一功能,我們可以編寫一個 polyfill。
Array.includes() 的 Polyfill
if (!Array.prototype.includes) {
Array.prototype.includes = function (element) {
return this.indexOf(element) !== -1;
};
}
通常我們只給回調傳遞一個參數,但內部來說,map() 提供 4 個參數給回調函數。
// 在 forEach 的情況下,陣列也可以訪問
arr.map((value,index,array,this)=>{})
const arr = [1,2,3,4,5,65];
console.log(arr.map((val)=>{
console.log(arr[0]);
return val;
})); // arr 已經在作用域中,因此有什麼需求?
稀疏陣列 - 缺少元素的陣列
const arr = [1,2,,5,6,,7,8,9] // 稀疏陣列
// 預設情況下,map 跳過這些並且不會調用回調函數。
// 空位保留在陣列中
console.log(arr.map((val)=>{
if(!val){
return 0;
}
return val*2
})) // [2, 4, 6, 8, 10, empty, 130]
如果您想在稀疏陣列中提供缺省值而不是空值,可以利用 forEach 或展開運算子進行。
const arr = [1,2,,5,6,,7,8,9];
// 使用展開運算子將稀疏陣列轉換成包含明確 undefined 值的密集陣列 || 也可以使用 forEach。
console.log([...arr].map((val,index,arr)=>{
if(!val){
return arr[index-1] || 0;
}
return val*2
})) // [2, 4, 2, 10, 12, 6, 14, 16, 18]
map() 在執行之前設置元素的範圍:指在第一次回調執行之前,正在被回調處理的元素是確定的。
自動將一種類型轉換為另一種類型。<br>
這主要以三種方式發生:
隱式強制轉換 → JS 自動轉換類型。<br>
console.log(10+"2"); // [串接]
console.log(10-"2"); // [轉換] - 轉為數字
console.log(10*"2"); // [轉換] - 轉為數字
console.log(10/"2"); // [轉換] - 轉為數字
console.log(true+1) // true 轉換為數字得到 1
// false -> 0
console.log(null+undefined) // NaN
// null -> 0
// undefined -> NaN
console.log(null + 10); // 10 (null → 0)
console.log(undefined + 10); // NaN (undefined → NaN)
const obj = { name: "John" };
console.log(String(obj)); // "[object Object]"
console.log(obj + ""); // "[object Object]"
// [] -> ""
console.log([] + 2); // "2" (陣列 → 空字串 → 串接)
console.log([] - 2); // -2 (陣列 → 空字串 → 0 - 2 = -2)
console.log([1] + [2]); // "12"
顯式強制轉換 → 我們手動使用函數轉換類型。<br>
抽象操作 → JS 中類型轉換的內部規則。
原文出處:https://dev.to/jay818/javascript-basics-for-a-senior-dev-1lob