JavaScript完全指南:从入门到精通

一、JavaScript基础概念

1.1 什么是JavaScript?

JavaScript(简称JS)是一种轻量级的解释型编程语言,主要用于为网页添加交互性。它是Web开发的三大核心技术之一(HTML、CSS、JavaScript)。

1.2 JavaScript的历史

  • 1995年:Brendan Eich在10天内创造了JavaScript,最初名为Mocha
  • 1996年:改名为LiveScript,最后定名为JavaScript
  • 1997年:ECMAScript标准建立
  • 2009年:Node.js诞生,JS可在服务器端运行
  • 2015年:ES6(ECMAScript 2015)发布,引入大量新特性
  • 至今:持续发展和完善,每年都有新版本

1.3 JavaScript的特点

  • 解释型语言:无需编译,直接在浏览器中执行
  • 动态类型:变量类型在运行时确定
  • 函数式编程:支持高阶函数、闭包等特性
  • 面向对象:基于原型的面向对象编程
  • 跨平台:可在浏览器、Node.js等环境中运行
  • 事件驱动:适合处理用户交互和异步操作

1.4 JavaScript的应用场景

  • 前端开发:网页交互、动画、表单验证
  • 后端开发:Node.js服务器、API开发
  • 移动开发:React Native、Ionic
  • 桌面应用:Electron
  • 小程序开发:微信小程序、支付宝小程序
  • 游戏开发:Canvas游戏、WebGL

二、JavaScript基础语法

2.1 JavaScript的引入方式

行内JavaScript
html 复制代码
<button onclick="alert('Hello!')">点击我</button>
内部JavaScript
html 复制代码
<script>
    console.log('Hello World!');
</script>
外部JavaScript
html 复制代码
<script src="script.js"></script>

注意

  • script标签通常放在body底部,避免阻塞页面渲染
  • 可以使用deferasync属性优化加载
  • defer:按顺序加载,在HTML解析完成后执行
  • async:异步加载,加载完成后立即执行
html 复制代码
<script defer src="script.js"></script>
<script async src="script.js"></script>

2.2 注释

javascript 复制代码
// 单行注释

/*
 * 多行注释
 * 可以写多行
 */

/**
 * 文档注释
 * @param {string} name - 名字
 * @returns {string} - 问候语
 */
function greet(name) {
    return `Hello, ${name}!`;
}

2.3 语句和分号

javascript 复制代码
// 使用分号(推荐)
let a = 1;
let b = 2;
let c = a + b;

// 不使用分号(自动插入分号)
let a = 1
let b = 2
let c = a + b

// 建议始终使用分号,避免潜在问题

三、变量和数据类型

3.1 变量声明

javascript 复制代码
// var - 函数作用域(不推荐)
var name = '张三';

// let - 块级作用域(推荐)
let age = 25;

// const - 常量,块级作用域(推荐)
const PI = 3.14159;

// 不重复声明
let x = 1;
// let x = 2; // 错误:不能重复声明

// 可以重新赋值
x = 3;

// const 声明后不能重新赋值
const y = 1;
// y = 2; // 错误:不能重新赋值

// const 对象可以修改属性
const person = { name: '李四' };
person.name = '王五'; // 正确
// person = {}; // 错误:不能重新赋值

3.2 数据类型

原始类型(Primitive Types)
javascript 复制代码
// 1. Undefined - 未定义
let undefinedVar;
console.log(undefinedVar); // undefined

// 2. Null - 空值
let nullVar = null;
console.log(nullVar); // null

// 3. Boolean - 布尔值
let isTrue = true;
let isFalse = false;

// 4. Number - 数字
let integer = 42;
let float = 3.14;
let scientific = 1e5; // 100000
let hex = 0xff; // 255
let binary = 0b1010; // 10
let octal = 0o755; // 493

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

// 5. String - 字符串
let str1 = '单引号字符串';
let str2 = "双引号字符串";
let str3 = `模板字符串 ${age}`;
let multiLine = `
    多行
    字符串
`;

// 6. Symbol - 符号(ES6)
let sym = Symbol('description');
let sym2 = Symbol('description');
console.log(sym === sym2); // false

// 7. BigInt - 大整数(ES2020)
let bigInt = 9007199254740991n;
let bigInt2 = BigInt('9007199254740992');
引用类型(Reference Types)
javascript 复制代码
// Object - 对象
let obj = {
    name: '张三',
    age: 25,
    sayHello: function() {
        console.log('Hello!');
    }
};

// Array - 数组
let arr = [1, 2, 3, 'four', { five: 5 }];

// Function - 函数
function myFunction() {
    console.log('Function');
}

let arrowFunction = () => {
    console.log('Arrow Function');
};

// Date - 日期
let date = new Date();
let date2 = new Date('2026-01-01');

// RegExp - 正则表达式
let regex = /pattern/g;
let regex2 = new RegExp('pattern', 'g');

// Map - 映射(ES6)
let map = new Map();
map.set('key', 'value');

// Set - 集合(ES6)
let set = new Set([1, 2, 3, 3]); // {1, 2, 3}

3.3 类型检测

javascript 复制代码
// typeof - 检测基本类型
console.log(typeof 42); // "number"
console.log(typeof 'hello'); // "string"
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"

// instanceof - 检测对象类型
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
console.log(new Date() instanceof Date); // true

// constructor - 构造函数
console.log([].constructor === Array); // true

// Object.prototype.toString - 最精确的类型检测
function getType(value) {
    return Object.prototype.toString.call(value).slice(8, -1);
}

console.log(getType(42)); // "Number"
console.log(getType([])); // "Array"
console.log(getType(null)); // "Null"
console.log(getType(undefined)); // "Undefined"

// 类型转换
// 转为字符串
String(123); // "123"
String(true); // "true"
String(null); // "null"
String(undefined); // "undefined"
123.toString(); // "123"
''.toString(); // ""

// 转为数字
Number('123'); // 123
Number('123abc'); // NaN
Number(''); // 0
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
parseInt('123'); // 123
parseInt('123abc'); // 123
parseFloat('3.14'); // 3.14

