
人生就是学校。在那里,与其说好的教师是幸福,不如说好的教师是不幸。——海贝尔
数据
这个词,在生活中随处可见,如股票数据、人体数据、身份数据等,我们常常将一些有用的信息,称为数据。
每种语言都会对数据做分类,我们将数据的分类,叫作数据类型
,JS中将数据分为两大类原始数据类型
和引用数据类型
。
原始数据类型
不可在细分的数据类型
字符串类型
String
引号包裹的内容,JS中的引号
- 双引号:"
- 单引号:'
- 反引号(模板字符串):`
var string = "我是双引号包裹的字符串";
var string2 = '我是单引号包裹的字符串';
var string3 = `我是反引号包裹的字符串`;
数字类型
Number
JS中不区分浮点数和整数,统一使用number表示数字,JS使用IEEE-754双精度来表示小数
var num = 1;
var fNum = 1.0;
var dNum = 1.00;
var num3 = -1;
很多人经常会把数字和字符串用错,比如我以前常把手机号定义为数字类型,但其实它是字符串类型😁,
13506828279
我们都是幺三五零六八二八二七九
这样的读,如果是数字类型的我们应该读成一百三十五亿六百八十二万八千二百七十九
,当我们无法判断这个数据是字符串还是数字的时候,我们不妨通过这种读法来判断。
布尔类型
Boolean
用于表示真或假两种状态
- true:真
- false:假
var flag = true;
var flag = false;
undefined类型
Undefined
表示未定义,不存在
当一个变量声明,但未赋值时,值就为undefined
var a;
var b;
var c = undefined;
null 类型
Null
表示空值,不存在
var a = null;
虽然null和undefined都可以用来表示不存在的含义,但实际上它俩还是还是有点区别:
- null一般表示此处不应该有值,大部分是开发者手动设置
- undefined则表示此处应该有值,但现在还没有赋值
Symbol类型
Symbol
ES6提出的数据类型,表示一个唯一值
var sym1 = Symbol(1);
var sym2 = Symbol(1);
sym1 === sym2 // false
BigInt类型
ES10提案的新数据类型(由于新提出还没普遍使用,先忽略)
引用数据类型
字面量:直接书写的具体数据
对象类型
Object
具有名/值对的集合,JS中对象类型主要有内置对象
、普通对象
、浏览器对象
// ===== 普通对象 ======
// 对象字面量
var obj = {
name: 'value',
};
// 使用内置Object构造函数
var obj2 = new Object({
name: 'value',
});
// 使用Object.create
var obj3 = Object.create(null);
// ===== 内置对象 ======
var arr = [1, 2, 3]; // 数组对象
var regexp = /123/; // 正则对象
var strObj = new String(123); // 字符串对象
var numObj = new Number('123'); // 数字对象
var boolObj = new Boolean(1); // 布尔对象
var dateObj = new Date(); // 日期对象
...
// ===== 浏览器对象 ======
window
document
history
navigator
screen
location
函数
Function
带有名称和参数的Javascript代码段
// 函数声明
function fn1(name) {
console.log(name);
}
// 函数表达式
var fn2 = function(name) {
console.log(name);
};
// 使用内置Function构造函数
var fn3 = new Function('name', 'console.log(name)');
区别
这里忽略类型隐式转换,均采用同种数据类型的数据进行比较
- 数据相等判断:
- 原始数据比较值内容是否放相同
- 引用数据比较引用地址是否指向同一个堆存储空间
- 存储位置:
- 原始数据存放在
栈区
- 引用数据将
引用地址
存放在栈区
,将真正的数据存放在堆区
- 原始数据存放在
- 数据是否可修改:
- 原始数据不能被修改,具有不可变性
- 引用数据能被修改
- 数据的传递
- 原始数据进行值传递
- 引用数据进行引用地址的传递
数据类型判断
一. typeof
以字符串形式,返回数据的数据类型
-
优点:
- 能够精准的表示原始数据的类型(null除外)
- 容错性高,当判断目标为一个未声明的变量时,不会报错
-
缺点:
- 对引用数据的类型判断不精准
-
返回的结果
- "string"
- "number"
- "boolean"
- "undefined"
- "symbol"
- "object"
- "function"
typeof "very goood"; // "string"
typeof 1234; // "number"
typeof 1234.22; // "number"
typeof NaN; // "number"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof a; // "undefined"
typeof function test() {}; // "function"
typeof null; // "object"
typeof {}; // "object"
typeof []; // "object"
typeof null返回"object",主要原因
- JavaScript的的历史原因
- 计算机在运行代码前,会将代码转换为机器码0, 1。typeof通过机器码的低3~4位来判断数据类型,null的机器码为全0;Object类型数据的低三位也是0,这就导致了typeof误以为null也是Object类型数据 null机器码:00000000 00000000 00000000 00000
000
object机器码:xxxxxxxx xxxxxxxx xxxxxxxx xxxxx000
二. instanceof
返回布尔值(通过判断数据的构造函数,来判断数据的类型)
- 优点:
- 能够
较为
精准的表示引用数据类型 - 解决了null 为 Object 类型的问题
- 能够
- 缺点:
- 不能用于判断原始数据类型
- 不能判断通过
iframe
传递过来的数据的类型
var arr = [1, 2, 3, 4];
// 实际原理:arr.__proto__ === Arrar.prototype
arr instanceof Array; // true
// 但由于原型链继承,会出现以下判断不准确的情况
// 实现原理:
// step1:arr._proto__ === Object.prototype ⇒ false
// step2: arr.__proto__.__protot__ === Object.prototype ⇒ true
arr instanceof Object; // true
三. constructor
返回布尔值(通过判断数据的构造函数,来判断数据的类型)
- 优点:
- 能够精准的表示引用数据类型
- 解决了null 为 Object 类型的问题
- 缺点:
- 不能用于判断原始数据类型
- 不能判断通过
iframe
传递过来的数据的类型
var arr = [1, 2, 3, 4];
arr.constructor === Array; // true
arr.constructor === Object; // false
instanceof和constructor非常相似,只是在实现原理上有些不同
- instanceof 通过 a.__proto__和 A.prototype是否相等
- constructor 通过 a.constructor === A是否相等
四. toString
目前对原始数据类型和引用数据类型判断最为精准的方式
var toString = Object.prototype.toString;
toString.call('test'); // "[object String]"
toString.call(123); // "[object Number]"
toString.call(NaN); // "[object Number]"
toString.call(true); // "[object Boolean]"
toString.call(undefined); // "[object Undefined]"
toString.call(null); // "[object Null]"
toString.call([]); // "[object Array]"
toString.call({}); // "[object Object]"
toString.call(function a() {}); // "[object Function]"