JavaScript基础语法

131 阅读6分钟

1、变量声明和作用域

var

  • 作用域:函数作用域(function scope)。
    • 在函数内部声明的变量,只能在函数内部访问。
    • 在函数外部声明的变量,会成为全局变量。
  • 提升(Hoisting) :变量声明会被提升到函数或全局作用域的顶部,但赋值不会被提升。
  • 重复声明:允许重复声明同一个变量。
  • 全局属性:在全局作用域中声明的 var 变量会成为全局对象(如 window)的属性。 示例
function example() {
  if (true) {
    var x = 10; // 函数作用域
  }
  console.log(x); // 10,x 在函数内可访问
}
example();
console.log(x); // 报错,x 在函数外不可访问

let

  • 作用域:块级作用域(block scope)。
    • 在 {} 块内声明的变量,只能在块内访问。
  • 提升:变量声明会被提升到块级作用域的顶部,但在声明之前访问会触发“暂时性死区”(Temporal Dead Zone, TDZ)。
  • 重复声明:不允许重复声明同一个变量。
  • 全局属性:在全局作用域中声明的 let 变量不会成为全局对象的属性。 示例
function example() {
  if (true) {
    let y = 20; // 块级作用域
    console.log(y); // 20
  }
  console.log(y); // 报错,y 在块外不可访问
}
example();

const

  • 作用域:块级作用域(block scope)。
    • 与 let 相同,const 声明的变量只能在块内访问。
  • 提升:与 let 相同,存在暂时性死区。
  • 重复声明:不允许重复声明同一个变量。
  • 不可变性
    • 声明的变量必须初始化,且不能重新赋值。
    • 如果变量是对象或数组,其属性或元素可以修改。
  • 全局属性:在全局作用域中声明的 const 变量不会成为全局对象的属性。 示例
const z = 30; // 必须初始化
z = 40; // 报错,不能重新赋值
const person = { name: "Alice" };
person.name = "Bob"; // 允许修改属性
console.log(person.name); // Bob

三者区别

特性varletconst
作用域函数作用域块级作用域块级作用域
提升声明提升,赋值不提升声明提升,存在 TDZ声明提升,存在 TDZ
重复声明允许不允许不允许
可变性可重新赋值可重新赋值不可重新赋值
全局属性是全局对象的属性不是全局对象的属性不是全局对象的属性
初始化可不初始化可不初始化必须初始化
注意:避免使用var,优先使用const,必要时使用let

示例对比

  • var的问题
for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i); // 输出 3 次 3
  }, 100);
}

由于 var 是函数作用域,i 在循环结束后仍然是 3

  • let解决方案
for (let i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i); // 输出 0, 1, 2
  }, 100);
}

由于let是块级作用域,每次循环都会创建一个新的i。

注意:变量未赋值时默认值为 undefinedconst 声明常量需初始化且不可重新赋值。

2、数据类型

  • 基本类型

    • string:字符串,如 "Hello"
    • number:数字,如 423.14
    • boolean:布尔值,如 truefalse
    • null:表示空值。
    • undefined:表示未定义的值。
    • symbol:唯一且不可变的值(ES6 新增)。
  • 引用类型

    • object:对象,如 { name: "Alice", age: 25 }
    • array:数组,如 [1, 2, 3]
    • function:函数。
    • 注意点typeof null 返回 "object"(历史遗留问题)。

判断数据类型判断数据类型的方法1、typeof 特点: 返回一个字符串,表示操作数的数据类型。 可以识别基本类型(如 number、 - 掘金

3、运算符与表达式

  • 算术运算符+-*/%(取余)。
  • 比较运算符=====!=!==><>=<=
  • 逻辑运算符&&(与)、||(或)、!(非)。
  • 赋值运算符=+=-=*=/=

注意=====的区别:

  • == 会在比较两个值时进行类型转换,如果类型不同,会尝试将它们转换为相同的类型,然后再进行比较。

示例:

console.log(5 == "5"); // true,因为 "5" 被转换为 5
console.log(0 == ""); // true,因为空字符串被转换为 0
console.log(0 == "0"); // true,因为 "0" 被转换为 0
console.log(null == undefined); // true,特殊规则
console.log("true" == true); // false,因为 "true" 转换为 NaN,而 NaN 不等于 true
  • === 会在比较两个值时,不仅比较它们的值,还会比较它们的类型。如果类型不同,直接返回 false,不会进行类型转换。

示例:

console.log(5 === "5"); // false,因为类型不同(number vs string)
console.log(0 === ""); // false,因为类型不同(number vs string)
console.log(0 === "0"); // false,因为类型不同(number vs string)
console.log(null === undefined); // false,因为类型不同(null vs undefined)
console.log("true" === true); // false,因为类型不同(string vs boolean)
console.log(5 === 5); // true,因为类型和值都相同
console.log("hello" === "hello"); // true,因为类型和值都相同

特殊情况

  • nullundefined 之间使用 == 时会返回 true,但使用 === 时会返回 false
  • NaN 不等于任何值,包括它自己。

4、流程控制语句

5、函数

函数是 JavaScript 中的基本构建块,用于封装可重用的代码:

  • 函数声明function 关键字。
  • 函数表达式:将函数赋值给变量。
  • 箭头函数:ES6 新增的简洁语法。 示例
// 函数声明
function greet(name) {
  return "Hello, " + name;
}
// 函数表达式
const greet = function(name) {
  return "Hello, " + name;
};
// 箭头函数
const greet = (name) => "Hello, " + name;
console.log(greet("Alice")); // Hello, Alice

参数的类型

  • 基本参数
function add(a, b) {
  return a + b;
}
console.log(add(2, 3)); // 5
  • 默认参数(为参数设置默认值)
function greet(name = "Guest") {
  return "Hello, " + name;
}
console.log(greet()); // Hello, Guest
  • 剩余参数(使用...语法将多个参数合并为数组)
function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3)); // 6

立即执行函数:立即执行函数是指在定义后立即执行的函数,通常用于创建独立的作用域。

(function() {
  let x = 10;
  console.log(x); // 10
})();

箭头函数的特点

  • 没有自己的 this,继承外层作用域的 this
  • 不能用作构造函数(不能使用 new)。
  • 没有 arguments 对象。

6、对象

对象是键值对的集合,用于存储复杂数据:

  • 属性:对象的键值对。
  • 方法:对象的函数属性。

示例

let person = {
  name: "Alice",
  age: 25,
  greet: function() {
    return "Hello, " + this.name;
  }
};
console.log(person.name); // Alice
console.log(person.greet()); // Hello, Alice

详细:对象对象是 JavaScript 的核心数据结构,用于存储键值对。 可以通过对象字面量、构造函数或类创建对象。 - 掘金

7、数组

数组是用于存储多个值的有序集合: