Carmineprince's Blog
首页
    • HTML
    • CSS
    • JavaScript
    • Vue
    • React
    • TypeScript
    • Node
    • Flutter
    • Electron
    • Python
    • 运维
    • 重学前端
  • 分类
  • 标签
  • 归档

Ziqi Wang

胡思乱想程序员
首页
    • HTML
    • CSS
    • JavaScript
    • Vue
    • React
    • TypeScript
    • Node
    • Flutter
    • Electron
    • Python
    • 运维
    • 重学前端
  • 分类
  • 标签
  • 归档
  • 关于类型,有哪些细节需要注意
    • 为什么有的编程规范要求用 void 0 代替 undefined?
    • 字符串有最大长度吗?
    • 0.1 + 0.2 不是等于 0.3 么?为什么 JavaScript 里不是这样的?
    • ES6 新加入的 Symbol 是个什么东西?
    • 为什么给对象添加的方法能用在基本类型上?
  • JavaScript是面向对象还是基于对象
  • 《重学前端》
carmineprince
2021-10-22

关于类型,有哪些细节需要注意

# 关于类型,有哪些细节需要注意

  • 为什么有的编程规范要求用 void 0 代替 undefined?
  • 字符串有最大长度吗?
  • 0.1 + 0.2 不是等于 0.3 么?为什么 JavaScript 里不是这样的?
  • ES6 新加入的 Symbol 是个什么东西?
  • 为什么给对象添加的方法能用在基本类型上?

# 为什么有的编程规范要求用 void 0 代替 undefined?

因为在JavaScript中undefined并不是保留字段,因此undefined可能会作为变量名进行赋值,从而污染数据。

const undefined = 'nothing'
// 此时给其他变量赋值undefined将会出现数据污染
let tempNumber = undefined // nothing,不是想要的结果
let tempNumber = void 0 // tempNumber = undefined,这才是想要的结果
1
2
3
4

# 字符串有最大长度吗?

String有最大长度是2^53 - 1,但是这个最大长度,并不是字符数。

因为 String 的意义并非“字符串”,而是字符串的 UTF16 编码,我们字符串的操作 charAt、charCodeAt、length 等方法针对的都是 UTF16 编码。所以,字符串的最大长度,实际上是受字符串的编码长度影响的。

Note:现行的字符集国际标准,字符是以 Unicode 的方式表示的,每一个 Unicode 的码点表示一个字符,理论上,Unicode 的范围是无限的。UTF 是 Unicode 的编码方式,规定了码点在计算机中的表示方法,常见的有 UTF16 和 UTF8。 Unicode 的码点通常用 U+??? 来表示,其中 ??? 是十六进制的码点值。 0-65536(U+0000 - U+FFFF)的码点被称为基本字符区域(BMP)。

# 0.1 + 0.2 不是等于 0.3 么?为什么 JavaScript 里不是这样的?

在JavaScript中的数字类型使用双精度,在其他语言中是double类型。Number类型有18437736874454810627(即 2^64-2^53+3) 个值。

为了表达几个额外的语言场景(比如不让除以0出错,而引入了无穷大的概念),规定了几个额外情况:

  • NaN,占用了 9007199254740990,这原本是符合 IEEE 规则的数字;
  • Infinity,无穷大;
  • -Infinity,负无穷大。

另外,值得注意的是,JavaScript 中有 +0 和 -0,在加法类运算中它们没有区别,但是除法的场合则需要特别留意区分,“忘记检测除以 -0,而得到负无穷大”的情况经常会导致错误,而区分 +0 和 -0 的方式,正是检测 1/x 是 Infinity 还是 -Infinity。

根据双精度浮点数的定义,Number 类型中有效的整数范围是 -0x1fffffffffffff 至 0x1fffffffffffff,所以 Number 无法精确表示此范围外的整数。

非整数的 Number 类型无法用 ==(=== 也不行) 来比较:

 console.log( 0.1 + 0.2 == 0.3); // false
1

这里输出的结果是 false,说明两边不相等的,这是浮点运算的特点,浮点数运算的精度问题导致等式左右的结果并不是严格相等,而是相差了个微小的值。

所以实际上,这里错误的不是结论,而是比较的方法,正确的比较方法是使用 JavaScript 提供的最小精度值:

console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON);
1

Math.abs(x):获取x的绝对值 Number.EPSILON: 表示 1 与Number可表示的大于 1 的最小的浮点数之间的差值。

# ES6 新加入的 Symbol 是个什么东西?

Symbol 是 ES6 中引入的新类型,它是一切非字符串的对象 key 的集合,在 ES6 规范中,整个对象系统被用 Symbol 重塑。

Symbol 可以具有字符串类型的描述,但是即使描述相同,Symbol 也不相等。

var mySymbol = Symbol("my symbol"); // 创建
1

# 为什么给对象添加的方法能用在基本类型上?

JavaScript 中的几个基本类型,都在对象类型中有一个“亲戚”。它们是:

  • Number;
  • String;
  • Boolean;
  • Symbol;

3 和 new Number(3) 是完全不同的值:

  • 3是Number类型
  • new Number(3)是对象类型

Number、String和Boolean,三个构造器是两用的,当跟new搭配时,他们产生对象,当直接调用时,他们标识强制类型转换。

Symbol 函数比较特殊,直接用 new 调用它会抛出错误,但它仍然是 Symbol 对象的构造器。

JavaScript 语言设计上试图模糊对象和基本类型之间的关系,我们日常代码可以把对象的方法在基本类型上使用,比如:

console.log("abc".charAt(0)); //a
1

甚至我们在原型上添加方法,都可以应用于基本类型,比如以下代码,在 Symbol 原型上添加了 hello 方法,在任何 Symbol 类型变量都可以调用。

    Symbol.prototype.hello = () => console.log("hello");
 
    var a = Symbol("a");
    console.log(typeof a); //symbol,a 并非对象
    a.hello(); //hello,有效
1
2
3
4
5

答:.运算符提供了装箱操作,它会根据基础类型构造一个临时对象,使得我们能在基础类型上调用对应对象的方法。

#javascript#笔记#重学前端#极客时间
上次更新: 10/22/2021, 5:55:53 PM
JavaScript是面向对象还是基于对象

JavaScript是面向对象还是基于对象→

最近更新
01
pc端rem配置
03-02
02
使用动态变量ts报错的解决
02-25
03
React Hook详解
02-18
更多文章>
Theme by Vdoing | Copyright © 2021-2022 Carmineprince | 鲁ICP备2021046263号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式