数据类型的种类
- 基本数据类型:Undefined、Null、Boolean、Number、String、Symbol ( es6 新增,表示独一无二的值 ) 和 BigInt ( es10 新增 )
- 引用数据类型:Object ( Object本质上是由一组无序的键值对组成的 )。里面包含 function、Array、Date 等。JavaScript 不支持任何创建自定义类型的机制,而所有值最终都将是上述 8 种数据类型之一。
数据类型的存储方式
- 原始数据类型:直接存储在栈 ( stack ) 中,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储。
- 引用数据类型:同时存储在栈 ( stack ) 和堆 ( heap ) 中,占据空间大、大小不固定。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
数据类型的判断
typeof 返回数据类型的字符串表达
- typeof 对于原始类型来说,除了 null 都可以显示正确的类型
- typeof 对于对象来说,除了函数都会显示 object
- 不能区别 null 与 object / object 与 array
- 另外对于 null 来说,很多人会认为他是个对象类型,其实这是错误的。虽然 typeof null 会输出 object,但是这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象,然而 null 表示为全零,所以将它错误的判断为 object 。虽然现在的内部类型判断代码已经改变了,但是对于这个 Bug 却是一直流传下来。
console.log(typeof 2); // number
console.log(typeof true); // boolean
console.log(typeof 'str'); // string
console.log(typeof Symbol('protein'))// symbol
console.log(typeof []); // object []数组的数据类型在 typeof 中被解释为 object
console.log(typeof function(){}); // function
console.log(typeof {}); // object
console.log(typeof undefined); // undefined
console.log(typeof null); // object null 的数据类型被 typeof 解释为 object
instanceof 用于检测构造函数的 prototype 属性是否出现在某个实例的原型链上
- instanceof 左为实例,右为构造函数。即判断左是不是右的实例对象。内部机制是通过原型链来判断的
- instanceof 可以精准判断引用数据类型 Array,Function,Object,而基本数据类型不能被 instanceof 精准判断,因为它本身不是一个实例对象
console.log(2 instanceof Number); // false
console.log(new Number(2) instanceof Number) // true
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log(Symbol('protein') instanceof Symbol) // false 不支持语法:"new Symbol()"
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log({} instanceof Object); // true
// console.log(undefined instanceof Undefined);
// console.log(null instanceof Null);
constructor 构造函数
- 如果我创建一个对象,更改它的原型,constructor 就会变得不可靠
console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(Symbol('protein').constructor === Symbol) // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true
console.log(new Date().constructor === Date) // true
console.log(new RegExp().constructor === RegExp) // true
console.log(new Error().constructor === Error) // true
// 改变原型指向
function Fn(){};
Fn.prototype=new Array();
var f=new Fn();
console.log(f.constructor===Fn); // false
console.log(f.constructor===Array); // true
console.log(f instanceof Fn) // true
console.log(f instanceof Array) // true
Object.prototype.toString.call()
- 使用 Object 对象的原型方法 toString,使用 call 改变 this 指向
const a = Object.prototype.toString;
console.log(a.call(2)); // [object Number]
console.log(a.call(true)); // [object Boolean]
console.log(a.call('str')); // [object String]
console.log(a.call(Symbol())) // [object Symbol]
console.log(a.call([])); // [object Array]
console.log(a.call(function(){})); // [object Function]
console.log(a.call({})); // [object Object]
console.log(a.call(undefined)); // [object Undefined]
console.log(a.call(null)); // [object Null]
console.log(a.call(new Date())) // [object Date]
console.log(a.call(new Error())) // [object Error]
console.log(a.call(new RegExp())) // [object RegExp]
判断数据类型实例
- Number --- !isNaN(parseFloat(arg))
数据类型的转换
Boolean 布尔值的转换
- 转换为布尔值调用 Boolean() 方法
- !!运算符可以将右侧的值强制转换为布尔值,这也是将值转换为布尔值的一种简单方法
- 转 Boolean 除了 undefined,null,false,0,-0,NaN,‘ ’ 空字符串 其他的值都转为 true,包括所有的对象。
| 原始值 |
转换目标 |
结果 |
| number |
Boolean |
除了 0、-0、NaN 都为 true |
| string |
Boolean |
除了空字符串 ' ' 都为 true |
| undefined、null |
Boolean |
false |
| 引用类型 |
Boolean |
true |
| number |
string |
6 => '6' |
| Boolean、函数、Symbol |
string |
'true' |
| 数组 |
string |
[1, 2] => '1, 2' |
| 对象 |
string |
'[ object, Object ]' |
| string |
number |
'6' => 6, 'p' => NaN |
| 数组 |
number |
[] => 0, [ '6' ] => 6, 其他都是 NaN |
| null |
number |
0 |
| 非数组的引用类型 |
number |
NaN |
| Symbol |
number |
抛错 |
数字和字符串的转换
- 转换为数字调用 Number()、parseInt() 和 parseFloat() 方法
- 转换为字符串调用 .toString() 或者 String() 方法
四则运算符
- 加法 + 运算符的特点
- 运算中其中一方为字符串,那么就会把另一方也转化成字符串
- 如果一方不是字符串或者数字,那么会将他转化成数字或者字符串
console.log(1 + '1'); // 11
console.log(true + true); // 2
console.log(4 + [1, 2, 3]); // 41, 2, 3
console.log('a' + + 'b'); // aNaN 因为 + 'b' 为 NaN
- 非加法运算符来说只要其中一方不是数字就会被转化成数字
console.log(2 * '1'); // 2
console.log(2 * []); // 0
console.log(2 * ['2']); // 4
console.log(2 * [1, 2]); // NaN
== 和 === 运算符
- === 判断左右类型和值是不是都相等
- == 如果左右类型相等,则进行大小的比较,如果左右类型不相等会进行类型转换
- 判断是否在对比 null 和 undefined 如果是返回 true
- 判断两者的类型是否为 string 和 number,如果是就会将 string 转为 number
1 == '1' => 1 == 1 // true
- 判断一方是否为 boolean 如果是就会将其转换成 number 在进行判断
'1' == true => '1' == 1 => 1 == 1 // true
- 判断一方是否为 object 另一方是否为 string、number、symbol 是的话就会把 object 转换成原始类型在进行判断
'1'== { name: 'protein' } => '1' == '[ object, object ]' // false
[] == ![] => [] == false => [] == 0 => 0 == 0 // true