// 转为布尔值
Boolean(0); // false
Boolean(''); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
Boolean(false); // false
// 其他都是true
Boolean(1); // true
Boolean('hello'); // true
Boolean([]); // true
Boolean({}); // true

四、运算符

4.1 算术运算符

javascript 复制代码
let a = 10;
let b = 3;

a + b; // 13 - 加法
a - b; // 7 - 减法
a * b; // 30 - 乘法
a / b; // 3.333... - 除法
a % b; // 1 - 取余
a ** b; // 1000 - 幂运算(ES6)

// 自增自减
let x = 5;
x++; // 6 - 后置自增(先返回后自增)
++x; // 7 - 前置自增(先自增后返回)
x--; // 6 - 后置自减
--x; // 5 - 前置自减

// 字符串拼接
'Hello' + ' ' + 'World'; // "Hello World"

4.2 比较运算符

javascript 复制代码
// 相等
1 == 1; // true
1 == '1'; // true(类型转换)
1 === 1; // true(严格相等)
1 === '1'; // false(类型不同)

// 不等
1 != 2; // true
1 != '1'; // false
1 !== 2; // true
1 !== '1'; // true

// 大于
5 > 3; // true
5 >= 5; // true

// 小于
3 < 5; // true
5 <= 5; // true

// Object.is - 严格相等(处理特殊情况)
Object.is(NaN, NaN); // true
Object.is(+0, -0); // false

4.3 逻辑运算符

javascript 复制代码
// 逻辑与
true && true; // true
true && false; // false
false && true; // false
false && false; // false

// 短路求值
let a = 1;
let b = a > 0 && a < 10; // true
let c = a > 10 && console.log('不会执行'); // undefined

// 逻辑或
true || true; // true
true || false; // true
false || true; // true
false || false; // false

// 短路求值
let d = a > 0 || a < 0; // true
let e = a > 10 || console.log('会执行'); // 会执行

// 逻辑非
!true; // false
!false; // true

// 空值合并运算符(ES2020)
let f = null ?? 'default'; // 'default'
let g = undefined ?? 'default'; // 'default'
let h = 0 ?? 'default'; // 0
let i = '' ?? 'default'; // ''

// 可选链运算符(ES2020)
let user = { profile: { name: '张三' } };
user?.profile?.name; // '张三'
user?.address?.city; // undefined

4.4 赋值运算符

javascript 复制代码
let a = 10;

a += 5; // a = a + 5; 15
a -= 3; // a = a - 3; 12
a *= 2; // a = a * 2; 24
a /= 4; // a = a / 4; 6
a %= 4; // a = a % 4; 2
a **= 3; // a = a ** 3; 8

// 解构赋值
let [x, y] = [1, 2];
console.log(x, y); // 1, 2

let { name, age } = { name: '张三', age: 25 };
console.log(name, age); // '张三', 25

4.5 位运算符

javascript 复制代码
let a = 5; // 二进制: 101
let b = 3; // 二进制: 011

// 按位与
a & b; // 1 (001)

// 按位或
a | b; // 7 (111)

// 按位异或
a ^ b; // 6 (110)

// 按位非
~a; // -6

// 左移
a << 1; // 10 (1010)

// 右移
a >> 1; // 2 (10)

// 无符号右移
a >>> 1; // 2 (10)

4.6 条件运算符

javascript 复制代码
// 三元运算符
let age = 18;
let canVote = age >= 18 ? '可以投票' : '不能投票';
console.log(canVote); // '可以投票'

// 链式三元运算符
let score = 85;
let grade = score >= 90 ? 'A' : 
           score >= 80 ? 'B' : 
           score >= 70 ? 'C' : 
           score >= 60 ? 'D' : 'F';
console.log(grade); // 'B'

五、控制流程

5.1 条件语句

javascript 复制代码
// if-else
let score = 85;
if (score >= 90) {
    console.log('优秀');
} else if (score >= 80) {
    console.log('良好');
} else if (score >= 60) {
    console.log('及格');
} else {
    console.log('不及格');
}

// switch
let day = '星期一';
switch (day) {
    case '星期一':
        console.log('工作日');
        break;
    case '星期二':
        console.log('工作日');
        break;
    case '星期六':
    case '星期日':
        console.log('周末');
        break;
    default:
        console.log('未知');
}

// switch 的严格相等
let x = '10';
switch (x) {
    case 10:
        console.log('数字10');
        break;
    case '10':
        console.log('字符串10'); // 输出这个
        break;
}

5.2 循环语句

javascript 复制代码
// for循环
for (let i = 0; i < 5; i++) {
    console.log(i);
}

// for-in循环(遍历对象属性)
let obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
    console.log(key, obj[key]);
}

// for-of循环(遍历可迭代对象)
let arr = [1, 2, 3, 4, 5];
for (let value of arr) {
    console.log(value);
}

// while循环
let i = 0;
while (i < 5) {
    console.log(i);
    i++;
}

// do-while循环
let j = 0;
do {
    console.log(j);
    j++;
} while (j < 5);

// break和continue
for (let i = 0; i < 10; i++) {
    if (i === 3) {
        continue; // 跳过3
    }
    if (i === 7) {
        break; // 退出循环
    }
    console.log(i);
}

// 标签循环
outer: for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
        if (i === 1 && j === 1) {
            break outer; // 退出外层循环
        }
        console.log(i, j);
    }
}

5.3 异常处理

javascript 复制代码
// try-catch-finally
try {
    // 可能出错的代码
    let result = 10 / 0;
    console.log(result);
} catch (error) {
    // 捕获错误
    console.error('发生错误:', error.message);
} finally {
    // 无论是否出错都会执行
    console.log('清理资源');
}

// 抛出错误
function divide(a, b) {
    if (b === 0) {
        throw new Error('除数不能为0');
    }
    return a / b;
}

try {
    divide(10, 0);
} catch (error) {
    console.error(error.message);
}

// 错误类型
new Error('普通错误');
new TypeError('类型错误');
new ReferenceError('引用错误');
new SyntaxError('语法错误');
new RangeError('范围错误');
new URIError('URI错误');
new EvalError('Eval错误');

六、函数

6.1 函数定义

javascript 复制代码
// 函数声明
function greet(name) {
    return `Hello, ${name}!`;
}

