参考文章:
数据类型
JS中分为七种数据类型,七种内置类型又分为两大类型:6种基本类型和Object
1.基本类型
基本类型主要是: Undefined、Boolean、String、Number、Null、Symbol(ECMAScript 6 新定义);
存放在栈中
基本类型存储在栈内存中,数据大小确定,内存空间大小可以分配,按值存放,所以可直接访问
值不可变
javascript中的原始值(undefined、null、布尔值、数字和字符串)与对象(包括数组和函数)有着根本区别。原始值是不可更改的:任何方法都无法更改(或“突变”)一个原始值。对数字和布尔值来说显然如此 —— 改变数字的值本身就说不通,而对字符串来说就不那么明显了,因为字符串看起来像由字符组成的数组,我们期望可以通过指定索引来假改字符串中的字符。实际上,javascript 是禁止这样做的。字符串中所有的方法看上去返回了一个修改后的字符串,实际上返回的是一个新的字符串值。
值不可变,但可以重新赋值,例如:
-
var a = "123"; -
console.log(a[1]='0'); //0 -
console.log(a); //123 -
a = "234"; -
console.log(a); //234 -
复制代码
基本类型的比较是值的比较
只要值相等就认为是相等的,推荐使用===进行比较,例如:
-
var a = 1; -
var b = 1; -
var c = true; -
console.log(a === b); //true -
console.log(a == c); //true '=='会进行类型转换 -
复制代码
2. 引用类型
引用数据类型统称为 Object 对象,主要包括对象、数组、函数、日期和正则
存放在堆中
堆内存中是无序存放
引用类型存放在堆内存中,变量实际上是一个存放在栈内存的指针,这个指针指向堆内存中的地址。每个空间大小不一样,要根据情况进行特定的分配,例如:
-
var person1 = {name: 'joj'}; -
var person2 = {name: 'xiaomi'}; -
var person3 = {name: 'xiaoyang'}; -
复制代码
值可变
例如:
-
var a = [1, 3]; -
a[1] = 2; -
console.log(a); //[1, 2] -
复制代码
引用类型的比较是引用的比较
每次我们对js中的引用类型进行操作的时候,都是操作其对象的引用(保存在栈内存中的指针),所以比较两个引用类型,看是否指向同一个对象。例如:
-
var a = [1, 2, 3]; -
var b = [1, 2, 3]; -
console.log(a === b); //false -
复制代码
虽然变量a,b表示的是同一个内容,但其在内存中的位置不一样,指向的不是同一个对象,所以不相等。
数据类型的判断
typeof
返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、symbol、object、undefined、function等7种数据类型,但不能判断null、array等
-
typeof Symbol(); // symbol 有效 -
typeof ''; // string 有效 -
typeof 1; // number 有效 -
typeof true; //boolean 有效 -
typeof undefined; //undefined 有效 -
typeof new Function(); // function 有效 -
typeof null; //object 无效 -
typeof [] ; //object 无效 -
typeof new Date(); //object 无效 -
typeof new RegExp(); //object 无效 -
复制代码
instanceof
用来判断A是否为B的实例,A instanceof B, 返回 boolean 值。instanceof 用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性,但它不能检测 null 和 undefined
-
[] instanceof Array; //true -
{} instanceof Object;//true -
new Date() instanceof Date;//true -
new RegExp() instanceof RegExp//true -
null instanceof Null//报错 -
undefined instanceof undefined//报错 -
复制代码
Object.prototype.toString.call()
最准确最常用
-
Object.prototype.toString.call('') ; // [object String] -
Object.prototype.toString.call(1) ; // [object Number] -
Object.prototype.toString.call(true) ; // [object Boolean] -
Object.prototype.toString.call(undefined) ; // [object Undefined] -
Object.prototype.toString.call(null) ; // [object Null] -
Object.prototype.toString.call(new Function()) ; // [object Function] -
Object.prototype.toString.call(new Date()) ; // [object Date] -
Object.prototype.toString.call([]) ; // [object Array] -
Object.prototype.toString.call(new RegExp()) ; // [object RegExp] -
Object.prototype.toString.call(new Error()) ; // [object Error] -
复制代码
类型转换
转Boolean
在条件判断时,undefined, null, false, NaN, '', ±0 转为 false, 其余都为true。
对象转基本类型
对象转基本类型,调用优先级 Symbol.toPrimitive > valueOf() > toString(),方法皆可重写
-
var a = { -
valueOf() { -
return 1; -
}, -
toString() { -
return 2; -
}, -
[Symbol.toPrimitive]() { -
return 3; -
} -
} -
a + 1; //4 -
a + '1'; //31 -
复制代码
对象键名的转换
- 对象的键名只能是字符串和Symbol类型
- 其它类型的键名会被转换成字符串类型
- 对象转字符串默认会调用 toString 方法
栗子1:
-
var a = {}, b = '123', c = 123; -
a[b] = 'b'; -
// c 的键名会被转换成字符串‘123’,会覆盖掉 b -
a[c] = 'c'; -
//输出 c -
console.log(a[b]) -
复制代码
栗子2:
-
var a = {}, b = Symbol('123'), c = Symbol('123'); -
// b 是 Symbol 类型,不需要转换 -
a[b] = 'b'; -
// c 是 Symbol 类型,不需要转换。任何一个 Symbol 类型的值都是不相等的,所以不会覆盖掉 b。 -
a[c] = 'c'; -
//输出 b -
console.log(a[b]) -
复制代码
栗子3:
-
var a={}, b={key:'123'}, c={key:'456'}; -
// b 不是字符串也不是 Symbol 类型,需要转换成字符串。 -
// 对象类型会调用 toString 方法转换成字符串 [object Object]。 -
a[b]='b'; -
// c 不是字符串也不是 Symbol 类型,需要转换成字符串。 -
// 对象类型会调用 toString 方法转换成字符串 [object Object]。这里会把 b 覆盖掉。 -
a[c]='c'; -
// 输出 c -
console.log(a[b]); -
复制代码
四则运算符
- 加法运算符:一方是字符串类型,另一方就会被转为字符串类型
- 其他运算符:一方是数字,另一方就会被转为数字
-
1 + '1'; // '11' -
2 * '2'; // 4 -
[1, 2] + [2, 1]; // '1,22,1' -
// [1, 2].toString() -> '1,2' -
// [2, 1].toString() -> '2,1' -
// '1,2' + '2,1' = '1,22,1' -
// 神奇! -
'a' + + 'b' // -> "aNaN" -
// 因为 + 'b' -> NaN -
// 你也许在一些代码中看到过 + '1' -> 1 -
复制代码
==运算符
其中,toPrimitive() 用于对象转基本类型
栗子:
-
// [] 转成 true,然后取反变成 false -
[] == false -
// 根据第 8 条得出 -
[] == ToNumber(false) -
[] == 0 -
// 根据第 10 条得出 -
ToPrimitive([]) == 0 -
// [].toString() -> '' -
'' == 0 -
// 根据第 6 条得出 -
0 == 0 // -> true -
复制代码
比较运算符
- 如果是对象,就通过
toPrimitive转换对象 - 如果是字符串,就通过
unicode字符索引来比较
本文深入解析JavaScript中的数据类型,区分基本类型与引用类型,探讨它们的存储方式、可变性及比较规则。同时,介绍了类型判断方法如typeof、instanceof和Object.prototype.toString.call(),并讨论了类型转换过程。

308

被折叠的 条评论
为什么被折叠?



