数据类型 基本类型
名字和值都存储在栈内存中,按值访问,可以操作保存在变量中的实际的值
六种基本类型:Number String Boolean Undefined Null Symbol
1 2 3 4 5 let a = 100 ;let b = a;a = 200 ; console .log (b);
引用类型
名字存储在栈内存中,值存储在堆内存中,操作的是变量的引用地址
五种引用类型:Object Array Function RegExp Date
1 2 3 4 5 let a = { age : 20 };let b = a;b.age = 21 ; console .log (a.age );
1 2 3 4 5 6 7 8 9 const obj1 = { x : 100 , y : 200 } const obj2 = obj1;let x1 = obj1.x ;obj2.x = 101 ; x1 = 102 ; console .log (obj1);
typeof 操作符
判断基本类型:Undefined Number String Boolean
判断函数:Function
识别引用类型(不可再细分):Object
1 2 3 4 5 6 typeof ccc typeof console .log typeof function ( ){} typeof null typeof ['a' , 'b' ] typeof {x : 100 }
手写深拷贝
默认情况下,基本类型都是深拷贝,引用类型都是浅拷贝
浅拷贝复制的是对象的引用地址,因此克隆对象和原对象指向同一个地址,修改一个对象的属性,另一个对象的属性也随之改变
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const obj1 = { age : 20 , name : 'XXX' , address : { city : 'guangzhou' }, arr : ['a' , 'b' , 'c' ] }; const obj2 = obj1;obj2.address .city = 'shanghai' ; obj2.arr [0 ] = 'a1' ; console .log (obj1.address .city ); console .log (obj2.address .city ); console .log (obj1.arr [0 ]); console .log (obj2.arr [0 ]);
深拷贝,即对象以其引用的对象被复制时,复制所有字段以及复制字段所指向的动态分配内存,因此克隆对象和原对象的修改互不影响
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function deepClone (obj ) { if (obj == null || typeof obj !== 'object' ) { return obj; } let result; if (obj instanceof Array ) { result = []; } else { result = {}; } for (let key in obj) { if (obj.hasOwnProperty (key)) { result[key] = deepClone (obj[key]); } } return result; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const obj1 = { age : 20 , name : 'XXX' , address : { city : 'guangzhou' }, arr : ['a' , 'b' , 'c' ] }; const obj2 = deepClone (obj1);obj2.address .city = 'shanghai' ; obj2.arr [0 ] = 'a1' ; console .log (obj1.address .city ); console .log (obj2.address .city ); console .log (obj1.arr [0 ]); console .log (obj2.arr [0 ]);
类型转换
JavaScript 在声明时只有一种类型,只有到运行期间才会确定当前类型
在运行期间,由于 JavaScript 没有对类型做严格限制,导致不同类型之间可以进行运算,因此需要允许类型之间互相转换
显式类型转换
显式类型转换就是手动地将一种值转换为另一种值
常用的显式类型转换方法有 Number、String、Boolean、parseInt、parseFloat、toString 等
to boolean 使用 Boolean() 将其他类型的值转换为 Boolean 类型:
原始类型
转换结果
Undefined
false
Null
false
Number
0 和 NaN 返回 false,其他返回 true
String
空字符串返回 false,非空字符串返回 true
Symbol
true
Object
true
1 2 3 4 5 6 7 8 9 Boolean (undefined ) Boolean (null ) Boolean (0 ) Boolean (NaN ) Boolean ('' ) Boolean ('aaa' ) Boolean (222 ) Boolean (Symbol ()) Boolean ({})
to number 使用 Number() 将基本类型的值转换为 Number 类型:
原始类型
转换结果
Undefined
NaN
Null
0
true
1
false
0
String
如果字符串中只包含数字,则转换为对应的数字 如果字符串中只包含十六进制格式,则转换为对应的十进制数字 如果字符串为空,则转换为 0 如果字符串包含上述之外的字符,则转换为 NaN
1 2 3 4 5 6 7 8 Number (undefined ) Number (null ) Number (true ) Number (false ) Number ('111' ) Number ('0x100F' ) Number ('' ) Number ('abc123' )
使用 Number() 将对象转换成 Number 类型:
调用对象的 valueOf() 方法,没有则去原型链上查找
如果 valueOf() 方法的返回值为原始值,则对返回值进行原始值 to number 的类型转换,得出转换结果
如果 valueOf() 方法返回值是对象,则调用对象的 toString() 方法
如果返回值为原始值, 则对返回值进行原始值 to number 的类型转换, 得出转换结果
如果返回值为对象, 则报错
类型
toString
valueOf
object
“[object <type>]“
指向自身
function
函数的字符串形式
指向自身
array
“arr0, arr1, …” 或者 “”
指向自身
date
包含本地时间信息的字符串
从1970年1月1日开始至今的毫秒数
regexp
正则表达式的字符串形式
指向自身
error
“<err>.name: <err>.message”
指向自身
1 2 3 4 5 6 7 8 9 Number ({}) Number ({a : 1 }) Number ([]) Number ([1 ]) Number ([1 , 2 , 3 ]) Number (function ( ){let a = 1 }) Number (new Date ) Number (new Error ('opps' )) Number (/\d+/g )
to string 使用 String() 将基本类型的值转换为 String 类型:
原始类型
转换结果
Undefined
“undefined”
Null
“null”
Number
相应数字的字符串类型
Boolean
“true” or “false”
String
String
1 2 3 4 5 String (undefined ) String (null ) String (123 ) String (true ) String (false )
使用 String() 将对象转换为 String 类型:
调用对象的toString()方法,没有则去原型链上查找
1 2 3 4 5 6 7 8 9 String ({}) String ({a : 1 }) String ([]) String ([1 ]) String ([1 , 2 , 3 ]) String (function ( ){let a = 1 }) String (new Date ) String (new Error ('opps' )) String (/\d+/g )
隐式类型转换 + 运算符 1 2 3 const a = 100 + 10 ; const b = 100 + '10' ; const c = true + '10' ;
== 运算符 1 2 3 4 5 100 == '100' ; 0 == '' ; 0 == false ; false == '' ; null == undefined ;
=== 运算符 注意!除了 == null 之外,其余一律使用 ===
1 2 3 4 5 6 const obj = { x : 100 }; if (obj.a == null ){}
逻辑运算符 1 2 3 console .log (10 && 0 ); console .log ('' || 'abc' ); console .log (!window .abc );
逻辑判断
经过两次非运算为 true 的变量为 truly 变量,反之为 falsely 变量
truly 变量:!!a === true 的变量
falsely 变量:!!a === false 的变量
1 2 3 4 5 6 7 !!0 === false !!NaN === false !!'' === false !!null === false !!undefined === false !!false === false
if 语句判断的是 truly 变量,即只有 truly 变量才会进入 if 语句内
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 const a = true ;if (a) { } const b = 100 ;if (b) { } const c = '' ;if (c) { } const d = null ;if (d) { } let e;if (e) { }