语法与数据类型

掌握JavaScript的基本语法规则和数据类型系统

JavaScript基本语法

JavaScript语法基于ECMAScript标准,具有以下特点:

  • 区分大小写 - myVariablemyvariable 是不同的
  • 使用Unicode字符集 - 支持多语言
  • 语句以分号结尾 - 可选但推荐使用
  • 使用花括号定义代码块
  • 使用空白字符提高可读性 - JavaScript会忽略多余的空白
  • 使用换行符分隔语句 - 大多数情况下可以省略分号

严格模式

ECMAScript 5引入了严格模式,可以在脚本或函数顶部添加"use strict";来启用:

严格模式
"use strict";

// 在严格模式下,以下操作会报错:
// x = 3.14;  // 报错 (x 未定义)
// delete x;  // 报错
// function x(p1, p1) {};  // 报错 (重复参数名)

严格模式的主要优点:

  • 消除了一些不安全的操作
  • 修复了JavaScript引擎难以优化的错误
  • 禁用了某些可能在未来版本中定义的语法

标识符和关键字

标识符命名规则

标识符是用来命名变量、函数、属性或参数的名字,规则如下:

  • 可以包含字母、数字、下划线(_)和美元符号($)
  • 必须以字母、下划线(_)或美元符号($)开头
  • 不能使用JavaScript关键字和保留字
  • 区分大小写

JavaScript关键字和保留字

break
case
catch
class
const
continue
debugger
default
delete
do
else
export
extends
finally
for
function
if
import
in
instanceof
new
return
super
switch
this
throw
try
typeof
var
void
while
with
yield

注释

JavaScript支持两种注释方式:

注释示例
// 这是单行注释

/*
 * 这是多行注释
 * 可以跨越多行
 */

let x = 5; // 行尾注释

注释的最佳实践

  • 使用注释解释代码的意图,而不是描述代码本身
  • 保持注释简洁明了
  • 及时更新过时的注释
  • 使用JSDoc格式为函数和类添加文档注释
JSDoc注释示例
/**
 * 计算两个数字的和
 * @param {number} a - 第一个数字
 * @param {number} b - 第二个数字
 * @returns {number} 两个数字的和
 */
function add(a, b) {
    return a + b;
}

数据类型

JavaScript有7种基本数据类型和1种引用类型:

类型 描述 示例 typeof返回值
String 字符串 "Hello", 'World' "string"
Number 数字 42, 3.14, NaN "number"
Boolean 布尔值 true, false "boolean"
Undefined 未定义 undefined "undefined"
Null 空值 null "object"
Symbol 唯一值(ES6) Symbol('id') "symbol"
BigInt 大整数(ES2020) 123n "bigint"
Object 对象 {name: "John"}, [1,2,3] "object"

基本类型 vs 引用类型

JavaScript中的数据类型可以分为两大类:

  • 基本类型 - 存储在栈内存中,按值访问,包括:String, Number, Boolean, Undefined, Null, Symbol, BigInt
  • 引用类型 - 存储在堆内存中,按引用访问,包括:Object, Array, Function, Date等
基本类型 vs 引用类型
// 基本类型 - 按值复制
let a = 10;
let b = a;  // b是a的值的副本
b = 20;
console.log(a);  // 10 (a的值没有改变)

// 引用类型 - 按引用复制
let obj1 = { value: 10 };
let obj2 = obj1;  // obj2和obj1引用同一个对象
obj2.value = 20;
console.log(obj1.value);  // 20 (obj1的值也改变了)

类型检测

使用typeof运算符检测数据类型:

typeof示例
console.log(typeof "Hello");        // "string"
console.log(typeof 42);             // "number"
console.log(typeof true);          // "boolean"
console.log(typeof undefined);   // "undefined"
console.log(typeof null);          // "object" (历史遗留问题)
console.log(typeof {});            // "object"
console.log(typeof []);            // "object"
console.log(typeof function(){}); // "function"
console.log(typeof Symbol('id'));  // "symbol"
console.log(typeof 123n);          // "bigint"
注意: typeof null返回"object"是JavaScript的一个已知bug,但由于历史原因无法修复。

更精确的类型检测

对于更精确的类型检测,可以使用Object.prototype.toString.call()

精确类型检测
console.log(Object.prototype.toString.call("Hello"));      // "[object String]"
console.log(Object.prototype.toString.call(42));           // "[object Number]"
console.log(Object.prototype.toString.call(true));        // "[object Boolean]"
console.log(Object.prototype.toString.call(null));        // "[object Null]"
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
console.log(Object.prototype.toString.call([]));            // "[object Array]"
console.log(Object.prototype.toString.call({}));            // "[object Object]"
console.log(Object.prototype.toString.call(function(){})); // "[object Function]"

字符串(String)

字符串用于表示文本数据:

字符串示例
// 字符串定义
let singleQuote = '单引号字符串';
let doubleQuote = "双引号字符串";
let backtick = `模板字符串`;

// 转义字符
let escaped = "第一行\n第二行";
let quoteInString = "He said, \"Hello!\"";

// 模板字符串 (ES6)
let name = "张三";
let age = 25;
let greeting = `Hello, ${name}! You are ${age} years old.`;

字符串常用转义字符

转义序列 含义
\n 换行
\t 制表符
\\ 反斜杠
\' 单引号
\" 双引号
\r 回车
\b 退格
\f 换页