// 函数表达式
const greet2 = function(name) {
    return `Hello, ${name}!`;
};

// 箭头函数(ES6)
const greet3 = (name) => {
    return `Hello, ${name}!`;
};

// 箭头函数简写
const greet4 = name => `Hello, ${name}!`;

// 箭头函数多个参数
const add = (a, b) => a + b;

// 箭头函数返回对象(需要括号)
const createUser = (name, age) => ({ name, age });

// 立即执行函数
(function() {
    console.log('立即执行');
})();

// 箭头函数版本的立即执行函数
(() => {
    console.log('立即执行');
})();

// 函数构造器(不推荐)
const greet5 = new Function('name', 'return `Hello, ${name}!`');

6.2 函数参数

javascript 复制代码
// 默认参数
function greet(name = 'World') {
    return `Hello, ${name}!`;
}
greet(); // 'Hello, World!'

// 剩余参数
function sum(...numbers) {
    return numbers.reduce((acc, num) => acc + num, 0);
}
sum(1, 2, 3, 4, 5); // 15

// 参数解构
function greetUser({ name, age }) {
    console.log(`${name}, ${age}岁`);
}
greetUser({ name: '张三', age: 25 });

// 结合默认参数和解构
function createUser({ name = '匿名', age = 0 } = {}) {
    return { name, age };
}
createUser(); // { name: '匿名', age: 0 }
createUser({ name: '李四' }); // { name: '李四', age: 0 }

6.3 作用域和闭包

javascript 复制代码
// 函数作用域
function outer() {
    let outerVar = 'outer';
    
    function inner() {
        let innerVar = 'inner';
        console.log(outerVar); // 可以访问外部变量
        console.log(innerVar);
    }
    
    inner();
    // console.log(innerVar); // 错误:无法访问内部变量
}

// 块级作用域
{
    let blockVar = 'block';
    console.log(blockVar);
}
// console.log(blockVar); // 错误:无法访问

// 闭包
function createCounter() {
    let count = 0;
    
    return {
        increment: function() {
            count++;
            return count;
        },
        decrement: function() {
            count--;
            return count;
        },
        getCount: function() {
            return count;
        }
    };
}

const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.decrement()); // 1
console.log(counter.getCount()); // 1

// 闭包应用:模拟私有变量
function createPerson(name) {
    let _name = name;
    
    return {
        getName: function() {
            return _name;
        },
        setName: function(newName) {
            _name = newName;
        }
    };
}

const person = createPerson('张三');
console.log(person.getName()); // '张三'
person.setName('李四');
console.log(person.getName()); // '李四'
// console.log(_name); // 错误:无法直接访问

6.4 this关键字

javascript 复制代码
// 方法中的this
const person = {
    name: '张三',
    greet: function() {
        console.log(`Hello, ${this.name}`);
    }
};
person.greet(); // 'Hello, 张三'

// 箭头函数中的this(继承外层作用域)
const person2 = {
    name: '李四',
    greet: () => {
        console.log(`Hello, ${this.name}`);
    }
};
person2.greet(); // 'Hello, undefined'

// 箭头函数在对象方法中的正确用法
const person3 = {
    name: '王五',
    greet: function() {
        setTimeout(() => {
            console.log(`Hello, ${this.name}`);
        }, 1000);
    }
};
person3.greet(); // 'Hello, 王五'

// call、apply、bind
function greet(greeting, punctuation) {
    console.log(`${greeting}, ${this.name}${punctuation}`);
}

const person4 = { name: '赵六' };
greet.call(person4, 'Hello', '!'); // 'Hello, 赵六!'
greet.apply(person4, ['Hi', '.']); // 'Hi, 赵六.'

const greetBound = greet.bind(person4, 'Hey');
greetBound('~'); // 'Hey, 赵六~'

6.5 高阶函数

javascript 复制代码
// 函数作为参数
function execute(fn) {
    fn();
}

execute(function() {
    console.log('执行函数');
});

// 函数作为返回值
function createMultiplier(factor) {
    return function(number) {
        return number * factor;
    };
}

const double = createMultiplier(2);
const triple = createMultiplier(3);

console.log(double(5)); // 10
console.log(triple(5)); // 15

// 回调函数
function fetchData(callback) {
    setTimeout(() => {
        const data = { name: '张三', age: 25 };
        callback(data);
    }, 1000);
}

fetchData(function(data) {
    console.log(data);
});

// 数组高阶函数
const numbers = [1, 2, 3, 4, 5];

// map
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// filter
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4]

// reduce
const sum = numbers.reduce((acc, n) => acc + n, 0);
console.log(sum); // 15

// find
const found = numbers.find(n => n > 3);
console.log(found); // 4

// some
const hasEven = numbers.some(n => n % 2 === 0);
console.log(hasEven); // true

// every
const allPositive = numbers.every(n => n > 0);
console.log(allPositive); // true

// forEach
numbers.forEach(n => console.log(n));

七、对象和数组

7.1 对象

javascript 复制代码
// 对象字面量
const person = {
    name: '张三',
    age: 25,
    greet: function() {
        console.log(`Hello, ${this.name}`);
    }
};

// 访问属性
person.name; // '张三'
person['age']; // 25

// 添加属性
person.city = '北京';
person['country'] = '中国';

// 删除属性
delete person.city;

// 检查属性
'name' in person; // true
person.hasOwnProperty('name'); // true

// 对象方法
Object.keys(person); // ['name', 'age', 'greet']
Object.values(person); // ['张三', 25, function]
Object.entries(person); // [['name', '张三'], ['age', 25], ['greet', function]]

// 对象解构
const { name, age } = person;
const { name: personName, age: personAge } = person;

// 对象展开运算符
const newPerson = { ...person, city: '上海' };

// 对象合并
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const merged = { ...obj1, ...obj2 };

// 计算属性名
const key = 'dynamic';
const obj = {
    [key]: 'value',
    [`prop_${Date.now()}`]: 'timestamp'
};

// getter和setter
const user = {
    _name: '张三',
    get name() {
        return this._name;
    },
    set name(value) {
        this._name = value;
    }
};

user.name; // '张三'
user.name = '李四';
user.name; // '李四'

