JavaScript 允许我们像对象一样使用基本类型(字符串,数字等)。
基本类型还提供调用方法等。我们会尽快研究这些,但首先我们会看看它是如何工作的,毕竟基本类型不是对象(在这里我们会分析的更加清楚)。
我们来看看基本类型和对象之间的关键区别。
基本类型
- 是原始类型中的一种值。
- 在 JavaScript 中有 6 种基本类型:
string
、number
、boolean
、symbol
、null
和undefined
。
对象类型
- 能够存储多个值作为属性。
- 可以使用大括号
{}
创建对象,例如:{name: "John", age: 30}
。JavaScript 中还有其他种类的对象,例如函数就是对象。
关于对象的最好的事情之一是我们可以存储一个函数作为它的一个属性:
let john = {
name: "John",
sayHi: function() {
alert("Hi buddy!");
}
};
john.sayHi(); // Hi buddy!
所以我们在这里创建了一个包含 sayHi
方法的对象 john
。
许多内置对象已经存在,例如那些处理日期,错误,HTML 元素等的内置对象。它们具有不同的属性和方法。
但是,这些特性都是有成本的!
对象比基本类型“更重”。他们需要额外的资源来支持运作。但是,由于属性和方法在编程中非常有用,JavaScript 引擎会尝试优化它们以减少额外的负担。
作为对象的基本类型
以下是 JavaScript 创建者面临的悖论:
- 人们想对字符串或数字这样的基本类型做很多事情,要是能通过其方法完成就太好了。
- 基本类型必须尽可能的简单轻量。
而解决方案看起来多少有点尴尬,如下:
- 基本类型仍然是原始数据。如预期相同,提供单个值
- JavaScript 允许访问字符串,数字,布尔值和符号的方法和属性。
- 当进行访问时,创建一个特殊的“包装对象”,它提供额外的功能,运行后即被销毁。
“包装对象”对于每种基本类型调用都是不同的,如String
, Number
, Boolean
和 Symbol
。因此,他们提供了不同的方法。
例如,方法 str.toUpperCase() 返回一个大写的字符串。
用法演示如下:
let str = "Hello";
alert( str.toUpperCase() ); // HELLO
很简单,对吧?以下是 str.toUpperCase()
实际发生的情况:
- 字符串
str
是一个基本类型。所以在访问它的属性时,会即刻创建一个包含字符串字面值的特殊对象,并且具有有用的方法,例如toUpperCase()
。 - 该方法运行并返回一个新的字符串(由
alert
显示)。 - 特殊对象被销毁,只留下基本类型
str
。
所以基本类型可以提供方法,但它们依然是轻量级的。
JavaScript 引擎高度优化了这个过程。它甚至可能跳过创建额外的对象。但是它仍然必须遵守规范,并且表现得好像它创造了一样。
数字有其自己的方法,例如,toFixed(n) 将数字四舍五入到给定的精度:
let n = 1.23456;
alert( n.toFixed(2) ); // 1.23
String/Number/Boolean
仅供内部使用像 Java 这样的一些语言允许我们使用 new Number(1)
或 new Boolean(false)
等语法明确地为基本类型创建“包装对象”。
在 JavaScript 中,由于历史原因,这也是可以的,但极其不推荐。因为这样会出问题。
例如:
alert( typeof 1 ); // "number"
alert( typeof new Number(1) ); // "object"!
同样的,zero
,是一个对象,alert 将显示出来:
let zero = new Number(0);
if (zero) { // zero is true, because it's an object
alert( "zero is truthy?!?" );
}
另一方面,不使用 new
的 String/Number/Boolean
是一个明智的选择。它们将一个值转换为相应的类型:转成 string,number,或 boolean(原始类型)。
例如,下面完全是有效的:
let num = Number("123"); // 将字符串转成数字
特殊的基本类型 null
和 undefined
是个例外。他们没有相应的“包装对象”,也没有提供任何方法。从某种意义上说,他们是“最原始的”。
尝试访问这种值的属性会导致错误:
alert(null.test); // error
总结
-
除
null
和undefined
以外的基本类型都提供了许多有用的方法。我们将在即将到来的章节中研究这些内容。 -
从形式上讲,这些方法通过临时对象工作,但 JavaScript 引擎可以很好地调整以优化内部,因此调用它们并不需要太高的成本。
评论
<code>
标签插入只有几个词的代码,插入多行代码可以使用<pre>
标签,对于超过 10 行的代码,建议你使用沙箱(plnkr,JSBin,codepen…)