一.数据类型
JavaScript中有7中数据类型,分为基本数据类型和引用数据类型两大类:
1.基本数据类型
-
Number
(数字):整数或浮点数,例如3.14
或-42
。
-
String
(字符串):字符串是一系列字符,例如"Hello, World!"
。
-
Boolean
(布尔值):表示真或假,例如true
或false
。
-
Null
(空值):表示没有值,例如null
。
-
Undefined
(未定义):表示未定义的值,例如undefined
。
-
Symbol
(符号):表示唯一的标识符,例如Symbol('example)
。
2.引用数据类型
-
Object
(对象):是一组属性和方法的集合,例如{ name: 'Alice', age: 30 }
。
-
Array
(数组):是一个有序的集合,例如[1, 2, 3]
。
-
Function
(函数):是一段可重复使用的代码块,例如function add(a, b) { return a + b; }
。
-
Date
(日期):表示日期和时间,例如new Date()
。
-
RegExp
(正则表达式):用于匹配字符串的模式,例如/\d+/g
。
3.基本数据类型和引用数据类型区别
-
基本数据类型存在于栈
(stack)中,是不可变的,修改一个基本数据类型的值,实际上会创建一个新的值。
-
引用数据类型存在于堆
(heap)中,是可变的,引用数据类型的变量实际上是对值得引用,而不是值本身。
-
例如:如果两个变量引用同一个对象,当一个变量修改该对象时,另一个变量也会受到影响。
-
注:堆和栈的概念存在于数据结构和操作系统内存中,在数据结构中:
4.判断数据类型的方法
console.log(typeof 123); // number
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof {}); // object
console.log(typeof []); // object
console.log(typeof function(){}); // function
typeof
操作符用于检测变量的数据类型,返回一个字符串,其值为变量的数据类型。它能够正确地判断基本数据类型的数据类型,但不能用于判断引用类型,因为它会统一返回为object
。
console.log(new String("hello") instanceof String); // true
console.log(123 instanceof Number); // false
console.log(new Number(123) instanceof Number); // true
console.log(true instanceof Boolean); // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log({} instanceof Object); // true
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
instanceof
操作符用于检测一个对象是否为某个类的实例,它的原理是检查对象的原型链中是否存在指定类的原型。它不能用于判断基本数据类型。
Object.prototype.toString.call()
方法
console.log(Object.prototype.toString.call(123)); // [object Number]
console.log(Object.prototype.toString.call(true)); // [object Boolean]
console.log(Object.prototype.toString.call(undefined)); // [object Undefined]
console.log(Object.prototype.toString.call(null)); // [object Null]
console.log(Object.prototype.toString.call({})); // [object Object]
console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call(function(){})); // [object Function]
Object.prototype.toString
方法用于返回一个表示对象类型的字符串。它的原理是获取对象的内部[[Class]]属性,并将其转换为字符串形式。所有对象的内部[[Class]]属性都可以通过Object.prototype.toString.call(obj)
方法获取。
console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true
constructor
属性返回对象的构造函数。每个对象(除 null
和 undefined
)都有一个constructor
属性,可以通过该属性获取对象的构造函数。由于每个数据类型都对应一个构造函数,因此可以通过判断变量的 constructor
属性来判断变量的数据类型。
5.判断数组的方法
let arr = [1, 2, 3];
console.log(arr instanceof Array); // true
let arr = [1, 2, 3];
console.log(Array.isArray(arr)); // true
Object.prototype.toString.call()
方法
let arr = [1, 2, 3];
console.log(Object.prototype.toString.call(arr) === "[object Array]"); // true
注意: 第一种和第二种方式的效率较高,并且可以处理跨 iframe
的情况。第三种方式会出现误判,例如当一个类似数组的对象使用 Object.prototype.toString.call()
方法判断时,也会返回 “[object Array]”,因此需要谨慎使用。
6.instanceof的原理和实现
instanceof
用于检查一个对象是否是另一个对象的实例。它的语法如下:
object instanceof constructor //object是要检查的对象,constructor是一个函数或类,表示要检查的类型。
function myInstanceOf(object, constructor) {
let proto = Object.getPrototypeOf(object);
while (proto) {
if (proto === constructor.prototype) {
return true;
}
proto = Object.getPrototypeOf(proto);
}
return false;
}
let arr = [];
console.log(myInstanceOf(arr, Array)); // true
console.log(myInstanceOf(arr, Object)); // true
console.log(myInstanceOf(arr, RegExp)); // false
该方法首先获取object
的原型对象,并循环遍历原型链,逐级比较每个原型对象是否等于constructor.prototype
。如果找到了相等的原型对象,则返回true
,否则返回false
。
7.(0.1+0.2 ! == 0.3)问题
-
原因
使用 IEEE 754 标准来表示浮点数,该标准使用二进制来表示小数。因为在二进制中无法准确地表示一些十进制小数,因此在进行浮点数计算时会出现舍入误差,从而导致某些计算结果不准确。
0.1
在十进制中可以准确地表示为 0.1
,但在二进制中表示为 0.0001100110011001100110011001100110011001100110011...
(循环节为 0011
),其中小数点后的数值是无限循环的。同样地,0.2 在二进制中也是无限循环的,表示为 0.0011001100110011001100110011001100110011001100110...
(循环节为 0011
)
-
解决方案
-
方案1:Math.abs()
function isEqual(num1, num2) {
return Math.abs(num1 - num2) < Number.EPSILON;
}
// Number.EPSILON 属性表示 1 与Number可表示的大于 1 的最小的浮点数之间的差值。
console.log(isEqual(0.1 + 0.2, 0.3); // 输出 true
-
方案2:toFixed()
var result = (0.1 + 0.2).toFixed(1); // 将小数点后一位四舍五入
console.log(result); // 输出 0.3
注意:``toFixed()
在Chrome 浏览器
中存在精度问题(工作中踩的坑
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)