一、数据类型
最新的 ECMAScript 标准定义了 8 种数据类型:
1.七种简单数据类型(也称 原始数据类型)
- Undefined,一个特殊的关键字,表示变量未赋值时的属性。
- Null ,一个特殊的关键字,逻辑上null 表示一个空对象指针,这也是给typeof 传递一个null ,会返回'object '的原因。另外null 是由undefined 派生而来的,ECMA将它们定义为表面相等,所以null == undefined 为 true。
- 布尔值(Boolean) ,有 2 个值分别是:true 和 false。 要将一个其他类型的值转换为布尔值,可以调用Boolean()转型函数。转换规则如下:
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
String | 非空字符串 | ""(空字符串) |
Number | 非零数值(包括无穷值) | 0、NaN |
Object | 任意对象 | null |
Undefined | N/A | undefined |
- 数字(Number ),整数或浮点数,例如: 42、0、-3.1415926、0x1f(16进制)、NaN(不是数值,No a Number)等。具备有效数值范围,若超出,可以使用BigInt数据类型。
- 字符串(String),一串表示文本值的字符序列。可以通过toString()或 + ''的方式转换为字符串类型。
- 符号(Symbol),ECMAScript 6 中新增的数据类型,一种实例是唯一且不可改变的数据类型。
- 任意精度的整数 (BigInt),可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。
2.一种复杂数据类型(也称 引用数据类型)
引用数据类型Object,包括
- 对象(Object):键值对的集合。
- 数组(Array):有序的值的列表。
- 函数(Function):可执行的代码块。
- 日期(Date):表示日期和时间的对象。
- 正则表达式(Regular Expression):用于模式匹配的对象。
二、基本数据类型和引用数据类型的特点
1.基本类型
基本数据类型存储在栈中(栈区指内存里的栈内存),占用的内存较小,可以直接操作它们的值,而且是按值传递的,即一个变量的值是直接存储在变量中的,它们的比较也是按值进行的。
例如:有以下几个基本类型的变量:
ini
var name = 'jozo';
var city = 'guangzhou';
var age = 22;
那么它的存储结构如下图:
栈区包括了变量的标识符和变量的值。
2.引用类型
引用类型的对象存储于堆中,占用的内存较大,不能直接操作它们的值,而是需要通过引用来访问它们的属性和方法,它们的赋值和比较也是按引用进行的,即一个变量的值是一个指向实际对象的引用。
例如:有以下几个对象:
ini
js
复制代码
var person1 = {name:'jozo'};
var person2 = {name:'xiaom'};
var person3 = {name:'xiaoq'};
则这三个对象的在内存中保存的情况如下图:
由于基本类型和引用类型的差异,它们在使用上也有所不同。当我们对基本类型进行赋值、传参和比较时,只是对它们的值进行操作,而不会影响其他变量的值。但是对于引用类型,如果我们将一个引用类型变量赋值给另一个变量,那么两个变量实际上是指向同一个对象的引用。这意味着,如果我们在其中一个变量上进行修改,另一个变量也会受到影响。
例如: 1.基本类型和引用类型在参数传递中的区别
ini
let a = 10;
let obj = { value: 20 };
function change(x, y) {
x = 20;
y.value = 30;
}
change(a, obj);
console.log(a); // 输出 10
console.log(obj.value); // 输出 30
解析:基本类型的参数传递是值传递,函数内部对参数的修改不会影响原变量的值,因为函数内部修改的是参数的副本。而引用类型的参数传递是引用传递,函数内部对参数的修改会影响原变量的值,因为函数内部修改的是参数指向的对象的属性值。
2.基本类型和引用类型在赋值中的区别
ini
let a = 10;
let b = a;
a = 20;
console.log(b); // 输出 10
let obj1 = { value: 10 };
let obj2 = obj1;
obj1.value = 20;
console.log(obj2.value); // 输出 20
解析:基本类型的赋值是将变量的值复制一份给新变量,修改其中一个变量的值不会影响另一个变量的值。而引用类型的赋值是将变量的指针复制一份给新变量,两个变量指向同一个对象,修改其中一个变量指向的对象的属性值会影响另一个变量指向的对象。
3.基本类型和引用类型的相等比较
ini
console.log(10 === 10); // 输出 true
console.log({} === {}); // 输出 false
let obj1 = { value: 10 };
let obj2 = obj1;
console.log(obj1 === obj2); // 输出 true
解析:基本类型的相等比较是值比较,只有两个变量的值完全相同才相等。而引用类型的相等比较是指针比较,只有两个变量指向同一个对象才相等。
4.基本类型和引用类型的类型判断
javascript
console.log(typeof 10); // 输出 "number"
console.log(typeof {}); // 输出 "object"
let obj = { value: 10 };
console.log(obj instanceof Object); // 输出 true
解析:使用 typeof 运算符可以判断基本类型的类型,使用 instanceof 运算符可以判断引用类型的类型。因为引用类型的类型是 Object,所以 instanceof Object 运算符可以用来判断一个变量是否为引用类型。
三、typeof 和 instanceof
typeof
与instanceof
都是判断数据类型的方法,区别如下:
typeof
会返回一个运算数的基本类型 ,instanceof
返回的是布尔值instanceof
可以准确判断引用数据类型 ,但是不能正确判断原始数据类型typeof
可以判断原始数据类型 (null
除外),但是无法判断引用数据类型 (function
除外)
那为什么typeof判断null为object?
这是 JavaScript
语言的一个历史遗留问题,在第一版JS
代码中用32位比特来存储值,通过值的1-3
位来识别类型,前三位为000
表示对象类型。而null
是一个空值,二进制表示都为0,所以前三位也就是000
,所以导致 typeof null
返回 "object"
四、instanceof 运算符的实现原理
instanceof
运算符适用于检测构造函数的prototype
属性上是否出现在某个实例对象的原型链上
instanceof
运算符的原理是基于原型链的查找。当使用 obj instanceof Constructor
进行判断时,JavaScript
引擎会从 obj
的原型链上查找 Constructor.prototype
是否存在,如果存在则返回 true
,否则继续在原型链上查找。如果查找到原型链的顶端仍然没有找到,则返回 false
。
instanceof
运算符只能用于检查某个对象是否是某个构造函数的实例,不能用于基本类型的检查,如string
、number
等。
五、null和undefined区别
Undefined
和 Null
都是基本数据类型,这两个基本数据类型分别都只有一个值,就是 undefined
和 null
。
- undefined 代表的含义是未定义 ,一般变量声明了但还没有定义 的时候会返回
undefined
,typeof
为undefined
- null 代表的含义是空对象 ,null主要用于赋值给一些可能会返回对象的变量,作为初始化,
typeof
为object
ini
null == undefined // true
null === undefined //false
六、0.1+0.2 ! == 0.3
因为浮点数运算的精度问题。在计算机运行过程中,需要将数据转化成二进制,然后再进行计算。 因为浮点数自身小数位数的限制而截断的二进制在转化为十进制,就变成0.30000000000000004,所以在计算时会产生误差。
解决方案
-
将其先转换成整数,再相加之后转回小数。具体做法为先乘10相加后除以10
inilet x=(0.1*10+0.2*10)/10; console.log(x===0.3)
-
使用
number
对象的toFixed
方法,只保留一位小数点。scss(n1 + n2).toFixed(2)
七、判断数组的方式有哪些
-
通过
Object.prototype.toString.call()
做判断javascriptObject.prototype.toString.call(obj).slice(8,-1) === 'Array';
-
通过原型链做判断
iniobj.__proto__ === Array.prototype;
-
通过ES6的
Array.isArray()
做判断iniArray.isArrray(obj);
-
通过
instanceof
做判断javascriptobj instanceof Array