1. variable声明
in JavaScriptin, variable is 用于storedata containers. ES6之 before , JavaScript只 has var关键字用于声明variable, ES6引入了let and const关键字, providing了更 good variable声明方式.
1.1 var关键字
var关键字 is ES6之 before 唯一 variable声明方式, 它 has 以 under 特点:
- function作用域: variable只 in 声明它 function in has 效
- variable提升: variable声明会被提升 to function顶部
- 可以重复声明: 同一作用域 in 可以重复声明同一variable
// var声明example
function example() {
console.log(x); // undefined (variable提升)
var x = 10;
console.log(x); // 10
// 重复声明
var x = 20;
console.log(x); // 20
}
example();
console.log(x); // error: xundefined (function作用域)
1.2 let关键字
let关键字 is ES6引入 variable声明方式, 它 has 以 under 特点:
- 块级作用域: variable in 声明它 块 (such asif, for, functionetc.) in has 效
- 无variable提升: variable不会被提升, 必须先声明 after using
- 不能重复声明: 同一作用域 in 不能重复声明同一variable
// let声明example
function example() {
// console.log(y); // error: yundefined (无variable提升)
let y = 10;
console.log(y); // 10
// 块级作用域
if (true) {
let y = 20;
console.log(y); // 20
}
console.log(y); // 10
// let y = 30; // error: 重复声明
}
example();
1.3 const关键字
const关键字也 is ES6引入 , 用于声明常量, 它 has 以 under 特点:
- 块级作用域: and
let相同, 具 has 块级作用域 - 无variable提升: and
let相同, 必须先声明 after using - 不能重复声明: and
let相同, 同一作用域 in 不能重复声明 - 必须初始化: 声明时必须赋值
- 不能重 new 赋值: 一旦赋值, 不能modify (但object and array in 容可以modify)
// const声明example
const PI = 3.14159;
console.log(PI); // 3.14159
// PI = 3.14; // error: 不能重 new 赋值
// object常量
const person = {
name: "张三",
age: 30
};
console.log(person); // { name: "张三", age: 30 }
// 可以modifyobjectproperty
person.age = 31;
console.log(person); // { name: "张三", age: 31 }
// 但不能重 new 赋值整个object
// person = { name: "李四", age: 25 }; // error: 不能重 new 赋值
1.4 variable声明best practices
- 优先using
const: for 于不需要重 new 赋值 variable, usingconst - 其次using
let: for 于需要重 new 赋值 variable, usinglet - 避免using
var:var作用域规则 easy 导致error - using has 意义 variable名: variable名应该清晰表达variable 用途
- 遵循命名规范: using驼峰命名法 (such asfirstName)
2. dataclass型
JavaScript has 两种dataclass型: 原始dataclass型 and 引用dataclass型.
2.1 原始dataclass型
原始dataclass型 is 不可变 data, 直接store in 栈memoryin. JavaScript has 7种原始dataclass型:
2.1.1 Number (number)
Numberclass型表示整数 and 浮点数:
let integer = 42; // 整数
let float = 3.14; // 浮点数
let negative = -10; // 负数
let zero = 0; // 零
console.log(typeof integer); // number
console.log(typeof float); // number
// 特殊数值
let infinity = Infinity; // 正无穷 big
let negativeInfinity = -Infinity; // 负无穷 big
let NaN = NaN; // 不 is a number (Not a Number)
console.log(infinity); // Infinity
console.log(negativeInfinity); // -Infinity
console.log(NaN); // NaN
console.log(typeof NaN); // number (特殊circumstances)
2.1.2 String (string)
Stringclass型表示文本data, 可以using单引号, 双引号 or 反引号package围:
let singleQuote = 'Hello'; // 单引号
let doubleQuote = "World"; // 双引号
let backtick = `Hello ${doubleQuote}`; // 反引号 (模板string)
console.log(singleQuote); // Hello
console.log(doubleQuote); // World
console.log(backtick); // Hello World
console.log(typeof backtick); // string
// string long 度
console.log(singleQuote.length); // 5
// stringmethod
console.log(singleQuote.toUpperCase()); // HELLO
console.log(doubleQuote.toLowerCase()); // world
console.log(backtick.includes('Hello')); // true
2.1.3 Boolean (boolean值)
Booleanclass型表示逻辑值, 只 has 两个值: true and false:
let isTrue = true;
let isFalse = false;
console.log(typeof isTrue); // boolean
console.log(typeof isFalse); // boolean
// boolean值 using
if (isTrue) {
console.log("条件 for 真");
} else {
console.log("条件 for fake");
}
2.1.4 Null (null)
Nullclass型表示一个null, 只 has 一个值: null:
let emptyValue = null;
console.log(emptyValue); // null
console.log(typeof emptyValue); // object (history遗留issues)
// null using场景: 明确表示一个variable没 has 值
let user = null; // 表示user不存 in
2.1.5 Undefined (undefined)
Undefinedclass型表示一个variable未被赋值, 只 has 一个值: undefined:
let unassigned;
console.log(unassigned); // undefined
console.log(typeof unassigned); // undefined
// 显式赋值 for undefined
let explicitUndefined = undefined;
console.log(explicitUndefined); // undefined
2.1.6 Symbol (符号)
Symbol is ES6引入 class型, 表示唯一 标识符:
// creationSymbol
let symbol1 = Symbol();
let symbol2 = Symbol('description');
let symbol3 = Symbol('description');
console.log(symbol1); // Symbol()
console.log(symbol2); // Symbol(description)
console.log(symbol2 === symbol3); // false (每个Symbol都 is 唯一 )
console.log(typeof symbol1); // symbol
// Symbol using场景: serving asobjectproperty 键
const user = {
[Symbol('id')]: 123,
name: '张三'
};
console.log(user); // { name: '张三', [Symbol(id)]: 123 }
2.1.7 BigInt ( big 整数)
BigInt is ES11引入 class型, 用于表示任意精度 整数:
// creationBigInt
let bigInt1 = 100n; // usingn after 缀
let bigInt2 = BigInt(100); // usingBigIntfunction
console.log(bigInt1); // 100n
console.log(bigInt2); // 100n
console.log(typeof bigInt1); // bigint
// BigInt using场景: processing超出Number范围 整数
let largeNumber = 9007199254740991n;
console.log(largeNumber); // 9007199254740991n
2.2 引用dataclass型
引用dataclass型 is 可变 data, store in 堆memoryin, 栈memoryinstore is 指向堆memory 引用. JavaScript 引用dataclass型主要 has :
2.2.1 Object (object)
Objectclass型 is JavaScriptin最basic 引用dataclass型, 表示键值 for collection:
// creationobject
let person = {
name: "张三",
age: 30,
greet: function() {
console.log(`你 good , 我 is ${this.name}`);
}
};
console.log(person); // { name: "张三", age: 30, greet: [Function: greet] }
console.log(typeof person); // object
// 访问objectproperty
console.log(person.name); // 张三
console.log(person['age']); // 30
// 调用objectmethod
person.greet(); // 你 good , 我 is 张三
// modifyobjectproperty
person.age = 31;
console.log(person.age); // 31
2.2.2 Array (array)
Arrayclass型 is 特殊 object, 用于store has 序 元素collection:
// creationarray
let fruits = ["苹果", "香蕉", "橙子"];
let numbers = [1, 2, 3, 4, 5];
let mixed = [1, "Hello", true, null, undefined];
console.log(fruits); // [ "苹果", "香蕉", "橙子" ]
console.log(typeof fruits); // object
console.log(Array.isArray(fruits)); // true
// 访问array元素
console.log(fruits[0]); // 苹果
console.log(fruits[2]); // 橙子
// modifyarray元素
fruits[1] = "葡萄";
console.log(fruits); // [ "苹果", "葡萄", "橙子" ]
// array long 度
console.log(fruits.length); // 3
2.2.3 Function (function)
Functionclass型 is 特殊 object, 用于store可执行 code:
// function声明
function add(a, b) {
return a + b;
}
// function表达式
let multiply = function(a, b) {
return a * b;
};
// 箭头function (ES6+)
let divide = (a, b) => a / b;
console.log(typeof add); // function
console.log(typeof multiply); // function
console.log(typeof divide); // function
// 调用function
console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6
console.log(divide(6, 3)); // 2
2.3 dataclass型检测
可以usingtypeofoperation符 and instanceofoperation符检测dataclass型:
// typeofoperation符: 检测原始dataclass型 and function
console.log(typeof 42); // number
console.log(typeof "Hello"); // string
console.log(typeof true); // boolean
console.log(typeof null); // object (history遗留issues)
console.log(typeof undefined); // undefined
console.log(typeof Symbol()); // symbol
console.log(typeof 100n); // bigint
console.log(typeof {}); // object
console.log(typeof []); // object
console.log(typeof function() {}); // function
// instanceofoperation符: 检测引用dataclass型
console.log({} instanceof Object); // true
console.log([] instanceof Array); // true
console.log([] instanceof Object); // true (array is object 子class)
console.log(function() {} instanceof Function); // true
console.log(function() {} instanceof Object); // true (function is object 子class)
// 特殊检测method
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
console.log(null === null); // true (检测null 唯一method)
3. class型转换
JavaScript is a弱class型language, 会自动forclass型转换. 同时, 也可以手动forclass型转换.
3.1 自动class型转换
JavaScript in 需要时会自动转换dataclass型:
// number and string相加: string连接
console.log(10 + "5"); // "105"
// number and boolean值相加: boolean值转换 for number (true->1, false->0)
console.log(10 + true); // 11
console.log(10 + false); // 10
// string and boolean值相加: boolean值转换 for string
console.log("Hello " + true); // "Hello true"
// 比较operationin class型转换
console.log(10 == "10"); // true (自动转换class型)
console.log(10 === "10"); // false (严格比较, 不转换class型)
// 逻辑operationin class型转换
console.log(Boolean(0)); // false
console.log(Boolean("")); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
console.log(Boolean([])); // true (空array is 真值)
console.log(Boolean({})); // true (空object is 真值)
3.2 手动class型转换
可以using in 置function手动转换dataclass型:
3.2.1 转换 for string
// String()function
let num = 42;
let str1 = String(num);
console.log(str1); // "42"
console.log(typeof str1); // string
// toString()method
let bool = true;
let str2 = bool.toString();
console.log(str2); // "true"
console.log(typeof str2); // string
// 模板string
let value = null;
let str3 = `${value}`;
console.log(str3); // "null"
console.log(typeof str3); // string
3.2.2 转换 for number
// Number()function
let str = "42";
let num1 = Number(str);
console.log(num1); // 42
console.log(typeof num1); // number
// 转换失败返回NaN
let invalidStr = "Hello";
let num2 = Number(invalidStr);
console.log(num2); // NaN
// parseInt()function: 转换 for 整数
let floatStr = "3.14";
let intNum = parseInt(floatStr);
console.log(intNum); // 3
// parseFloat()function: 转换 for 浮点数
let floatNum = parseFloat(floatStr);
console.log(floatNum); // 3.14
// 一元加号operation符
let strNum = "100";
let num3 = +strNum;
console.log(num3); // 100
console.log(typeof num3); // number
3.2.3 转换 for boolean值
// Boolean()function
let zero = 0;
let bool1 = Boolean(zero);
console.log(bool1); // false
let nonZero = 42;
let bool2 = Boolean(nonZero);
console.log(bool2); // true
// 空string
let emptyStr = "";
let bool3 = Boolean(emptyStr);
console.log(bool3); // false
// 非空string
let nonEmptyStr = "Hello";
let bool4 = Boolean(nonEmptyStr);
console.log(bool4); // true
// 一元感叹号operation符 (取反)
let value = "test";
let bool5 = !!value; // 双重取反, 转换 for boolean值
console.log(bool5); // true
实践case: class型转换练习
creation一个JavaScript程序, 演示各种class型转换:
- creationvariablestore不同class型 data (number, string, boolean值, objectetc.)
- 演示自动class型转换 (such asnumber and string相加)
- 演示手动class型转换 (usingNumber(), String(), Boolean()function)
- usingtypeofoperation符检测转换 before after dataclass型
- in 控制台输出转换结果
// class型转换实践case
// 1. creation不同class型 variable
let num = 42;
let str = "10";
let bool = true;
let obj = { value: 50 };
let arr = [1, 2, 3];
let emptyStr = "";
let zero = 0;
// 2. 自动class型转换
console.log("=== 自动class型转换 ===");
console.log("number + string:", num + str); // "4210"
console.log("number + boolean值:", num + bool); // 43
console.log("string + boolean值:", str + bool); // "10true"
console.log("number == string:", num == str); // false (42 == "10")
console.log("10 == \"10\":", 10 == "10"); // true
// 3. 手动class型转换
console.log("\n=== 手动class型转换 ===");
// 转换 for string
console.log("number转string:", String(num), typeof String(num));
console.log("boolean值转string:", String(bool), typeof String(bool));
// 转换 for number
console.log("string转number:", Number(str), typeof Number(str));
console.log("boolean值转number:", Number(bool), typeof Number(bool));
console.log("空string转number:", Number(emptyStr), typeof Number(emptyStr));
// 转换 for boolean值
console.log("number转boolean值:", Boolean(num), typeof Boolean(num));
console.log("零转boolean值:", Boolean(zero), typeof Boolean(zero));
console.log("空string转boolean值:", Boolean(emptyStr), typeof Boolean(emptyStr));
console.log("object转boolean值:", Boolean(obj), typeof Boolean(obj));
console.log("array转boolean值:", Boolean(arr), typeof Boolean(arr));
// 4. 特殊转换
console.log("\n=== 特殊转换 ===");
console.log("using一元加号转换string:", +str, typeof +str);
console.log("using双重感叹号转换number:", !!num, typeof !!num);
console.log("null转number:", Number(null)); // 0
console.log("undefined转number:", Number(undefined)); // NaN
互动练习: variable and dataclass型练习
- using
const声明一个常量TAX_RATE, 值 for 0.08 - using
let声明variableprice, 值 for 100 - using
let声明variablequantity, 值 for 3 - 计算总价 (price * quantity) 并store in variable
subtotalin - 计算税费 (subtotal * TAX_RATE) 并store in variable
taxin - 计算总价格 (subtotal + tax) 并store in variable
totalin - using
console.log()输出以 under in 容: - 商品价格: [price]
- 购买数量: [quantity]
- small 计: [subtotal]
- 税费: [tax]
- 总计: [total]
- using
typeofoperation符check每个variable dataclass型, 并 in 控制台输出
- using
prompt()获取user输入 商品价格 and 数量 - 将user输入 string转换 for number
- 重 new 计算总价, 税费 and 总价格
- using
alert()显示计算结果
4. variable作用域
4.1 全局作用域
in function out 部声明 variable具 has 全局作用域, 可以 in 任何地方访问:
// 全局variable
let globalVar = "全局variable";
function example() {
console.log(globalVar); // 可以访问全局variable
}
example(); // 全局variable
console.log(globalVar); // 全局variable
4.2 function作用域
in function in 部usingvar声明 variable具 has function作用域, 只能 in function in 部访问:
function example() {
// function作用域variable
var functionVar = "function作用域variable";
console.log(functionVar); // 可以访问
}
example(); // function作用域variable
// console.log(functionVar); // error: functionVarundefined
4.3 块级作用域
in 块 (such asif, for, functionetc.) in 部usinglet and const声明 variable具 has 块级作用域, 只能 in 块 in 部访问:
function example() {
if (true) {
// 块级作用域variable
let blockVar = "块级作用域variable";
const blockConst = "块级作用域常量";
console.log(blockVar); // 可以访问
console.log(blockConst); // 可以访问
}
// console.log(blockVar); // error: blockVarundefined
// console.log(blockConst); // error: blockConstundefined
}
example();
4.4 词法作用域
JavaScriptadopts词法作用域 (静态作用域) , variable 作用域由其 in codein 位置决定:
let globalVar = "全局";
function outer() {
let outerVar = " out 部";
function inner() {
let innerVar = " in 部";
console.log(innerVar); // in 部
console.log(outerVar); // out 部 (可以访问 out 部function variable)
console.log(globalVar); // 全局 (可以访问全局variable)
}
inner();
console.log(outerVar); // out 部
console.log(globalVar); // 全局
// console.log(innerVar); // error: innerVarundefined
}
outer();
console.log(globalVar); // 全局
// console.log(outerVar); // error: outerVarundefined