js类型、值和变量

 JavaScript类型可以分为两类:原始类型和对象类型。原始类型包括数值、字符串、布尔值、及特殊值(null和undefined)。除这些原始类型外的值都是对象。

1 数值

js 的主要数值类型Number用于表示整数和近似数。

1.1 二进制浮点数与舍入错误

js 使用的IEEE-754浮点表示法是一种二进制表示法,向0.1,0.01等二进制浮点表示法无法精确表示。经过js数值有足够大的精度,能非常近似地表示0.1,单无法精确地表示。

这可能会导致一些问题,比如:

let x = 0.3 – 0.2;

let y = 0.2 – 0.1;

x == y; // false,两个值不一样

x === 0.1; // false,无法精确到0.1

这些问题并不是js独有的问题,而是所有使用二进制浮点数的编程语言共有的问题。

2 文本

js中表示文本的类型是String。

js最早的版本要求字符串字面量必须写在一行,到ES5,可以在每行末尾加一个反斜杠(\)从而把字符串字面量写到多行上。这个反斜杠后它后面的行终结符都不属于字符串字面量。ES6的反引号语法支持跨行字符串,而行终结符也是字符串字面量的一部分。

// 写在一行但表示两行的字符串:

“hello \n word”;

// 写在两行单只有一行的字符串:

“hello \

word”;

// 写在两行实际也是两行的字符串:

`hello

word`;

2.1 模版字面量

ES6及之后的版本,字符串字面量可以用反引号来定界,这称为模版字面量:

let s = `hello word`;

模版字面量可以包含任意js表达式,可以是任意数量,将这些表达式的值转换为字符串,然后再把这些字符串与反引号中的字面量组合:

let name = ‘黄兮言’;

let str = `Hello ${name}`; // hello 黄兮言

如果在开头的反引号前面有一个函数名(标签),那么模版字面量中的文本和表达式的值将作为参数传给这个函数。“标签化模版字面量”的值就是这个函数的返回值。

let name = ‘js’;

‘hello ’.concat`${name} !`; // 返回值是:hello js!

2.2 模式匹配

js 定义了正则表达式(RegExp)的数据类型。

一对斜杠之间的文本构成了正则表达式字面量。这对斜杠的第二个后面也可以跟一个或多个字母,用于修改模式的定义。

let str = “hello js! this is very goods.”;

let pattern = /\bvery\b/; //匹配very这个单词

pattern.test(str); // true,是否存在匹配

str.search(pattern); //第一个匹配的位置

str.match(pattern); // [“very”] 所有匹配项的数组

3 null 与 undefined

null

是“object”类型,表示某个值不存在。程序级别、正常或意料之中的空值。

undefined

表示一种更深层次的不存在,类型是“undefined”。表示一种系统级别、意料之外或类似错误的空值。

图 null 与 undefined的区别

null 与 undefined在实际的开发中经常被混用。

4 符号(Symbol)

是ES6新增的一种原始类型,用作非字符串的属性名。

let sym = Symbol(“prop”);

typeof sym; // symbol

let o {sym: ‘’}; //定义sym属性

Symbol函数永远不会返回相同的值,比如 Symbol(“a”) !== Symbol(“a)”;

这个特性常用来为对象添加新的属性,这样就无须担心可能重写已有的同名属性了。

Symbol.for()与Symbol()不同,Symbol.for()会返回一个与该字符串关联的符号值。相同字符串始终返回相同的值。

let s = Symbol.for(“a”);

let t = Symbol.for(“a”);

s === t; // true

s.toString(); // Symbol(a)

Symbol.keyFor(t); // a

5 类型转换

js对象到原始值转换到复杂性,主要在于某些对象类型有不止一种原始值的表示。比如Date对象可以用字符串表示,也可以用时间戳表示。

偏字符串

返回原始值,而且只要可能就返回字符串。

偏数值

返回原始值,而且只要可能就返回数值。

无偏好

不倾向任何原始值类型,由类定义自己的转换规则。

表 js定义的3种原始值转换的基本算法

对象到布尔值到转换:不需要使用上面的转换算法。所有对象都转换为true,包括空数组,甚至new Boolean(false)这样的包装对象。

5.1 toString()和valueOf()方法

所有的对象都会继承这两个方法。

toString():返回对象的字符串表示。很多类都定义了自己特有的toString()版本。

valueOf():把对象转换为代表对象的原始值(如果存在这样一个原始值)。对象是复合值,且多数对象不能真正通过一个原始值来表示,因此valueOf()方法默认情况下只返回对象本身。

5.2 对象到原始值转换算法

偏字符串算法

首先尝试toString()方法,如果方法存在且返回原始值,则返回该值,否则尝试valueOf()方法,如果存在且返回原始值,则返回该值,否则转换失败,报TypeError。

偏数值算法

与偏字符串算法类似,先尝试valueOf()再尝试toString()。

无偏好算法

取决于被转换对象的类,如果是Date类型,则使用偏字符串算法,否则使用偏数值算法。

表 js 定义的3种原始值转换的算法实现

空字符串转换数值为0,只有一个元素的数组转换为该元素对应的字符串。

Number([]); // 0

Number([99]); // 99

6 var与let

ES6 推荐使用let来代替var,在这之前,声明变量的唯一方式是使用var关键字。var与let的重要区别如下:

1)使用var声明的变量不具有块作用域。var的作用域仅限于包含函数的函数体。

2)如果在函数体外部使用var,则会声明一个全局变量。与let声明的全局变量有重要区别。var声明的被实现为全局对象的属性。全局对象可通过globalThis引用,假如在函数外面写了var x = 2; 则相对于 globalThis.x = 2;

3)与let变量不同,var多次声明同名变量是合法的。

4)var声明有一个独特的特性是作用域提升,在使用var声明变量时,该声明会被提高到包含函数的顶部。但是变量的初始化仍在代码所在位置完成。也就是在函数某处定义了一个var变量,则可在函数的任意位置使用,而不会报错。

你可能感兴趣的:(JavaScript权威指南,开发语言,javascript,node.js)