数据类型

JavaScript 中的数据(值)都具有特定的类型。例如:

var msg = 'bufanxueyuan';
var age = 24;
// 两个变量存储的数据 就属于不同的类型

在 JavaScript 中数据类型分为两大类:

  • 基本(原始、简单)数据类型
  • 引用(复杂)数据类型

基本数据类型有:Number、String、Boolean、null、undefined

引用数据类型有:Array(数组)、Object(对象)、Function(函数)

我们可以将任何类型的值存入变量。例如,一个变量可以在前一刻是个字符串,下一刻就存储一个数字:

// 没有错误 动态类型语言
var message = "hello";
message = 123456;

允许这种操作的编程语言,例如 JavaScript,被称为“动态类型”(dynamically typed)的编程语言,意思是虽然编程语言中有不同的数据类型,但是你定义的变量并不会在定义后,被限制为某一数据类型,而是动态可改变的。

基本类型

Number 类型

var n = 123;
n = 12.345;

number 类型包含整数和浮点数。

数字可以有很多操作,比如,乘法 *、除法 /、加法 +、减法 - 等等。

“特殊数值”:Infinity-InfinityNaN

  • Infinity 代表数学概念中的 无穷大 ∞。是一个比任何数字都大的特殊值。

    我们可以通过除以 0 来得到它:

alert( 1 / 0 ); // Infinity

或者在代码中直接使用它:

alert( Infinity ); // Infinity
  • NaN 代表一个计算错误。它是一个不正确的或者一个未定义的数学操作所得到的结果,比如:
alert( "not a number" / 2 ); // NaN,这样的除法是错误的

NaN 是粘性的。任何对 NaN 的进一步操作都会返回 NaN

alert( "not a number" / 2 + 5 ); // NaN

所以,如果在数学表达式中有一个 NaN,会被传播到最终结果。

数学运算是安全的

在 JavaScript 中做数学运算是安全的。我们可以做任何事:除以 0,将非数字字符串视为数字,等等。只不过不合理的运算,我们会得到 NaN 的结果。

不精确的计算

alert( 0.1 + 0.2 ); // 0.30000000000000004

一个数字以其二进制的形式存储在内存中,一个 1 和 0 的序列。但是在十进制数字系统中看起来很简单的 0.10.2 这样的小数,实际上在二进制形式中是无限循环小数。

使用二进制数字系统无法 精确 存储 0.10.2,就像没有办法将三分之一存储为十进制小数一样。

IEEE-754 数字格式通过将数字舍入到最接近的可能数字来解决此问题。这些舍入规则通常不允许我们看到“极小的精度损失”,但是它确实存在。

不仅仅是 JavaScript,许多其他编程语言也存在同样的问题。PHP,Java,C,Perl,Ruby 给出的也是完全相同的结果,因为它们基于的是相同的数字格式。

String 类型

JavaScript 中的字符串都被括在引号里。

在 JavaScript 中,有三种包含字符串的方式。

  1. 双引号:"Hello"

  2. 单引号:'Hello'

双引号和单引号都是“简单”引用,在 JavaScript 中两者几乎没有什么差别。

var str = "Hello";
var str2 = 'Single quotes are ok too';
var phrase = `can embed another`;

反引号是ES6新增的

Boolean 类型(逻辑类型)

boolean 类型仅包含两个值:truefalse

这种类型通常用于存储表示 yes 或 no 的值:true 意味着 “yes,正确”,false 意味着 “no,不正确”。

// 我们想用一个变量表达是否是开发环境, 就可以用布尔值表达

var isDev = true; // 是,代表是开发环境的意思

// 那么false 代表不是

“null” 值

它是一个独立的类型,只包含 null 值:

var age = null;

相比较于其他编程语言,JavaScript 中的 null 仅仅是一个代表“无”、“空”或“值未知”的特殊值。

上面的代码表示 age 是未知的。

“undefined” 值

它也是一个独立的类型,只包含 undefined 值:

undefined 的含义是 未被赋值

如果一个变量已被声明,但未被赋值,那么它的值就是 undefined

var age;

alert(age); // 弹出 "undefined"

引用数据类型

其他所有的数据类型都被称为“原始类型”,因为它们的值只包含一个单独的内容(字符串、数字或者其他)。相反,引用数据类型 则用于储存数据集合和更复杂的实体。

// 数组:表示同一类数据的集合
var arr = [24,23,21,19,20]; // 存储年龄的集合

// 对象:
var user = {
    name:'张三',
    age:24
}
// 函数:
function foo(){
    alert('hello')
}

基本类型和引用类型的区别

var message = "Hello!";
var phrase = message;

//结果我们就有了两个独立的变量,每个都存储着字符串 "Hello!"。

对象不是这样的。

变量存储的不是对象自身,而是该对象的“内存地址”,换句话说就是一个对该对象的“引用”。

下面是这个对象的示意图:

var user = {
  name: "John"
};

这里,该对象被存储在内存中的某处。而变量 user 保存的是对此处的“引用”。

当一个对象变量被拷贝 —— 引用则被拷贝,而该对象并没有被复制。

例如

var user = { name: "John" };

var admin = user; // 拷贝引用

现在我们有了两个变量,它们保存的都是对同一个对象的引用:

我们可以用任何变量来访问该对象并修改它的内容:

// 演示
var user = { name: "John" };

var admin = user; // 拷贝引用

admin.name = 'Pete'; // 通过 "admin" 引用来修改

alert(user.name); // 'Pete',修改能通过 "user" 引用看到

上面的例子说明这里只有一个对象。就像我们有个带两把钥匙的锁柜,并使用其中一把钥匙(admin)来打开它。那么,我们如果之后用另外一把钥匙(user),就也能看到所作的改变。

typeof 运算符

typeof 运算符返回参数的数据类型。当我们想要分别处理不同类型值的时候,或者想快速进行数据类型检验时,非常有用。

它支持两种语法形式:

  1. 作为运算符:typeof x

  2. 函数形式:typeof(x)

换言之,有括号和没有括号,得到的结果是一样的。

typeof x 的调用会以字符串的形式返回数据类型:

//
typeof undefined // "undefined"

typeof 0 // "number"

typeof true // "boolean"

typeof "foo" // "string"

typeof null // "object"  (1)

typeof [1,2,3] // "object" (3)

typeof {name:'张三'} // "object"

typeof alert // "function"  (2)
  1. typeof null 的结果是 "object"。这是官方承认的 typeof 的行为上的错误,这个问题来自于 JavaScript 语言的早期,并为了兼容性而保留了下来。null 绝对不是一个 objectnull 有自己的类型,它是一个特殊值。

  2. typeof alert 的结果是 "function",因为 alert 在 JavaScript 语言中是一个函数。其实函数也隶属于 object 类型。但是 typeof 会对函数区分对待,并返回 "function"

  3. typeof [1,2,3] 的结果是 "object",因为数组也隶属于 object 类型。所以用typeof并不能准确的区分对象和数组。

文档更新时间: 2022-03-28 17:36   作者:张老师