// 对象冻结(不可修改)
const frozen = Object.freeze({ a: 1 });
// frozen.a = 2; // 错误(严格模式下)

// 对象密封(不能添加或删除属性)
const sealed = Object.seal({ a: 1 });
sealed.b = 2; // 错误
delete sealed.a; // 错误
sealed.a = 2; // 正确

7.2 数组

javascript 复制代码
// 数组创建
const arr1 = [1, 2, 3];
const arr2 = new Array(1, 2, 3);
const arr3 = Array.of(1, 2, 3);
const arr4 = Array(3); // [empty × 3]

// 数组访问
arr1[0]; // 1
arr1[arr1.length - 1]; // 3

// 数组长度
arr1.length; // 3

// 添加元素
arr1.push(4); // 尾部添加
arr1.unshift(0); // 头部添加

// 删除元素
arr1.pop(); // 尾部删除
arr1.shift(); // 头部删除

// 数组方法
// splice - 删除/插入/替换
const arr = [1, 2, 3, 4, 5];
arr.splice(2, 1); // 删除索引2的元素 -> [1, 2, 4, 5]
arr.splice(2, 0, 3); // 在索引2处插入3 -> [1, 2, 3, 4, 5]
arr.splice(2, 1, 99); // 替换索引2的元素 -> [1, 2, 99, 4, 5]

// slice - 切片
const sliced = arr.slice(1, 3); // [2, 99]

// concat - 连接
const arrA = [1, 2];
const arrB = [3, 4];
const arrC = arrA.concat(arrB); // [1, 2, 3, 4]

// join - 连接成字符串
const str = [1, 2, 3].join('-'); // '1-2-3'

// reverse - 反转
const reversed = [1, 2, 3].reverse(); // [3, 2, 1]

// sort - 排序
const nums = [3, 1, 4, 1, 5, 9, 2, 6];
nums.sort(); // [1, 1, 2, 3, 4, 5, 6, 9](按字符串排序)
nums.sort((a, b) => a - b); // [1, 1, 2, 3, 4, 5, 6, 9](按数字排序)

// indexOf / lastIndexOf - 查找索引
const fruits = ['苹果', '香蕉', '橙子'];
fruits.indexOf('香蕉'); // 1
fruits.indexOf('葡萄'); // -1
fruits.lastIndexOf('苹果'); // 0

// includes - 检查是否包含
fruits.includes('香蕉'); // true
fruits.includes('葡萄'); // false

// find - 查找元素
const users = [
    { id: 1, name: '张三' },
    { id: 2, name: '李四' }
];
const user = users.find(u => u.id === 2); // { id: 2, name: '李四' }

// findIndex - 查找索引
const index = users.findIndex(u => u.id === 2); // 1

// forEach - 遍历
[1, 2, 3].forEach((item, index) => {
    console.log(index, item);
});

// map - 映射
const doubled = [1, 2, 3].map(n => n * 2); // [2, 4, 6]

// filter - 过滤
const evens = [1, 2, 3, 4, 5].filter(n => n % 2 === 0); // [2, 4]

// reduce - 归约
const sum = [1, 2, 3, 4, 5].reduce((acc, n) => acc + n, 0); // 15

// some - 是否有满足条件的
const hasEven = [1, 3, 5, 7, 8].some(n => n % 2 === 0); // true

// every - 是否都满足条件
const allPositive = [1, 2, 3, 4, 5].every(n => n > 0); // true

// 数组解构
const [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(first, second, rest); // 1, 2, [3, 4, 5]

// 数组展开运算符
const arrA = [1, 2];
const arrB = [...arrA, 3, 4]; // [1, 2, 3, 4]

// Array.from - 从类数组创建数组
const arrayLike = { 0: 'a', 1: 'b', length: 2 };
Array.from(arrayLike); // ['a', 'b']

// Array.isArray - 检查是否为数组
Array.isArray([1, 2, 3]); // true
Array.isArray({}); // false

// 数组扁平化
const nested = [1, [2, [3, [4]]]];
nested.flat(Infinity); // [1, 2, 3, 4]

// 数组去重
const unique = [1, 2, 2, 3, 3, 4];
[...new Set(unique)]; // [1, 2, 3, 4]

八、ES6+新特性

8.1 let和const

javascript 复制代码
// let - 块级作用域
for (let i = 0; i < 3; i++) {
    console.log(i); // 0, 1, 2
}
// console.log(i); // 错误:i不存在

// const - 常量
const PI = 3.14159;
// PI = 3.14; // 错误:不能重新赋值

// const 对象
const person = { name: '张三' };
person.name = '李四'; // 正确
// person = {}; // 错误:不能重新赋值

8.2 箭头函数

javascript 复制代码
// 基本语法
const add = (a, b) => a + b;

// 单参数
const square = x => x * x;

// 多行代码
const greet = name => {
    const greeting = `Hello, ${name}!`;
    return greeting;
};

// 返回对象(需要括号)
const createPerson = (name, age) => ({ name, age });

// 箭头函数不绑定this
const obj = {
    name: '张三',
    greet: function() {
        setTimeout(() => {
            console.log(this.name); // '张三'
        }, 1000);
    }
};

8.3 模板字符串

javascript 复制代码
const name = '张三';
const age = 25;

// 基本用法
const greeting = `Hello, ${name}!`;
console.log(greeting); // 'Hello, 张三!'

// 多行字符串
const message = `
    你好,${name}
    今年${age}岁
`;

// 表达式
const result = `${name} ${age > 18 ? '成年' : '未成年'}`;

// 标签模板
function highlight(strings, ...values) {
    return strings.reduce((result, str, i) => {
        return result + str + (values[i] ? `<strong>${values[i]}</strong>` : '');
    }, '');
}

const highlighted = highlight`Hello, ${name}!`;
// 'Hello, <strong>张三</strong>!'

8.4 解构赋值

javascript 复制代码
// 数组解构
const [a, b, c] = [1, 2, 3];
const [first, , third] = [1, 2, 3];
const [x, y, ...rest] = [1, 2, 3, 4, 5];

// 对象解构
const { name, age } = { name: '张三', age: 25 };
const { name: personName, age: personAge } = { name: '张三', age: 25 };

// 默认值
const { city = '北京' } = { name: '张三' };

// 函数参数解构
function greet({ name, age }) {
    console.log(`${name}, ${age}岁`);
}
greet({ name: '张三', age: 25 });

// 嵌套解构
const user = {
    profile: {
        name: '张三',
        age: 25
    },
    address: {
        city: '北京'
    }
};
const { profile: { name, age }, address: { city } } = user;

8.5 展开运算符

javascript 复制代码
// 数组展开
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]

