前端知识笔记
- undefined 和 void 0 的区别
undefined 类型表示未定义,它的类型只有个值,就是undefined。
void 运算符 能对给定的表达式进行求值,并返回undefined,void后面跟任意表达式返回的都是undefined,例如void(1),void('hahaha'),至于写void 0 是因为 void 0 是表达式最短的一个,
当然 void 1 同理
- 为什么有的编程规范要求用 void 0 代替 undefined?
任何变量在赋值之前都是undefined类型,但是在JavaScript的代码中undefined是一个变量,而并非是一个关键字。这是JavaScript 语言公认的设计失误之一,所以我们为了避免无意中被篡改,
使用void运算来把任意一个表达式变成undefined的值,并且void 是不能被重写的,用void 0 代替undefined 能节省很多字节,好多的js压缩工具在压缩过程中都是用void 0 代替了undefined
- JavaScript中基本类型 String
String 用于表示文本数据。String 有最大长度是 2^53 - 1,并且String的意义并不是字符串,而是字符串的 UTF16 编码,我们字符串的操作 charAt、charCodeAt、length 等方法针对的都是
UTF16 编码。所以,字符串的最大长度,实际上是受字符串的编码长度影响的,
JavaScript 中的字符串是永远无法变更的,一旦字符串构造出来,无法用任何方式改变字符串的内容,所以字符串具有值类型的特征。例如:
let str1 = 'dddd' d[1] = 'a' console.log(str1) // dddd let str2 = ''𠮷' console.log(str2.length) // str2.length === 2
即使使用的是字符串的splice,split 方法,他返回的也只是一个新对象,而不是最一开始的字符串,也就是说 所有字符串身上的方法,都是返回新的值,而不是操作字符串本身
- JavaScript中基本类型Number
Number跟字符串一样,也有长度的限制,在JavaScript中,Number的最大长度为18437736874454810627,也就是2^64-2^53+3
JavaScript 中的 Number 类型基本符合 IEEE 754-2008 规定的双精度浮点数规则,但是 JavaScript 为了表达几个额外的语言场景(比如不让除以 0 出错,而引入了无穷大的概念),
规定了几个例外情况:
NaN,占用了 9007199254740990,这原本是符合 IEEE 规则的数字;
Infinity,无穷大;
-Infinity,负无穷大。
例如:
console.log(0/0) // NaN
console.log(1/0) // Infinity console.log(-1/0) // -Infinity console.log(1/0) // Infinity console.log(1/-0) // -Infinity
还有一个关于JavaScript中比较经典的问题:0.1 + 0.2 === 0.3
这里输出的结果是 false,说明两边不相等的,这是浮点运算的特点,浮点数运算的精度问题导致等式左右的结果并不是严格相等,而是相差了个微小的值。
控制台打印为:
console.log(0.1 + 0.2) // 0.30000000000000004
但是我们可以用JavaScript 提供的最小精度值 - Number.EPSILON来比较:如
console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON) // true
这样比较左右两边的差是否小于最小精度
- 类型转换
类型转换对于我们前端开发人员来说不算什么陌生的东西,比如
console.log('1' == 1) // ture
console.log( 1 == true) // true
当然这里使用的是相等,不是使用的全等,相等和全等的区别这里就不在详细做笔记了,主要区别就是相等只比较值,而全等还会比较类型,言归正传,我们都知道这样比较结果为true,
但是具体做了什么东西呢?这里就引出了一个概念 ---- 装箱与拆箱
-
- 装箱:把基本数据类型转化为对应的引用数据类型的操作
例如:
const str1 = 'abc'
const str2 = str1.indexOf('a')
但是这里有一个问题,str1是一个基本数据类型,他不是对象,也不应该有方法,但是JavaScript内部为我们做了一些处理,也就是装箱,让他能够调用方法,具体实现的机制如下:
(1)创建String类型的一个实例
(2)在实例上调用指定的方法
(3)销毁这个实例
例如:
const str1 = 'aaaa' let newStr = str1.substring(2) 简易演示: var s1 = new String(str1); // 新建临时变量显示的把基本数据类型变成引用类型 newStr = s1.substring(2); // 进行操作 s1 = null; // 销毁临时变量 ( 把对象设置为null 后,证明该对象已经没有对对象的引用了,js的垃圾回收机制会自动回收该对象 )
// 个人理解
那既然有装箱,也同样存在拆箱
例如:
let num1 = new Number(123) let str1 = new String('123') // 对这两个变量进行typeof操作,打印如下 console.log(typeof num1) // object console.log(typeof str1) // object // 由此可证明这两个变量为引用类型,接下来我们对他进行拆箱 num1 = num1.valueOf() str1 = str1.toString() console.log(typeof num1) // number console.log(typeof str1) // string
如代码所示,我们对一个引用类型数据进行valueOf()或者toString() 操作的话,就可以把引用类型数据改为基本类型数据
- JavaScript中的引用类型Object
Object 是 JavaScript 中最复杂的类型,也是 JavaScript 的核心机制之一。Object 表示对象的意思,它是一切有形和无形物体的总称,并且对象里面还有基本类型的亲戚:
Number;String;Boolean;Symbol;这四个里面前三个都可以通过new 操作符进行调用,当用new 调用时代表生成对象,直接使用表示强制类型转化:例:
const num = new Number(1) // 代表创建一个Number对象 console.log(num) // Number { 1 } console.log(Number(num)) // 1
Symbol比较特殊,直接使用New操作符会报错,原因是:围绕原始数据类型创建一个显式包装器对象从 ECMAScript 6 开始不再被支持。 然而,现有的原始包装器对象,
如 new Boolean、new String以及new Number,因为遗留原因仍可被创建。所以直接使用New操作符会报错,但是他仍然是Symbol 对象的构造器。

浙公网安备 33010602011771号