ECMAscript原始值、引用值、類型轉換、淺拷貝、深拷貝總結

#ECMAscript原始值、引用值、類型轉換、淺拷貝、深拷貝
##原始值
存儲在棧(stack)中的簡單數據段,也就是說,它們的值直接存儲在變量訪問的位置
棧區(stack):系統自動分配的內存空間,有系統自動釋放。
##引用值
存儲在堆(heap)中的對象,也就是說,存儲在變量處的值是一個指針(point),指向存儲對象的內存處
堆區(heap):動態分配的內存空間,大小不確定,也不會自動釋放。
##類型轉換

  1. 轉爲字符串

    Boolean、String、Number是僞對象,他們實際上具有屬性和方法。所以都有相應的toString()方法進行轉化

     (1)Number 類型的 toString() 方法
     	默認模式
     	var num1 = 1;
     	var num2 = 1.0;
     	num1.toString();	//返回 "1"
     	num2.toString();	//返回 "1"
     (2)Number 類型的 toString() 方法
     	基模式
     	var num = 10;
     	num.toString(2);	//返回 "1010"
     	num.toString(8);	//返回 "12"
     	num.toString(16);	//返回 "A"
    
  2. 轉換爲數字

    parseInt、parseFloat針對字符串。parseInt() 方法首先查看位置 0 處的字符,判斷它是否是個有效數字;如果不是,該方法將返回 NaN,不再繼續執行其他操作。如果是有效數字,則一直重複執行下去,直到發現不是有效數字,將這個字符之前有效的字符串轉爲數字

     (1)parseInt() 函數
     	將值轉換爲整型
     	var num = parseInt("12abc");   //返回 12
     	var num = parseInt("0xA");	   //返回 10
     	var num = parseInt("23.9");	   //返回 23
     	var num = parseInt("abc");	   //返回 NaN
     (2) parseInt() 函數
     	也有基模式
     	var num = parseInt("AF", 16);  //返回 175
     	var num = parseInt("10", 2);   //返回 2
     	var num = parseInt("10", 8);   //返回 8
     	var num = parseInt("10", 10);  //返回 10
     	var num = parseInt("010");	   //返回 8
     	var num = parseInt("010", 8);  //返回 8
     	var num = parseInt("010", 10); //返回 10
     (3)parseFloat() 函數
     	字符串必須以十進制形式表示浮點數
     	var num = parseFloat("12abc"); //返回 12
     	var num = parseFloat("0xA");   //返回 NaN
     	var num = parseFloat("1.2");   //返回 1.2
     	var num = parseFloat("1.2.3"); //返回 1.2
     	var num = parseFloat("0102");  //返回 102
     	var num = parseFloat("abc");   //返回 NaN
    
  3. 強制類型轉換

    Boolean(value) - 把給定的值轉換成 Boolean 型

    Number(value) - 把給定的值轉換成數字(可以是整數或浮點數)

    String(value) - 把給定的值轉換成字符串

     (1)Boolean() 函數
     	至少有一個字符的字符串、非 0 數字或對象時,Boolean() 函數將返回 true,如果是空字符串、數字 0、undefined 或 null,它將返回 false
     	var b1 = Boolean("");		//false - 空字符串
     	var b1 = Boolean("hello");	//true - 非空字符串
     	var b1 = Boolean(300);		//true - 非零數字
     	var b1 = Boolean(null);		//false - null
     	var b1 = Boolean(0);		//false - 零
     	var b1 = Boolean(new object());	//true - 對象
     (2)Number() 函數
     	與 parseInt() 和 parseFloat() 方法的處理方式相似,只是它轉換的是整個值,而不是部分值
     	var n1 = Number(false)	    //返回 0
     	var n1 = Number(true)	    //返回 1
     	var n1 = Number(undefined)	//返回 NaN
     	var n1 = Number(null)	    //返回 0
     	var n1 = Number("1.2")	    //返回 1.2
     	var n1 = Number("12")	    //返回 12
     	var n1 = Number("1.2.3")	//返回 NaN
     	var n1 = Number(new object())  //返回 NaN
     	var n1 = Number(50)	        //返回 50
     (3)String() 函數
     	可把任何值轉換成字符串
     	和調用 toString() 方法的唯一不同之處在於,對 null 和 undefined 值強制類型轉換可以生成字符串而不引發錯誤
     	var s1 = String(null);	    //"null"
     	var oNull = null;
     	var s2 = oNull.toString();	//會引發錯誤
    

