js中實現深淺拷貝
值型別和引用型別
說起深淺拷貝,我覺得需要理清楚 值型別
和 引用型別
值型別
所謂 值型別
就是 undefined
,null
,number
, string
,boolean
等五種基本資料型別, 應該還有一個Symbol
型別。
值型別的資料儲存在棧記憶體中
在 值型別
中修改值相當於重新在棧記憶體中開闢了一個新的儲存空間,類似於:
用程式碼來解釋就是:
var num1 = 5
var num2 = num1
值型別的值不可改變
javascript中的原始值(undefined、null、布林值、數字和字串)與物件(包括陣列和函式)有著根本區別。原始值是不可更改的:任何方法都無法更改(或“突變”)一個原始值。對數字和布林值來說顯然如此 —— 改變數字的值本身就說不通,而對字串來說就不那麼明顯了,因為字串看起來像由字元組成的陣列,我們期望可以通過指定索引來假改字串中的字元。實際上,javascript 是禁止這樣做的。字串中所有的方法看上去返回了一個修改後的字串,實際上返回的是一個新的字串值。
var str = 'abc'
str[0] = 'd'
console.log(str) // 'abc'
值型別的比較是對值的比較
值型別的比較是值的比較,只要它們的值相等就認為他們是相等的
var a = 1;
var b = 1;
console.log(a === b);//true
引用型別
引用型別的資料存放在堆記憶體中
引用型別的值存放在堆記憶體中,變數儲存的是一個存放在棧記憶體,指向堆記憶體的指標。
var person1 = {name:'jozo'};
var person2 = {name:'xiaom'};
var person3 = {name:'xiaoq' };
引用型別的值可以改變
引用型別是可以直接改變其值的
var a = [1,2,3];
a[1] = 5;
console.log(a[1]); // 5
引用型別的比較是引用的比較
所以每次我們對 js 中的引用型別進行操作的時候,都是操作其物件的引用(儲存在棧記憶體中的指標),所以比較兩個引用型別,是看其的引用是否指向同一個物件。
var a = [1,2,3];
var b = [1,2,3];
console.log(a === b); // false
var a = [1, 2, 3]
var b = a
console.log(a === b) // true
傳值與傳址
瞭解了基本資料型別與引用型別的區別之後,我們就應該能明白傳值與傳址的區別了。
在我們進行賦值操作的時候,基本資料型別的賦值(=)是在記憶體中新開闢一段棧記憶體,然後再把再將值賦值到新的棧中
var a = 10;
var b = a;
a ++ ;
console.log(a); // 11
console.log(b); // 10
所以說,基本型別的賦值的兩個變數是兩個獨立相互不影響的變數。
但是引用型別的賦值是傳址。只是改變指標的指向,例如,也就是說引用型別的賦值是物件儲存在棧中的地址的賦值,這樣的話兩個變數就指向同一個物件,因此兩者之間操作互相有影響。
var a = {}; // a儲存了一個空物件的例項
var b = a; // a和b都指向了這個空物件
a.name = 'jozo';
console.log(a.name); // 'jozo'
console.log(b.name); // 'jozo'
b.age = 22;
console.log(b.age);// 22
console.log(a.age);// 22
console.log(a == b);// true
淺拷貝
實現:
function shallowCopy (src) {
let new = {}
for (let i in src) {
if (src.hasOwnProperty(i)) {
new[i] = src[i]
}
}
return new
}
深拷貝
一種騷操作是利用JSON.parse 和 JSON.stringify
var a = {
name: 'SpawN',
age: 28
}
var b = JSON.parse(JSON.stringify(a))
b.name = 'Johnny.R'
console.log(a.name) // 'SpawN'
另外一種是科班操作,也就是常規操作,就是利用遞迴,來遍歷目標物件下的所有屬性
function deepCopy(obj) {
if (typeof obj !== 'object') return
// 初始化
var newObj = obj instanceof Array ? [] : {}
for (let k in obj) {
if (obj.hasOweProperty(k)) {
newObj[k] = typeof obj[k] === 'object' ? agruments.callee(obj[k]) : obj[k]
}
}
return newObj
}
這裡僅僅是實現了基本的深拷貝,對一些邊界並沒有進行妥善的處理。基本思路就是通過for in 迴圈,當值為物件的時候,再遞迴進行for in迴圈。
相關推薦
js中實現深淺拷貝
值型別和引用型別 說起深淺拷貝,我覺得需要理清楚 值型別 和 引用型別 值型別 所謂 值型別 就是 undefined,null,number, string ,boolean 等五種基本資料型別, 應該還有一個Symbol型別。 值型別的資料儲存在
js中的深淺拷貝理解
淺拷貝,通俗理解就是拷貝一層,例如{a:1,b:{c:1,d:2}},那麼拷貝的是a,b指向的記憶體的位置;由於b指向的是一個物件的引用,那麼,我對原來物件中的c屬性進行修改,也會影響到新物件屬性的值;但是修改原來物件中a的值,就不會影響後新物件a的值; 那麼如何實現淺拷貝呢? func
js中的深淺拷貝
js中的深拷貝與淺拷貝 深拷貝: 如果拷貝的時候,將當前物件的資料的引用結構都拷貝一份,即深拷貝,資料在記憶體中獨立存在。 淺拷貝: 若拷貝的時候,只針對當前物件的屬性地址的拷貝,即淺拷貝。 拷貝: 複製一份,指將物件資料複製一份。 *注意
js中的深拷貝和淺拷貝
所有 object 簡單的 col images new color 其他 java 深復制和淺復制只針對像 Object, Array 這樣的復雜對象的。簡單來說,淺復制只復制一層對象的屬性,而深復制則遞歸復制了所有層級。 深淺拷貝 的主要區別就是:復制的是引用(地址)還
JS中實現JSON對象和JSON字符串之間的相互轉換
獲取 bsp com .com ins 對象 ie7 strong line 對於主流的瀏覽器(比如:firefox,chrome,opera,safari,ie8+),瀏覽器自己提供了JSON對象,其中的parse和stringify方法實現了JSON對象和JSON字符串
js中實現高德地圖坐標經緯度轉百度地圖坐標
math.sqrt pan poi 結果 mat blog 筆記 百度 說明 1 function tobdMap(x, y) { 2 var x_pi = 3.14159265358979324 * 3000.0 / 180.0; 3
js中實現繼承的不同方式以及其缺點
但是 scrip UC .proto 就是 圖片 問題 inf 引用 1.利用call和apply,借助構造函數 fucntion P(){ this.name = "P"; } fucntion C1(){ P.call(this); }
js中的深拷貝與淺拷貝
nbsp 中一 局限性 深拷貝與淺拷貝 ext bsp post body extend 對於字符串類型,淺拷貝是對值的拷貝,對於對象來說,淺拷貝是對對象地址的拷貝,並沒有開辟新的棧,也就是拷貝的結果是兩個對象指向同一個地址,修改其中一個對象的屬性,則另一個對象的屬性也會改
[記錄] JavaScript 中的深淺拷貝(克隆)
ray 方式 pro 是否 span div ext 引用 針對 淺拷貝和深拷貝針對的是Object、Array這樣復雜的引用類型數據 簡單說:淺拷貝只復制一層的屬性,而深拷貝則遞歸復制所有層級的屬性 一、淺拷貝 1 function clone(origin
淺談關於java中的深淺拷貝
long private 創建 .com ktr nal ride 相同 cto 一.淺拷貝(shallow copy) 1.如何實現淺拷貝? Object類 是所有類的直接或間接父類,Object中存在clone方法,如下 protected native O
Node.js中使用pipe拷貝大文件不能完全拷貝的解決辦法
ads 沒有 str pat some pipe reads 大文件 close 原來的代碼如下: var readable = fs.createReadStream( filepath ); var writable = fs.createWriteStream( ou
js中實現跨域的幾種方法
js中幾種實用的跨域方法原理詳解 這裡說的js跨域是指通過js在不同的域之間進行資料傳輸或通訊,比如用ajax向一個不同的域請求資料,或者通過js獲取頁面中不同域的框架中(iframe)的資料。只要協議、域名、埠有任何一個不同,都被當作是不同的域。 下表給出了相對http://sto
angular.js和vue.js中實現函數去抖(debounce)
搜索輸入框 sea class 方案 get clas 電路 dia ive 問題描述 搜索輸入框中,只當用戶停止輸入後,才進行後續的操作,比如發起Http請求等。 學過電子電路的同學應該知道按鍵防抖。原理是一樣的:就是說當調用動作n毫秒後,才會執行該動作,若在這n毫秒內又
JS中的淺拷貝和深拷貝。
拷貝 結果 如果 string typeof aso clone return isarray //淺拷貝 var o1 = { a: 10, b: 20, c: 30 }; var o2 = o1; o2.a = 100; console.log(o1);
JS中實現陣列取最大值
情景: 有一個如下陣列: var classify=["5","47","98","12","165"]; 我現在要求取出這個數組裡面的最大值。 完整程式碼: function ceshi(){ var classify=["5","47","98","12","165
Java中支援深淺拷貝的第三方庫
深拷貝 Apache旗下的Commons-Lang3包有一個序列化的工具SerializationUtils,可以做深拷貝。 當然前提是你的類實現了序列化介面。 Java Deep Cloning Library是我覺得最好用的一個。它的深拷貝通過反射實現,適合用於你 不能控制的第三方類或者沒有實現序
JS--變數及深淺拷貝
JS變數分為基本型別和引用型別 基本型別資料包括Number, String, Boolean, Null, Undefined五種型別; 引用資料型別包括Array, Date, RegExp, Function等, 統稱為Object型別。 JS變數的
js中實現楊輝三角
實現效果:楊輝三角 即: 提示使用者輸入要實現的楊輝三角行數: 請輸入楊輝三角的行數: 8 程式碼實現後的效果如下: 1 1.1 1.2.1 1.3.3.1 1.4.6.4.1 1.5.10.10.5.1 1.6.15.20.15.6.1 1
----如何在js中實現公有和私有屬性
私有方法其實和閉包是有關係的,私有方法在其他語言裡面是不被訪問到的,除非有專門的介面,js的區域性作用域裡面的東西在正常情況下也是不能被外部訪問到,但是通過閉包的方式可以訪問到,這樣我們就可以利用這個特性,看例子: var book = (function(){ var page =
js中實現button按鈕變灰不可用,可用的方法
按鈕變灰不可用方法:document.getElementById("crop").setAttribute("disabled", true); 按鈕可用方法:document.getElementById("crop").removeAttribute("disabled"); 按