// 对象展开
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }

// 函数参数展开
function sum(...numbers) {
    return numbers.reduce((acc, n) => acc + n, 0);
}
sum(1, 2, 3, 4, 5); // 15

// 数组合并
const merged = [...arr1, ...[4, 5]]; // [1, 2, 3, 4, 5]

// 对象合并
const mergedObj = { ...obj1, ...{ c: 3, d: 4 } };

8.6 Promise和async/await

javascript 复制代码
// Promise基础
const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('成功');
    }, 1000);
});

promise.then(result => {
    console.log(result); // '成功'
}).catch(error => {
    console.error(error);
});

// Promise链
promise
    .then(result => result + '!')
    .then(result => result + '!!')
    .then(result => console.log(result)); // '成功!!'

// Promise.all
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);

Promise.all([promise1, promise2, promise3])
    .then(results => console.log(results)); // [1, 2, 3]

// Promise.race
Promise.race([promise1, promise2, promise3])
    .then(result => console.log(result)); // 1(最先完成的)

// async/await
async function fetchData() {
    try {
        const result = await promise;
        console.log(result); // '成功'
    } catch (error) {
        console.error(error);
    }
}

fetchData();

// async函数返回Promise
async function asyncFunction() {
    return '返回值';
}
asyncFunction().then(result => console.log(result)); // '返回值'

// 并行执行
async function parallel() {
    const [result1, result2] = await Promise.all([
        promise1,
        promise2
    ]);
    console.log(result1, result2); // 1, 2
}
parallel();

8.7 Class类

javascript 复制代码
// 基本类
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    greet() {
        console.log(`Hello, ${this.name}!`);
    }

    static createAnonymous() {
        return new Person('匿名', 0);
    }
}

const person = new Person('张三', 25);
person.greet(); // 'Hello, 张三!'
const anonymous = Person.createAnonymous();

// 继承
class Student extends Person {
    constructor(name, age, grade) {
        super(name, age);
        this.grade = grade;
    }

    study() {
        console.log(`${this.name}正在学习`);
    }

    greet() {
        super.greet();
        console.log(`我是${this.grade}年级学生`);
    }
}

const student = new Student('李四', 20, 3);
student.greet(); // 'Hello, 李四!' '我是3年级学生'
student.study(); // '李四正在学习'

// Getter和Setter
class User {
    constructor(name) {
        this._name = name;
    }

    get name() {
        return this._name;
    }

    set name(value) {
        this._name = value;
    }
}

const user = new User('张三');
console.log(user.name); // '张三'
user.name = '李四';
console.log(user.name); // '李四'

8.8 模块化

javascript 复制代码
// 导出
// math.js
export const PI = 3.14159;
export function add(a, b) {
    return a + b;
}
export function subtract(a, b) {
    return a - b;
}

// 默认导出
export default function multiply(a, b) {
    return a * b;
}

// 导入
// main.js
import multiply, { PI, add, subtract } from './math.js';
import * as math from './math.js';

console.log(PI); // 3.14159
console.log(add(1, 2)); // 3
console.log(multiply(3, 4)); // 12
console.log(math.subtract(5, 3)); // 2

8.9 其他新特性

javascript 复制代码
// Symbol
const sym = Symbol('description');
const obj = { [sym]: 'value' };

// Proxy
const handler = {
    get: function(target, property) {
        console.log(`Getting ${property}`);
        return target[property];
    },
    set: function(target, property, value) {
        console.log(`Setting ${property} to ${value}`);
        target[property] = value;
    }
};

const proxy = new Proxy({}, handler);
proxy.name = '张三'; // 'Setting name to 张三'
console.log(proxy.name); // 'Getting name' '张三'

// Reflect
const obj = { name: '张三' };
Reflect.get(obj, 'name'); // '张三'
Reflect.set(obj, 'age', 25); // true

// Map
const map = new Map();
map.set('key', 'value');
map.get('key'); // 'value'
map.has('key'); // true
map.delete('key'); // true

// Set
const set = new Set([1, 2, 3, 3]);
set.add(4);
set.has(3); // true
set.delete(3); // true

// WeakMap
const weakMap = new WeakMap();
const key = {};
weakMap.set(key, 'value');
weakMap.get(key); // 'value'

// WeakSet
const weakSet = new WeakSet();
const obj = {};
weakSet.add(obj);
weakSet.has(obj); // true

// Array.from
Array.from([1, 2, 3]); // [1, 2, 3]
Array.from('hello'); // ['h', 'e', 'l', 'l', 'o']

// Array.of
Array.of(1, 2, 3); // [1, 2, 3]

// Object.assign
const target = { a: 1 };
const source = { b: 2 };
Object.assign(target, source); // { a: 1, b: 2 }

// Object.is
Object.is(NaN, NaN); // true
Object.is(+0, -0); // false

// 字符串方法
'hello'.includes('ell'); // true
'hello'.startsWith('he'); // true
'hello'.endsWith('lo'); // true
'hello'.repeat(3); // 'hellohellohello'
'hello'.padStart(10, '='); // '=====hello'
'hello'.padEnd(10, '='); // 'hello====='

// 数组方法
[1, 2, 3].includes(2); // true
[1, 2, 3].findIndex(x => x > 1); // 1
[1, 2, 3].copyWithin(0, 2); // [3, 2, 3]

// 数组填充
new Array(5).fill(0); // [0, 0, 0, 0, 0]

// 指数运算符
2 ** 3; // 8
Math.pow(2, 3); // 8

九、DOM操作

9.1 选择元素

javascript 复制代码
// 选择单个元素
document.getElementById('myId');
document.querySelector('.myClass');
document.querySelector('div > p');