##淺拷貝和深拷貝
深拷貝與淺拷貝的概念只存在於引用數據類型

  1. 基本數據類型

    目前基本數據類型有:Boolean、Null、Undefined、Number、String、Symbol

    基本數據類型在賦值操作時是傳值。在賦值操作時,基本數據類型的賦值是在內存裏開闢了一段新的棧內存,然後再把值賦值到新開闢的棧內存中。

  2. 引用數據類型

    引用數據類型有:Object、Array、Function、RegExp、Date 等

    引用數據類型在賦值操作時是傳址。在賦值操作時,引用類型的賦值只是改變了指針的指向,在給變量賦值時,是把對象保存在棧內存中的地址賦值給變量,結果是兩個變量指向同個棧內存地址。

  3. 淺拷貝

    對基本數據類型進行值傳遞,對引用數據類型進行引用傳遞般的拷貝,此爲淺拷貝。

     (1)通過擴展運算符...實現淺拷貝
     (2)通過Object.assign()實現淺拷貝(可以實現一維對象的深拷貝)
     	var obj1 = {x: 1, y: 2}, obj2 = Object.assign({}, obj1);
     	console.log(obj1) //{x: 1, y: 2}
     	console.log(obj2) //{x: 1, y: 2}
     	obj2.x = 2; //修改obj2.x
     	console.log(obj1) //{x: 1, y: 2}
     	console.log(obj2) //{x: 2, y: 2}
     	var obj1 = {
     	    x: 1, 
     	    y: {
     	        m: 1
     	    }
     	};
     	var obj2 = Object.assign({}, obj1);
     	console.log(obj1) //{x: 1, y: {m: 1}}
     	console.log(obj2) //{x: 1, y: {m: 1}}
     	obj2.y.m = 2; //修改obj2.y.m
     	console.log(obj1) //{x: 1, y: {m: 2}}
     	console.log(obj2) //{x: 2, y: {m: 2}}
    
  4. 深拷貝

    對基本數據類型進行值傳遞,對引用數據類型,創建一個新的對象,並複製其內容,此爲深拷貝。

     (1)通過Lodash的cloneDeepAPI 實現深拷貝
     	let _ = require('lodash');
     	let obj1 = {
     	  a: 1,
     	  b: {
     	    c: 2
     	  }
     	};
     	let obj2 = _.cloneDeep(obj1);
     	obj2.b.c = 6;
     	console.log(obj1.b.c); // 2
     	console.log(obj2.b.c); // 6
     (2)通過JSON.parse(JSON.stringify())進行深拷貝,但會忽略undefined、任意的函數、symbol 值
     	var obj1 = {
     	    x: 1, 
     	    y: {
     	        m: 1
     	    },
     	    a:undefined,
     	    b:function(a,b){
     	      return a+b
     	    },
     	    c:Symbol("foo")
     	};
     	var obj2 = JSON.parse(JSON.stringify(obj1));
     	console.log(obj1) //{x: 1, y: {m: 1}, a: undefined, b: ƒ, c: Symbol(foo)}
     	console.log(obj2) //{x: 1, y: {m: 1}}
     	obj2.y.m = 2; //修改obj2.y.m
     	console.log(obj1) //{x: 1, y: {m: 1}, a: undefined, b: ƒ, c: Symbol(foo)}
     	console.log(obj2) //{x: 2, y: {m: 2}}
     (3)只能實現一維對象的深拷貝:
     	Object.assign():
     		見3.(2)
     	slice():
     		var arr1 = [1, 2], arr2 = arr1.slice();
     		console.log(arr1); //[1, 2]
     		console.log(arr2); //[1, 2]
     		arr2[0] = 3; //修改arr2
     		console.log(arr1); //[1, 2]
     		console.log(arr2); //[3, 2]
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章