作者:zhangl
原文:JS数据类型与隐式转换
数据类型
JS的数据类型主要分为两大类:基本数据类型与引用数据类型,下面我们会围绕这两大数据类型进行说明和扩展
基本数据类型
- 存储位置:栈
- 存储空间:固定
- 特点:不可变性(immutable)
String(字符串类型)
用于存储字符变量,可以用单引号和双引号包裹
// 定义字符串变量
var str = 'zhangl';
// 不可变性
str.slice(1); // 'hangl'
console.log(str); // 'zhangl'
// 判断类型
console.log(typeof str); // "string"
复制代码
Number(数字类型)
JS中只有一种数字类型,既可以使用存储整数,也可以存储浮点数
// 定义数字变量
var numInt = 123;
var numFloat = 123.00;
// 只有一种数据类型
console.log(typeof numInt); // "number"
console.log(typeof numFloat); // "number"
复制代码
Boolean(布尔类型)
只有两个值true(真)或false(假)
// 定义布尔变量
var boolTrue = true;
var boolFalse = false;
// 定义一个true, false以外的值
var isBoolValue = 123;
console.log(typeof boolTrue); // "boolean"
console.log(typeof boolFalse); // "boolean"
console.log(typeof isBoolValue === 'boolean'); // false
复制代码
Null
表示一个空值
// 定义null变量
var nullData = null;
// 这里使用toString判断是否是null类型
console.log(Object.prototype.toString.call(nullData)); // "[obejct Null]"
复制代码
使用typeof判断null不准确,会返回object,原因是JS在底层存储变量时,会以二进制的形式保存,二进制的前三位表示数据类型,对象类型的前三位为0,null的二进制码全部都为0,从而导致了typeof在判断时,将null误判断为对象类型数据
[000:对象; 010:浮点数; 100:字符串; 110:布尔; 1:整数]
Undefined
表示一个变量被声明,但未赋值(没有值)
// 声明undefined变量
var undefinedData;
console.log(typeof undefinedData); // "undefined"
复制代码
Symbol(ES6推出的一种唯一且不可变的数据类型)
- 特点:
- 作为属性名,不会被for...in,for...of遍历出来;也不会被Object.keys();Object.getOwnPropertyNames();JSON.stringify()获取
- 使用场景:
- 作为对象的私有属性
- 防止对象重名属性污染
// 创建symbol变量
var s1 = Symbol('name');
var s2 = Symbol('name');
// 判断类型
console.log(typeof s1); // "symbol"
// 比较两个description都为'name'的变量
console.log(s1 === s2); // false
// 比较两个变量的description
console.log(s1.description === s2.description); // true => 'name' === 'name'
// 获取Symbol值
var value1 = Symbol.for('name');
var value2 = Symbol.for('name');
console.log(value1 === value2); // true
// 私有属性(不能被外界获取到)
var obj = {};
obj[Symbol('name')] = 'zhangl';
obj[Symbol('age')] = 18;
for (var key in obj) {
console.log(obj[key]); // 没有输出
}
// 防止对象重名属性污染
// 普通对象属性,前面的会被后面的覆盖
var obj2 = {};
obj2[Symbol('name')] = 'zhangl';
obj2[Symbol('name')] = 'zhoul';
console.log(obj2)// {Symbol(name): "zhangl", Symbol(name): "zhoul"}
复制代码
注:ES10新推出了一个BigInt类型,用于处理超过Number.MAX_SAFE_INTEGER的数
基本数据类型内存图
// 基本数据类型复制,是重新开辟一个新的空间存储新变量
var str1 = 'zhangl';
var str2 = str2;
复制代码
引用数据类型
- 存储位置:引用(栈)、值(堆)
- 存储空间:不固定,可动态调整
- 特点:修改一个引用的堆空间值,那么其他所有指向该堆空间的引用都会受到影响
Object(对象类型)
表示一组无序的集合
// 定义一个对象
var obj = {};
obj['name'] = 'zhangl';
obj['age'] = 18;
obj['gender'] = 'MAN';
// 判断类型
console.log(Object.prototype.toString.call(obj)); // "[object Object]"
console.log(obj.name); // 'zhangl'
// obj的引用赋值给obj2
var obj2 = obj;
// 改变obj2引用的堆空间值,obj引用的堆空间值也发生相应的改变
obj2.name = 'zhoul';
console.log(obj.name); // 'zhoul'
console.log(obj2.name); // 'zhoul'
复制代码
Array(数组类型)
表示一组有序的,类型相同(JS中能存储不同类型的数据)的集合
// 定义一个数组
var arr = [];
// 添加元素
for (var i = 0; i < 5; i++) {
arr.push(i);
}
// 判断类型
console.log(Object.prototype.toString.call(arr)); // "[object Array]"
console.log(arr); // [0, 1, 2, 3, 4];
// arr的引用赋值给arr2
var arr2 = arr;
// 改变arr2的长度,查看arr的长度
arr2.length = 2;
console.log(arr.length); // 2
console.log(arr2.length) // 2
复制代码
Function(函数类型)
// 声明函数
function fn1() {
console.log(this);
}
// 判断类型
console.log(typeof fn1); // "function"
// 定义函数
var fn2 = fn1;
// 给fn2添加name属性,查看fn1
fn2.age = 18;
console.log(fn1.age); // 18
console.log(fn2.age); // 18
复制代码
引用数据类型内存图
var obj1 = {
name: 'zhangl',
age: 18
};
var obj2 = obj1;
复制代码