你不知道的JavaScript(中)

2023-01-03  本文已影响0人  普通市民王二狗

1 类型

1.1 js有七种内置类型

1 undefined 2 boolean 3 number 4 string 5 object 6 null 7 symbol

但是null稍微特殊
typeof null === "object"; // true
所以如果检测一个值是否为null,需要
var a = null;
(!a && typeof a === "object"); // true

1.2 JavaScript 中的变量是没有类型的,只有值才有。变量可以随时持有任何类型的值

换个角度来理解就是,JavaScript 不做”类型强制“。
在对变量执行 typeof 操作时,得到的结果并不是该变量的类型,而是该变量持有的值的类
型,因为 JavaScript 中的变量没有类型。

1.3 undefined && undeclared

undefined 是值的一种。undeclared 则表示变量还没有被声明过。
遗憾的是,JavaScript 却将它们混为一谈,在我们试图访问 "undeclared" 变量时这样报
错:ReferenceError: a is not defined,并且 typeof 对 undefined 和 undeclared 变量都返回
"undefined"。

typeof undefined == "undefined"
typeof undeclared == "undefined"

2 值

简单值(即标量基本类型值,scalar primitive)总是通过值复制的方式来赋值 / 传递,包括
null、undefined、字符串、数字、布尔和 ES6 中的 symbol。
复合值(compound value)——对象(包括数组和封装对象,参见第 3 章)和函数,则总 是通过引用复制的方式来赋值 / 传递。

var a = 2;
var b = a; // b是a的值的一个副本
b++;
a; // 2
b; // 3
var c = [1,2,3];
var d = c; // d是[1,2,3]的一个引用
d.push( 4 );
c; // [1,2,3,4]
d; // [1,2,3,4]

在上述代码中,a,b分别指向 值 的两个复本。a,b的改变互不影响。
c,d分别指向 值 的两个引用,而引用都指向同样的一个对象 [1,2,3],所以c,d的改变是对于所指对象的改变。

function foo(x) {
 x.push( 4 );
 x; // [1,2,3,4]
 // 然后
 x = [4,5,6];
 x.push( 7 );
 x; // [4,5,6,7]
}
var a = [1,2,3];
foo( a );
a; // 是[1,2,3,4],不是[4,5,6,7]

其中,a将 [1,2,3]的引用的复本,传给了变量x。变量x 指向 对象[1,2,3]的引用的复本,可以修改其值。
随后,变量x指向 更改为[4,5,6]的引用,这一操作并不会影响a的引用。

3 原生函数

3.1

new String("abc") 创建的是字符串 "abc" 的封装对象,而非基本类型值 "abc"。

var a = new String( "abc" );
typeof a; // 是"object",不是"String"
a instanceof String; // true
Object.prototype.toString.call( a ); // "[object String]"

3.2 内部属性 [[Class]]

这个属性无法直接访问,
一般通过 Object.prototype.toString(..) 来查看。例如:

Object.prototype.toString.call( [1,2,3] ); // "[object Array]"
Object.prototype.toString.call( /regex-literal/i ); // "[object RegExp]"

4 强制类型转换

将值从一种类型转换为另一种类型通常称为类型转换(type casting),这是显式的情况;隐式的情况称为强制类型转换(coercion)。
也可以这样来区分:类型转换发生在静态类型语言的编译阶段,而强制类型转换则发生在动态类型语言的运行时(runtime)。

上一篇下一篇

猜你喜欢

热点阅读