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]
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章