// 选择多个元素
document.getElementsByClassName('myClass'); // HTMLCollection
document.getElementsByTagName('div'); // HTMLCollection
document.querySelectorAll('.myClass'); // NodeList

// 遍历NodeList
document.querySelectorAll('.item').forEach(item => {
    console.log(item);
});

9.2 修改元素

javascript 复制代码
// 获取和设置属性
const element = document.getElementById('myId');
element.getAttribute('class');
element.setAttribute('class', 'newClass');
element.removeAttribute('class');

// 获取和设置样式
element.style.color = 'red';
element.style.backgroundColor = 'blue';
element.style.fontSize = '16px';

// class操作
element.classList.add('active');
element.classList.remove('inactive');
element.classList.toggle('active');
element.classList.contains('active');

// 修改内容
element.textContent = '文本内容';
element.innerHTML = '<strong>HTML内容</strong>';
element.innerText = '文本内容';

// 修改value(表单元素)
const input = document.getElementById('myInput');
input.value = '新值';

9.3 创建和删除元素

javascript 复制代码
// 创建元素
const newElement = document.createElement('div');
newElement.textContent = '新元素';
newElement.classList.add('new-item');

// 添加元素
document.body.appendChild(newElement);
document.body.insertBefore(newElement, document.body.firstChild);

// 删除元素
const oldElement = document.getElementById('oldId');
oldElement.remove();
// 或
oldElement.parentNode.removeChild(oldElement);

// 替换元素
const parent = document.getElementById('parent');
const newElement = document.createElement('div');
const oldElement = document.getElementById('oldId');
parent.replaceChild(newElement, oldElement);

// 克隆元素
const cloned = element.cloneNode(true); // true表示克隆子节点

9.4 事件处理

javascript 复制代码
// 添加事件监听
const button = document.getElementById('myButton');
button.addEventListener('click', function(event) {
    console.log('按钮被点击');
    console.log(event);
});

// 移除事件监听
function handleClick(event) {
    console.log('按钮被点击');
}
button.addEventListener('click', handleClick);
button.removeEventListener('click', handleClick);

// 事件对象
button.addEventListener('click', function(event) {
    event.preventDefault(); // 阻止默认行为
    event.stopPropagation(); // 阻止事件冒泡
    console.log(event.target); // 触发事件的元素
    console.log(event.currentTarget); // 绑定事件的元素
});

// 常用事件类型
button.addEventListener('click', handler); // 点击
input.addEventListener('input', handler); // 输入
input.addEventListener('change', handler); // 改变
form.addEventListener('submit', handler); // 提交
window.addEventListener('load', handler); // 加载完成
window.addEventListener('resize', handler); // 窗口大小改变
window.addEventListener('scroll', handler); // 滚动

// 事件委托
document.getElementById('list').addEventListener('click', function(event) {
    if (event.target.classList.contains('item')) {
        console.log('列表项被点击');
    }
});

9.5 DOM遍历

javascript 复制代码
// 父子关系
element.parentNode; // 父节点
element.parentElement; // 父元素
element.childNodes; // 所有子节点
element.children; // 所有子元素
element.firstChild; // 第一个子节点
element.firstElementChild; // 第一个子元素
element.lastChild; // 最后一个子节点
element.lastElementChild; // 最后一个子元素

// 兄弟关系
element.previousSibling; // 前一个兄弟节点
element.previousElementSibling; // 前一个兄弟元素
element.nextSibling; // 后一个兄弟节点
element.nextElementSibling; // 后一个兄弟元素

// 查找元素
element.querySelector('.class');
element.querySelectorAll('.class');
element.closest('.parent'); // 查找最近的祖先元素

十、异步编程

10.1 回调函数

javascript 复制代码
// 基本回调
function fetchData(callback) {
    setTimeout(() => {
        const data = { name: '张三', age: 25 };
        callback(data);
    }, 1000);
}

fetchData(function(data) {
    console.log(data);
});

// 回调地狱(不推荐)
fetchData(function(data1) {
    fetchData(function(data2) {
        fetchData(function(data3) {
            console.log(data1, data2, data3);
        });
    });
});

10.2 Promise

javascript 复制代码
// 创建Promise
const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        const success = true;
        if (success) {
            resolve('成功');
        } else {
            reject('失败');
        }
    }, 1000);
});

// 使用Promise
promise
    .then(result => {
        console.log(result);
        return result + '!';
    })
    .then(result => {
        console.log(result);
    })
    .catch(error => {
        console.error(error);
    })
    .finally(() => {
        console.log('完成');
    });

// Promise链
function fetchUser(id) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve({ id, name: '张三' });
        }, 1000);
    });
}

function fetchPosts(userId) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve([
                { id: 1, userId, title: '文章1' },
                { id: 2, userId, title: '文章2' }
            ]);
        }, 1000);
    });
}

fetchUser(1)
    .then(user => fetchPosts(user.id))
    .then(posts => console.log(posts))
    .catch(error => console.error(error));

// Promise.all
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);

Promise.all([promise1, promise2, promise3])
    .then(results => console.log(results)); // [1, 2, 3]

// Promise.race
Promise.race([promise1, promise2, promise3])
    .then(result => console.log(result)); // 1

// Promise.allSettled
Promise.allSettled([
    Promise.resolve(1),
    Promise.reject(2),
    Promise.resolve(3)
]).then(results => {
    console.log(results);
    // [
    //   { status: 'fulfilled', value: 1 },
    //   { status: 'rejected', reason: 2 },
    //   { status: 'fulfilled', value: 3 }
    // ]
});

10.3 async/await

javascript 复制代码
// 基本用法
async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error(error);
    }
}

fetchData();

// async函数返回Promise
async function asyncFunction() {
    return '返回值';
}
asyncFunction().then(result => console.log(result)); // '返回值'

// 并行执行
async function parallel() {
    const [result1, result2] = await Promise.all([
        fetchUser(1),
        fetchUser(2)
    ]);
    console.log(result1, result2);
}

// 顺序执行
async function sequential() {
    const user1 = await fetchUser(1);
    const user2 = await fetchUser(2);
    console.log(user1, user2);
}

