JavaScriptvariable and dataclass型

LearningJavaScriptin variable声明, dataclass型 and class型转换

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

  • 优先usingconst: for 于不需要重 new 赋值 variable, usingconst
  • 其次usinglet: for 于需要重 new 赋值 variable, usinglet
  • 避免usingvar: 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型转换:

  1. creationvariablestore不同class型 data (number, string, boolean值, objectetc.)
  2. 演示自动class型转换 (such asnumber and string相加)
  3. 演示手动class型转换 (usingNumber(), String(), Boolean()function)
  4. usingtypeofoperation符检测转换 before after dataclass型
  5. 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型练习

1. creation一个HTMLfile, package含以 under JavaScriptcode:
  1. usingconst声明一个常量TAX_RATE, 值 for 0.08
  2. usinglet声明variableprice, 值 for 100
  3. usinglet声明variablequantity, 值 for 3
  4. 计算总价 (price * quantity) 并store in variablesubtotalin
  5. 计算税费 (subtotal * TAX_RATE) 并store in variabletaxin
  6. 计算总价格 (subtotal + tax) 并store in variabletotalin
  7. usingconsole.log()输出以 under in 容:
    • 商品价格: [price]
    • 购买数量: [quantity]
    • small 计: [subtotal]
    • 税费: [tax]
    • 总计: [total]
  8. usingtypeofoperation符check每个variable dataclass型, 并 in 控制台输出
2. scale练习:
  • usingprompt()获取user输入 商品价格 and 数量
  • 将user输入 string转换 for number
  • 重 new 计算总价, 税费 and 总价格
  • usingalert()显示计算结果

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