好程式設計師web前端培訓分享JavaScript相關知識
好程式設計師web 前端培訓分享 JavaScript 相關知識 , 今天跟大家分享的是關於JavaScript 相關知識。正在從事 web 前端工作的小夥伴們來一起看看吧,希望能夠對大家有所幫助。
( 一 )JS 中基本型別和引用型別
JavaScript 的變數中包含兩種型別的值:基本型別值和引用型別值,在記憶體中的表現形式在於:前者是儲存在棧中的一些簡單的資料段,後者則是儲存在堆記憶體中的一個物件。
•基本型別值
在JavaScript 中基本資料型別有 String , Number , Undefined , Null , Boolean ,在 ES6 中,又定義了一種新的基本資料型別 Symbol ,所以一共有 6 種。
基本型別是按值訪問的,從一個變數複製基本型別的值到另一個變數後,這兩個變數的值是完全獨立的,即使一個變數改變了也不會影響到第二個變數。
let str1 = ' 你好 ';
let str2 = str1;
str2 = 'hello word'console.log(str2);//'hello word'
console.log(str1); //' 你好 '
•引用型別值
引用型別值是引用型別的例項,它是儲存在堆記憶體中的一個物件,引用型別是一種資料結構,最常用的是Object,Array,Function 型別,此外還有 Date,RegExp,Error 等。
在ES6 中提供了 Set,Map2 種新的資料結構。
( 二 )JS 中如何複製引用型別的
•基本型別和引用型別賦值的差異化
舉個例子:在下面程式碼中,只修改了obj1 中的 name 屬性,卻同時改變了 ob1 和 obj2 中的 name 屬性。
let obj1 = {'name': ' 小明 '};
let obj2 = obj1;obj2.name = ' 小蘭 ';
console.log(obj1); // {'name': ' 小明 '}
console.log(obj2); // {'name': ' 小明 '}
當變數複製引用型別值的時候,同樣和基本型別值一樣會將變數的值複製到新變數上,不同的是對於變數的值,它是一個指標,指向儲存在堆記憶體中的物件。
因為,在JS 中,堆記憶體中的物件無法直接訪問,必須要訪問這個物件在堆記憶體中的地址,然後再按照這個地址去獲得這個物件中的值。
( 三 ) 淺複製
在JS 中,如果屬性是基本型別,複製的就是基本型別的值 ; 如果屬性是引用型別,複製的就是記憶體地址 ; 所以如果其中一個物件改變了這個地址,就會影響到另一個物件。
下面是JavaScript 提供的淺複製方法:
Object.assign
ES6 中複製物件的方法,接受的第一個引數是複製的目標,剩下的引數是複製的源物件 ;
語法:Object.assign(target, ...sources)
let p = { 'name': 'hello word',};
let copyP = {};
Object.assign(copyP, p);
console.log(copyP);console.log(p);
Object.assign 是一個淺複製,它只是在根屬性 ( 物件的第一層級 ) 建立了一個新的物件,但是如果屬性的值是物件的話,只會複製一份相同的記憶體地址。
擴充套件運算子
利用擴充套件運算子可以在構造字面量物件時,進行克隆或者屬性複製。語法如下:
let cloneObj = { ...obj };
let obj = {'name': ' 星期一 ' , 'college': [' 星期二 ' , ' 星期三 ' , ' 星期四 ']}let obj2 = {...obj};
obj.name=' 不休息 ';//{'name': ' 不休息 ' , 'college': [' 星期二 ' , ' 星期三 ' , ' 星期四 ']}console.log(obj);//{'name': ' 星期一 ' , 'college': [' 星期二 ' , ' 星期三 ' , ' 星期四 ']}
console.log(obj2);
obj.college.push('Go');//{'name': ' 不休息 ' , 'college': [' 星期二 ' , ' 星期三 ' , ' 星期四 ']}
console.log(obj); //{'name': ' 不休息 ' , 'college': [' 星期二 ' , ' 星期三 ' , ' 星期四 ']}
console.log(obj2);
擴充套件運算子和Object.assign() 存在同樣的問題,對於值是物件的屬性無法完全複製成兩個不同物件 ;
但是如果屬性都是基本型別的值的話,使用擴充套件運算子更加簡潔。
( 四 ) 深複製
淺複製只在根屬性上在堆記憶體中建立了一個新的的物件,複製了基本型別的值,但是複雜資料型別也就是物件則是複製相同的地址。
而深複製則是將一個物件從記憶體中完整的複製一份出來,從堆記憶體中開闢一個新的區域存放新物件,且修改新物件不會影響原物件。
JSON.stringify
JSON.stringify() 是目前開發過程中最常用的深複製方式,原理是把一個物件序列化成為一個 JSON 字串,將物件的內容轉換成字串的形式再儲存在記憶體中,再用 JSON.parse() 反序列化將 JSON 字串變成一個新的物件。
舉個例子:
let obj = { name: ' 少帥 ', age: 18, friends: [' 阿大 ', ' 阿二 '], goodF: { name: ' 水果 ', age: 19, address: ' 上海 ', pets: [{name: ' 西瓜 '}, {name: ' 蘋果 '}]}, bir: new Date()};
let newObj = JSON.parse(JSON.stringify(obj));
obj.goodF.pets[0].name = ' 桔子 ';
console.log(newObj);console.log(obj);
使用JSON.stringify 實現深複製有幾點要注意:
1) 複製的物件的值中如果有函式 ,undefined,symbol ,經過 JSON.stringify() 序列化後的 JSON 字串中這個鍵值對會消失 ;
2) 無法複製不可列舉的屬性,無法複製物件的原型鏈
3) 複製 Date 引用型別會變成字串
4) 複製 RegExp 引用型別會變成空物件
5) 物件中含有 NaN 、 Infinity 和 -Infinity ,則序列化的結果會變成 null
遞迴實現深複製
具體實現如下:
/** * 輔助函式 , 判定是否是物件 * @param obj * @returns {boolean} */
function isObj(obj) { return obj instanceof Object;}
/** * 深複製 fromObj 面的所有屬性 / 值 , 到 toObj 物件裡面 * @param fromObj 複製物件 * @param toObj 目標物件 */
function deepCopyObj2NewObj(fromObj, toObj) {
for (let key in fromObj) {
if(fromObj.hasOwnProperty(key)){
let fromValue = fromObj[key]; // 如果是值型別,那麼就直接複製賦值
if (!isObj(fromValue)) {
toObj[key] = fromValue;
} else { // 如果是引用型別,那麼就再呼叫一次這個方法, // 去內部複製這個物件的所有屬性 // fromValue 是什麼型別 , 建立一個該型別的空物件
let tmpObj = new fromValue.constructor;
// console.log(tmpObj); // debugger;
deepCopyObj2NewObj(fromValue, tmpObj);
toObj[key] = tmpObj;
}
}
}}
( 五 ) 總結
1) 在日常開發中一般並不需要複製很多特殊的引用型別,深複製物件使用 JSON.stringify 是最直接和簡單的方法。
2) 實現一個完整的深複製是非常複雜的 , 需要考慮到很多邊界情況。對於特殊的引用型別有複製需求的話,建議藉助第三方完整的庫 , 例如 lodash.js 。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913864/viewspace-2706174/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師web前端培訓分享學習JavaScript程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享JavaScript框架J程式設計師Web前端JavaScript框架
- 好程式設計師web前端培訓分享JavaScript學習指南程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享CSS基礎知識學習程式設計師Web前端CSS
- 好程式設計師web前端培訓分享Javascript中原型屬性程式設計師Web前端JavaScript原型
- 好程式設計師web前端培訓分享JavaScript基礎語法程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享九個JavaScript小技巧程式設計師Web前端JavaScript
- 好程式設計師web前端培訓分享面試題Session、Cookie基礎知識程式設計師Web前端面試題SessionCookie
- 好程式設計師web前端培訓分享JavaScript學習筆記Promise程式設計師Web前端JavaScript筆記Promise
- 好程式設計師web前端培訓分享JavaScript學習筆記cookie程式設計師Web前端JavaScript筆記Cookie
- 好程式設計師web前端培訓分享JavaScript學習筆記SASS程式設計師Web前端JavaScript筆記
- 好程式設計師JavaScript分享ES6相關知識程式設計師JavaScript
- 好程式設計師web前端分享Cookie知識程式設計師Web前端Cookie
- 好程式設計師web前端分享web前端入門知識程式設計師Web前端
- 好程式設計師web前端培訓分享JavaScript學習筆記之設計模式程式設計師Web前端JavaScript筆記設計模式
- 好程式設計師web前端培訓分享怎樣學好css?程式設計師Web前端CSS
- 好程式設計師分享Web前端知識之HTML程式設計師Web前端HTML
- 好程式設計師web前端培訓分享如何講清楚Promise?程式設計師Web前端Promise
- 好程式設計師Web前端培訓分享如何講清楚this指向?程式設計師Web前端
- 好程式設計師web前端培訓分享Vue面試題程式設計師Web前端Vue面試題
- 好程式設計師web前端培訓分享HTML DOM節點程式設計師Web前端HTML
- 好程式設計師web前端培訓分享HTML DOM簡介程式設計師Web前端HTML
- 好程式設計師web前端培訓分享CSS定位的教程程式設計師Web前端CSS
- 好程式設計師web前端教程分享web前端基礎知識程式設計師Web前端
- 好程式設計師web前端培訓分享JavaScript學習筆記分支結構程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享JavaScript學習筆記之正則程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓分享JavaScript學習筆陣列的排序程式設計師Web前端JavaScript陣列排序
- 好程式設計師web前端培訓分享JavaScript學習筆記之陣列程式設計師Web前端JavaScript筆記陣列
- 好程式設計師web前端培訓JavaScript學習筆記DOM程式設計師Web前端JavaScript筆記
- 好程式設計師web前端培訓JavaScript學習筆記--jQuery程式設計師Web前端JavaScript筆記jQuery
- 好程式設計師Web前端分享一些小知識!程式設計師Web前端
- 好程式設計師Web前端培訓分享jQuery面試題梳理程式設計師Web前端jQuery面試題
- 好程式設計師web前端培訓分享node學習筆記程式設計師Web前端筆記
- 好程式設計師web前端培訓分享FormData 簡單介紹程式設計師Web前端ORM
- 好程式設計師web前端培訓分享JavaScript學習筆記函式進階程式設計師Web前端JavaScript筆記函式
- 好程式設計師web前端培訓分享JavaScript學習筆記之ES5程式設計師Web前端JavaScript筆記
- 好程式設計師Python培訓分享Python爬蟲相關框架程式設計師Python爬蟲框架
- 好程式設計師Java培訓分享JDK工具條知識點程式設計師JavaJDK