// 错误处理
async function withErrorHandling() {
    try {
        const data = await fetchData();
        return data;
    } catch (error) {
        console.error('发生错误:', error);
        return null;
    } finally {
        console.log('清理资源');
    }
}

10.4 Generator函数

javascript 复制代码
// 基本用法
function* generator() {
    yield 1;
    yield 2;
    yield 3;
}

const gen = generator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }

// 生成器函数
function* fibonacci() {
    let [a, b] = [0, 1];
    while (true) {
        yield a;
        [a, b] = [b, a + b];
    }
}

const fib = fibonacci();
console.log(fib.next().value); // 0
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2

// for...of遍历
for (const num of fibonacci()) {
    if (num > 100) break;
    console.log(num);
}

十一、错误处理

11.1 try-catch-finally

javascript 复制代码
try {
    // 可能出错的代码
    const result = 10 / 0;
    console.log(result);
} catch (error) {
    // 捕获错误
    console.error('发生错误:', error.message);
} finally {
    // 无论是否出错都会执行
    console.log('清理资源');
}

11.2 错误类型

javascript 复制代码
// Error - 基础错误
throw new Error('普通错误');

// TypeError - 类型错误
throw new TypeError('类型错误');

// ReferenceError - 引用错误
throw new ReferenceError('引用错误');

// SyntaxError - 语法错误
throw new SyntaxError('语法错误');

// RangeError - 范围错误
throw new RangeError('范围错误');

// URIError - URI错误
throw new URIError('URI错误');

// EvalError - Eval错误
throw new EvalError('Eval错误');

11.3 自定义错误

javascript 复制代码
class CustomError extends Error {
    constructor(message) {
        super(message);
        this.name = 'CustomError';
    }
}

throw new CustomError('自定义错误');

11.4 全局错误处理

javascript 复制代码
// 捕获未处理的Promise错误
window.addEventListener('unhandledrejection', event => {
    console.error('未处理的Promise错误:', event.reason);
});

// 捕获全局错误
window.addEventListener('error', event => {
    console.error('全局错误:', event.error);
});

十二、JavaScript最佳实践

12.1 代码规范

javascript 复制代码
// 使用const和let,避免var
const PI = 3.14159;
let count = 0;

// 使用语义化的变量名
const userName = '张三';
const userAge = 25;

// 使用一致的命名风格
const firstName = '张';
const lastName = '三';
const fullName = `${firstName}${lastName}`;

// 函数名使用动词开头
function getUserData() { }
function validateInput() { }
function handleSubmit() { }

// 避免全局变量
// ❌ 不好
globalVar = 'value';

// ✅ 好
const myModule = {
    localVar: 'value'
};

// 使用严格模式
'use strict';

// 避免使用eval和with
// ❌ 不好
eval('console.log("hello")');

// ✅ 好
console.log('hello');

12.2 性能优化

javascript 复制代码
// 避免在循环中创建函数
// ❌ 不好
for (let i = 0; i < 1000; i++) {
    document.getElementById('item' + i).addEventListener('click', function() {
        console.log(i);
    });
}

// ✅ 好
function handleClick(i) {
    return function() {
        console.log(i);
    };
}
for (let i = 0; i < 1000; i++) {
    document.getElementById('item' + i).addEventListener('click', handleClick(i));
}

// 使用事件委托
document.getElementById('list').addEventListener('click', function(event) {
    if (event.target.classList.contains('item')) {
        console.log('列表项被点击');
    }
});

// 避免频繁的DOM操作
// ❌ 不好
for (let i = 0; i < 1000; i++) {
    document.body.innerHTML += '<div>Item ' + i + '</div>';
}

// ✅ 好
let html = '';
for (let i = 0; i < 1000; i++) {
    html += '<div>Item ' + i + '</div>';
}
document.body.innerHTML = html;

// 使用文档片段
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
    const div = document.createElement('div');
    div.textContent = 'Item ' + i;
    fragment.appendChild(div);
}
document.body.appendChild(fragment);

// 防抖和节流
// 防抖
function debounce(func, wait) {
    let timeout;
    return function(...args) {
        clearTimeout(timeout);
        timeout = setTimeout(() => func.apply(this, args), wait);
    };
}

window.addEventListener('resize', debounce(function() {
    console.log('窗口大小改变');
}, 300));