数字(Number)

JavaScript使用64位浮点数格式表示所有数字:

数字示例
// 整数和浮点数
let integer = 42;
let float = 3.14159;
let scientific = 1.23e6; // 1230000

// 特殊数值
let infinity = Infinity;
let negativeInfinity = -Infinity;
let notANumber = NaN;

// 数值范围
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
console.log(Number.MAX_VALUE);        // 1.7976931348623157e+308
console.log(Number.MIN_VALUE);        // 5e-324

数字的进制表示

不同进制的数字
let decimal = 42;        // 十进制
let binary = 0b101010;   // 二进制 (42)
let octal = 0o52;        // 八进制 (42)
let hex = 0x2A;          // 十六进制 (42)

console.log(binary);  // 42
console.log(octal);   // 42
console.log(hex);     // 42

布尔值(Boolean)和特殊值

布尔值和特殊值
// 布尔值
let isTrue = true;
let isFalse = false;

// 特殊值
let empty = null;        // 表示空值
let notDefined;        // 值为 undefined
let explicitlyUndefined = undefined;

// 布尔转换
console.log(Boolean(""));        // false
console.log(Boolean("hello"));   // true
console.log(Boolean(0));         // false
console.log(Boolean(1));         // true
console.log(Boolean(null));      // false
console.log(Boolean(undefined)); // false
console.log(Boolean([]));        // true
console.log(Boolean({}));        // true

假值(Falsy)和真值(Truthy)

在JavaScript中,以下值在布尔上下文中会被认为是false(假值):

  • false
  • 0-0
  • 0n (BigInt)
  • "", '', `` (空字符串)
  • null
  • undefined
  • NaN

所有其他值都会被当作true(真值)。

Symbol和BigInt

Symbol类型

Symbol是ES6引入的新原始数据类型,表示唯一的标识符:

Symbol示例
// 创建Symbol
let id1 = Symbol("id");
let id2 = Symbol("id");

console.log(id1 === id2); // false - 每个Symbol都是唯一的

// 全局Symbol注册表
let globalId = Symbol.for("globalId");
let sameGlobalId = Symbol.for("globalId");

console.log(globalId === sameGlobalId); // true

BigInt类型

BigInt是ES2020引入的新原始数据类型,用于表示任意精度的整数:

BigInt示例
// 创建BigInt
let bigNumber = 1234567890123456789012345678901234567890n;
let bigFromNumber = BigInt(12345678901234567890);

// BigInt运算
let a = 10n;
let b = 20n;
console.log(a + b); // 30n

// 不能与Number混合运算
// console.log(10n + 20);  // 报错
console.log(10n + BigInt(20)); // 30n

类型转换

JavaScript会自动进行类型转换:

类型转换示例
// 显式转换
let num = "42";
console.log(Number(num));      // 42
console.log(String(42));      // "42"
console.log(Boolean(1));     // true

// 隐式转换
console.log("5" + 3);        // "53" (字符串连接)
console.log("5" - 3);        // 2 (数字减法)
console.log("5" * "2");      // 10 (数字乘法)

// 严格相等 vs 宽松相等
console.log("5" == 5);       // true (宽松相等)
console.log("5" === 5);      // false (严格相等)

类型转换规则

原始值 转换为数字 转换为字符串 转换为布尔值
false 0 "false" false
true 1 "true" true
0 0 "0" false
1 1 "1" true
"0" 0 "0" true
"1" 1 "1" true
NaN NaN "NaN" false
Infinity Infinity "Infinity" true
"" 0 "" false
"20" 20 "20" true
"twenty" NaN "twenty" true
[] 0 "" true
[20] 20 "20" true
[10,20] NaN "10,20" true
{} NaN "[object Object]" true

实践练习

👆 请点击上方按钮进行演示操作

选择不同的演示按钮来探索JavaScript的各种功能和用法

类型转换练习

选择转换类型并查看结果:

练习代码
// 练习1: 数据类型检测
let values = ["hello", 42, true, null, undefined, {}, []];
values.forEach(value => {
    console.log(`值: ${value}, 类型: ${typeof value}`);
});

// 练习2: 类型转换
console.log("10" + 5);           // "105"
console.log("10" - 5);           // 5
console.log(Boolean("0"));       // true
console.log(Boolean(0));         // false

// 练习3: 严格模式下的类型检查
"use strict";
function testStrict() {
    // 以下代码在严格模式下会报错
    // undeclaredVar = "test";  // 未声明变量赋值
    // delete Object.prototype;  // 删除不可删除的属性
}

常见问题与解答

1. 为什么typeof null返回"object"?

这是JavaScript的一个历史遗留错误。在JavaScript最初的实现中,值的类型标签存储在低位中,对象的类型标签是0,而null被表示为空指针(通常是0x00)。因此,typeof null错误地返回了"object"。

2. undefined和null有什么区别?

undefined表示变量已声明但未赋值,null表示一个空值或"无"的值。在实际使用中,undefined通常由JavaScript引擎自动赋值,而null需要显式赋值。

3. 什么时候使用==,什么时候使用===?

在大多数情况下,推荐使用===(严格相等),因为它不会进行类型转换,行为更可预测。只有在明确需要类型转换时才使用==(宽松相等)。

下一步学习

掌握了数据类型后,接下来可以学习: