最近边整理自己的笔记边复习,如果出现错误,希望路过的大佬能帮忙指出。
数据类型
《JS高程第3版》 第3.4章 数据类型 | 第5章 引用类型
- 基本数据类型
- 共6种:string number boolean null undefined symbol(ES6新增)
- 引用类型
- 除基本数据类型外的。
- 基本数据类型的3种包装类型(String Number Boolean)也是引用类型。
类型检测
基本数据类型的检测
typeof
基本数据类型中除null外,均可以准确检测。另可以检测Function。
typeof 'str' //"string"
typeof 1 //"number"
typeof true //"boolean"
typeof null //"object"
typeof undefined //"undefined"
typeof [] //"object"
typeof {} //"object"
typeof function(){} //"function"
// 包装类型
var c = 5; // typeof "number"
var d = new Number(8); // typeof "object"
应用:判断变量是引用类型(递归实现深拷贝用到过)
!obj[k] == null && (typeof obj[k] === "object" || typeof obj[k] === "function")
引用类型的检测
1. instanceof
不能在多全局对象的情况(例如:多个 frame 或多个 window 之间的交互) —— MDN
所以数组可以使用Array.isArray()。其他类型见后述方法。
2. Object.prototype.toString.call(myObj) === '[object Type]'
Object.prototype上有一个toString()方法,返回一个表示该对象的字符串。
判断引用类型和基本数据类型的类型,可以使用该方法。
// MDN的示例代码
var toString = Object.prototype.toString;
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
// Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
其他构造函数的原型对象继承了该方法,但改写成了输出内容字符串。所以需要用call()修改Object原型上的toString()的this后调用。
3. instance.constructor ==(=) Function 或 instance.__proto__.constructor ==(=) Function
用constructor是可以串联起实例和构造函数的,但是constructor的值是可以被修改的,所以不要这样判断。
数据类型转换
一是各类型互相转换的规则;二是不同运算符需要转换成哪些类型。
类型转换规则
类型转换一共3种情况:转布尔、转数字、转字符串。
-
转布尔值
只有null undefined、""、+0、-0、false、NaN 这7种情况转布尔结果是false,其余情况包括-1、"0"都会转为true。
-
转数字
// 字符串:能直接写成数字,和NaN
Number('1') // 1
var a = 1; Number(a) // 1
Number('a') // NaN
// 数组:空数组或只有一个数字元素,和NaN
Number([]) // 0
Number([0]) // 0
var a = 0; Number([a]) // 0
Number(['a']) // NaN
// 其它引用类型:NaN
Number({}) // NaN
// 特殊基本类型
Number(null) // 0
Number(undefined) // NaN
- 转字符串
// 数字、布尔、函数:直接加引号
// 数组
[].toString() // ""
[1, 2].toString() // "1,2"
[1, {}].toString() // "1,[object Object]"
// 对象
obj.toString() // "[object Object]"
运算符与类型转换
都有哪些运算符:《JS高程 3.5操作符》、表达式和运算符 - MDN
1. 关系运算符(> | >= | < | <= | ==)
《JS高程 3.5.6关系运算符》
两边数据类型相同才能进行比较。会转成数字或字符串类型,转成数字类型的优先级 》 转字符串。
基本类型和基本类型比较
// 类型相同不转换
"2" > "10" // true。不转数字,按字符串比较。
// 数字 和 字符串 转 数字
"2" > 10 // false
"a" > 10 // false
// 布尔 和 数字或字符串 转 数字
true > 10 // false
true == 1 // true
true > "" // true
true > "1" // false
true > "a" // false
// null undefined比较特别
Number(null) == 0
Number(undefined) == NaN
null == undefined // true。两边转数字不等,但直接比较返回相等。
null >= 0 // true。>= <=是true,其余情况null和0比较都是false。
undefined == 0 // false。undefined和0任何情况都是false。
引用类型和基本类型比较
// 和数字 转数字
[2] == 2 // true。 数组只有一个数字元素时,能转成数字。
["2"] == 2 // true
console.log({a: 1} >= 1) // false。NaN和任何值都不相等。
console.log({a: 1} <= 1) // false
// 和布尔 转数字
console.log({a: 1} >= true) // false
console.log({a: 1} >= false) // false
// 和字符串 先调用valueOf(),如果返回基本数据类型,就用结果进行比较;否则再调用toString()
var obj = {a: 1}
obj.valueOf() // {a: 1}
obj.valueOf().toString() // "[object Object]"
var arr = [1];
arr.valueOf() // [1]
arr.valueOf().toString() // "1"
[2] == "2" // true
["2"] == "2" // true
[1,2] == "1,2" // true
console.log({a: 1} >= "a") // false。比较的是"[object Object]" >= "a"
console.log({a: 1} <= "a") // true
引用类型和引用类型
比较内存地址
当且仅当与原始值比较时,对象会被转换为原始值。当两个操作数均为对象时,它们作为对象进行比较,仅当它们引用相同对象时返回true。 —— MDN
// 下面两个比较特殊。由于逻辑非运算符的存在,会转成数字进行比较。
Number([]) // 0
Number({}) // NaN
[] == ![] // true。左右变量最终转为数字进行比较;如果有!,先转布尔再转数字
{} == !{} // false
2. 算术运算符
减乘除余,都转成数字。下面只写加法。
基本类型、数组
转字符串优先级 》 转数字
// 有字符串转字符串
null + "" // "null"
undefined + "" // "undefined"
[].toString() // ""
[] + "" // ""
[] + "1" // "1"
[] + "a" // "a"
[1,2] + "1" // "1,21"
[1,'a'] + "1" // "1,a1"
[1,a] + "2" // "1,[object Object]2"
// 没字符串有数字,基本类型转数字,引用类型转字符串
null + 5 // 5
undefined + 5 // NaN
[1,2] + 5 // "1,25"
// 都没有,基本类型转数字,引用类型转字符串
null + undefined // NaN
null + true // 1
[] + true // "true"
对象
// 在 + 运算时,另一项无论是数字、字符串,都转字符串
"1" + {} // "1[object Object]"
1 + {a: 1} // "1[object Object]"
- 注:控制台测验时声明变量需注意:定义变量后运算和直接用{}方式,结果不同。
- {} 在运算符前面,不会被认为是对象,而被认为是代码块。另一项无论是数字、字符串,都转数字。
- {} 在运算符后面,或者先声明一个对象变量,那么它还是对象。
{} + 1 // 1 {a: 1} + 1 // 1 {} + "1" // 1 {} + "a" // NaN {a: 1} + "b" // NaN- 如果放在console.log()里,对象不会被认为是代码块。
3. 逻辑运算符
与
- 短路运算符。前项是真 -> 直接返回后项;前项是假 -> 直接返回前项。
0 && 2 // 0
1 && 2 // 2
-1 && 2 // 2
或
- 短路运算符。前项是真 -> 直接返回前项;前项是假 -> 直接返回后项。
0 || 2 // 2
1 || 2 // 1
-1 || 2 // -1
非
- 转布尔。
- 优先级最高。