// 节流
function throttle(func, limit) {
    let inThrottle;
    return function(...args) {
        if (!inThrottle) {
            func.apply(this, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}

window.addEventListener('scroll', throttle(function() {
    console.log('滚动');
}, 300));

12.3 安全性

javascript 复制代码
// 避免innerHTML,使用textContent
// ❌ 不好
element.innerHTML = userInput;

// ✅ 好
element.textContent = userInput;

// 输入验证
function validateInput(input) {
    // 去除HTML标签
    const sanitized = input.replace(/<[^>]*>/g, '');
    // 限制长度
    return sanitized.substring(0, 100);
}

// 防止XSS
function escapeHtml(unsafe) {
    return unsafe
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
}

// 使用HTTPS
// API请求使用HTTPS
fetch('https://api.example.com/data');

// 验证API响应
async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        if (!response.ok) {
            throw new Error('网络响应不正常');
        }
        const data = await response.json();
        // 验证数据结构
        if (!data || typeof data !== 'object') {
            throw new Error('无效的数据格式');
        }
        return data;
    } catch (error) {
        console.error('获取数据失败:', error);
        throw error;
    }
}

12.4 可维护性

javascript 复制代码
// 模块化
// utils.js
export function formatDate(date) {
    return date.toISOString();
}

export function validateEmail(email) {
    const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return regex.test(email);
}

// api.js
import { formatDate } from './utils.js';

export async function fetchUserData(userId) {
    const response = await fetch(`/api/users/${userId}`);
    const data = await response.json();
    return {
        ...data,
        formattedDate: formatDate(new Date(data.createdAt))
    };
}

// 使用注释
/**
 * 计算两个数字的和
 * @param {number} a - 第一个数字
 * @param {number} b - 第二个数字
 * @returns {number} 两个数字的和
 */
function add(a, b) {
    return a + b;
}

// 使用常量
const API_URL = 'https://api.example.com';
const MAX_RETRY_COUNT = 3;
const TIMEOUT_MS = 5000;

// 错误处理
async function fetchData() {
    try {
        const response = await fetch(API_URL);
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        return await response.json();
    } catch (error) {
        console.error('获取数据失败:', error);
        throw error;
    }
}

十三、实战示例

13.1 待办事项应用

javascript 复制代码
class TodoApp {
    constructor() {
        this.todos = [];
        this.init();
    }

    init() {
        this.loadTodos();
        this.render();
        this.bindEvents();
    }

    loadTodos() {
        const stored = localStorage.getItem('todos');
        if (stored) {
            this.todos = JSON.parse(stored);
        }
    }

    saveTodos() {
        localStorage.setItem('todos', JSON.stringify(this.todos));
    }

    addTodo(text) {
        const todo = {
            id: Date.now(),
            text,
            completed: false,
            createdAt: new Date().toISOString()
        };
        this.todos.push(todo);
        this.saveTodos();
        this.render();
    }

    toggleTodo(id) {
        const todo = this.todos.find(t => t.id === id);
        if (todo) {
            todo.completed = !todo.completed;
            this.saveTodos();
            this.render();
        }
    }

    deleteTodo(id) {
        this.todos = this.todos.filter(t => t.id !== id);
        this.saveTodos();
        this.render();
    }

    render() {
        const todoList = document.getElementById('todoList');
        todoList.innerHTML = '';

        this.todos.forEach(todo => {
            const li = document.createElement('li');
            li.className = `todo-item ${todo.completed ? 'completed' : ''}`;
            li.innerHTML = `
                <input type="checkbox" ${todo.completed ? 'checked' : ''}>
                <span>${todo.text}</span>
                <button class="delete-btn">删除</button>
            `;

            li.querySelector('input').addEventListener('change', () => {
                this.toggleTodo(todo.id);
            });

            li.querySelector('.delete-btn').addEventListener('click', () => {
                this.deleteTodo(todo.id);
            });

            todoList.appendChild(li);
        });
    }

    bindEvents() {
        const form = document.getElementById('todoForm');
        form.addEventListener('submit', (e) => {
            e.preventDefault();
            const input = document.getElementById('todoInput');
            const text = input.value.trim();
            if (text) {
                this.addTodo(text);
                input.value = '';
            }
        });
    }
}

// 初始化应用
const app = new TodoApp();

13.2 API请求封装

javascript 复制代码
class ApiClient {
    constructor(baseURL) {
        this.baseURL = baseURL;
        this.defaultHeaders = {
            'Content-Type': 'application/json'
        };
    }

    async request(endpoint, options = {}) {
        const url = `${this.baseURL}${endpoint}`;
        const config = {
            ...options,
            headers: {
                ...this.defaultHeaders,
                ...options.headers
            }
        };

        try {
            const response = await fetch(url, config);
            
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const data = await response.json();
            return data;
        } catch (error) {
            console.error('API请求失败:', error);
            throw error;
        }
    }

    get(endpoint, params = {}) {
        const queryString = new URLSearchParams(params).toString();
        const url = queryString ? `${endpoint}?${queryString}` : endpoint;
        return this.request(url, { method: 'GET' });
    }

    post(endpoint, data) {
        return this.request(endpoint, {
            method: 'POST',
            body: JSON.stringify(data)
        });
    }

    put(endpoint, data) {
        return this.request(endpoint, {
            method: 'PUT',
            body: JSON.stringify(data)
        });
    }

    delete(endpoint) {
        return this.request(endpoint, {
            method: 'DELETE'
        });
    }
}

// 使用示例
const api = new ApiClient('https://api.example.com');

async function loadData() {
    try {
        const users = await api.get('/users');
        console.log(users);
    } catch (error) {
        console.error('加载用户失败');
    }
}

async function createUser(userData) {
    try {
        const user = await api.post('/users', userData);
        console.log('用户创建成功:', user);
    } catch (error) {
        console.error('创建用户失败');
    }
}

十四、总结

JavaScript是一门功能强大、应用广泛的编程语言。通过本文的学习,你应该掌握了:

  1. JavaScript基础概念和语法
  2. 变量、数据类型和运算符
  3. 控制流程和异常处理
  4. 函数和高阶函数
  5. 对象和数组的详细使用
  6. ES6+新特性
  7. DOM操作和事件处理
  8. 异步编程(Promise、async/await)
  9. 错误处理和最佳实践
  10. 完整的实战示例

学习建议

  • 多动手实践,创建自己的项目
  • 参考优秀的开源项目代码
  • 关注JavaScript的最新发展和特性
  • 深入理解JavaScript的核心概念(闭包、原型链、异步)
  • 养成良好的编码习惯和代码规范
  • 学习TypeScript提高代码质量

JavaScript的学习是一个持续的过程,随着技术的发展,JavaScript也在不断进化。保持学习的热情,不断提升自己的技能,你一定能成为一名优秀的前端开发者!


希望这篇JavaScript详解教程对你有所帮助!如果你有任何问题或建议,欢迎留言讨论。持续学习,不断进步,让我们一起在Web开发的道路上越走越远!

相关推荐
optimistic_chen1 小时前
【Vue3 入门】掌握这些才能优雅上手
前端·javascript·vue.js·前端框架·visual studio code
xuhaoyu_cpp_java1 小时前
JAVA线程安全类
java·开发语言
香水5只用六神1 小时前
【TIM】基本定时器定时实验(2)
c语言·开发语言·stm32·单片机·嵌入式硬件·mcu·学习
BatyTao1 小时前
Python从零起步-数据容器
开发语言·python
承渊政道1 小时前
C++学习之旅【C++伸展树介绍以及红黑树的实现】
开发语言·c++·笔记·b树·学习·visual studio
郭涤生1 小时前
C++中设置函数与回调函数设值的性能差异及示例
开发语言·c++
m0_635647481 小时前
Qt开发与MySQL数据库教程(二)——MySQL常用命令以及示例
java·开发语言·数据库·mysql
fie88892 小时前
Spinal码MATLAB实现(采用One-at-a-Time哈希函数)
开发语言·matlab·哈希算法
ZHOUPUYU2 小时前
PHP 8.6的底层革命。那些看不见的优化,才是真正的惊喜
开发语言·后端·php