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
<buttononclick="alert('Hello!')">点击我</button>
内部JavaScript
<script> console.log('Hello World!');</script>
外部JavaScript
<scriptsrc="script.js"></script>

注意

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

2.2 注释

// 单行注释/* * 多行注释 * 可以写多行 *//** * 文档注释 * @param {string} name - 名字 * @returns {string} - 问候语 */functiongreet(name){return`Hello, ${name}!`;}

2.3 语句和分号

// 使用分号(推荐)let a =1;let b =2;let c = a + b;// 不使用分号(自动插入分号)let a =1let b =2let c = a + b // 建议始终使用分号,避免潜在问题

三、变量和数据类型

3.1 变量声明

// var - 函数作用域(不推荐)var name ='张三';// let - 块级作用域(推荐)let age =25;// const - 常量,块级作用域(推荐)constPI=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)
// 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;// 100000let hex =0xff;// 255let binary =0b1010;// 10let 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)
// Object - 对象let obj ={name:'张三',age:25,sayHello:function(){ console.log('Hello!');}};// Array - 数组let arr =[1,2,3,'four',{five:5}];// Function - 函数functionmyFunction(){ console.log('Function');}letarrowFunction=()=>{ console.log('Arrow Function');};// Date - 日期let date =newDate();let date2 =newDate('2026-01-01');// RegExp - 正则表达式let regex =/pattern/g;let regex2 =newRegExp('pattern','g');// Map - 映射(ES6)let map =newMap(); map.set('key','value');// Set - 集合(ES6)let set =newSet([1,2,3,3]);// {1, 2, 3}

3.3 类型检测

// typeof - 检测基本类型 console.log(typeof42);// "number" console.log(typeof'hello');// "string" console.log(typeoftrue);// "boolean" console.log(typeofundefined);// "undefined" console.log(typeofnull);// "object"(历史原因) console.log(typeof{});// "object" console.log(typeof[]);// "object" console.log(typeoffunction(){});// "function"// instanceof - 检测对象类型 console.log([]instanceofArray);// true console.log({}instanceofObject);// true console.log(newDate()instanceofDate);// true// constructor - 构造函数 console.log([].constructor === Array);// true// Object.prototype.toString - 最精确的类型检测functiongetType(value){returnObject.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');// 123Number('123abc');// NaNNumber('');// 0Number(true);// 1Number(false);// 0Number(null);// 0Number(undefined);// NaNparseInt('123');// 123parseInt('123abc');// 123parseFloat('3.14');// 3.14// 转为布尔值Boolean(0);// falseBoolean('');// falseBoolean(null);// falseBoolean(undefined);// falseBoolean(NaN);// falseBoolean(false);// false// 其他都是trueBoolean(1);// trueBoolean('hello');// trueBoolean([]);// trueBoolean({});// true

四、运算符

4.1 算术运算符

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 比较运算符

// 相等1==1;// true1=='1';// true(类型转换)1===1;// true(严格相等)1==='1';// false(类型不同)// 不等1!=2;// true1!='1';// false1!==2;// true1!=='1';// true// 大于5>3;// true5>=5;// true// 小于3<5;// true5<=5;// true// Object.is - 严格相等(处理特殊情况) Object.is(NaN,NaN);// true Object.is(+0,-0);// false

4.3 逻辑运算符

// 逻辑与true&&true;// truetrue&&false;// falsefalse&&true;// falsefalse&&false;// false// 短路求值let a =1;let b = a >0&& a <10;// truelet c = a >10&& console.log('不会执行');// undefined// 逻辑或true||true;// truetrue||false;// truefalse||true;// truefalse||false;// false// 短路求值let d = a >0|| a <0;// truelet e = a >10|| console.log('会执行');// 会执行// 逻辑非!true;// false!false;// true// 空值合并运算符(ES2020)let f =null??'default';// 'default'let g =undefined??'default';// 'default'let h =0??'default';// 0let i =''??'default';// ''// 可选链运算符(ES2020)let user ={profile:{name:'张三'}}; user?.profile?.name;// '张三' user?.address?.city;// undefined

4.4 赋值运算符

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, 2let{ name, age }={name:'张三',age:25}; console.log(name, age);// '张三', 25

4.5 位运算符

let a =5;// 二进制: 101let 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 条件运算符

// 三元运算符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 条件语句

// if-elselet score =85;if(score >=90){ console.log('优秀');}elseif(score >=80){ console.log('良好');}elseif(score >=60){ console.log('及格');}else{ console.log('不及格');}// switchlet 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){case10: console.log('数字10');break;case'10': console.log('字符串10');// 输出这个break;}

5.2 循环语句

// 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和continuefor(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 异常处理

// try-catch-finallytry{// 可能出错的代码let result =10/0; console.log(result);}catch(error){// 捕获错误 console.error('发生错误:', error.message);}finally{// 无论是否出错都会执行 console.log('清理资源');}// 抛出错误functiondivide(a, b){if(b ===0){thrownewError('除数不能为0');}return a / b;}try{divide(10,0);}catch(error){ console.error(error.message);}// 错误类型newError('普通错误');newTypeError('类型错误');newReferenceError('引用错误');newSyntaxError('语法错误');newRangeError('范围错误');newURIError('URI错误');newEvalError('Eval错误');

六、函数

6.1 函数定义

// 函数声明functiongreet(name){return`Hello, ${name}!`;}// 函数表达式constgreet2=function(name){return`Hello, ${name}!`;};// 箭头函数(ES6)constgreet3=(name)=>{return`Hello, ${name}!`;};// 箭头函数简写constgreet4=name=>`Hello, ${name}!`;// 箭头函数多个参数constadd=(a, b)=> a + b;// 箭头函数返回对象(需要括号)constcreateUser=(name, age)=>({ name, age });// 立即执行函数(function(){ console.log('立即执行');})();// 箭头函数版本的立即执行函数(()=>{ console.log('立即执行');})();// 函数构造器(不推荐)const greet5 =newFunction('name','return `Hello, ${name}!`');

6.2 函数参数

// 默认参数functiongreet(name ='World'){return`Hello, ${name}!`;}greet();// 'Hello, World!'// 剩余参数functionsum(...numbers){return numbers.reduce((acc, num)=> acc + num,0);}sum(1,2,3,4,5);// 15// 参数解构functiongreetUser({ name, age }){ console.log(`${name}, ${age}岁`);}greetUser({name:'张三',age:25});// 结合默认参数和解构functioncreateUser({ name ='匿名', age =0}={}){return{ name, age };}createUser();// { name: '匿名', age: 0 }createUser({name:'李四'});// { name: '李四', age: 0 }

6.3 作用域和闭包

// 函数作用域functionouter(){let outerVar ='outer';functioninner(){let innerVar ='inner'; console.log(outerVar);// 可以访问外部变量 console.log(innerVar);}inner();// console.log(innerVar); // 错误:无法访问内部变量}// 块级作用域{let blockVar ='block'; console.log(blockVar);}// console.log(blockVar); // 错误:无法访问// 闭包functioncreateCounter(){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// 闭包应用:模拟私有变量functioncreatePerson(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关键字

// 方法中的thisconst 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、bindfunctiongreet(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 高阶函数

// 函数作为参数functionexecute(fn){fn();}execute(function(){ console.log('执行函数');});// 函数作为返回值functioncreateMultiplier(factor){returnfunction(number){return number * factor;};}const double =createMultiplier(2);const triple =createMultiplier(3); console.log(double(5));// 10 console.log(triple(5));// 15// 回调函数functionfetchData(callback){setTimeout(()=>{const data ={name:'张三',age:25};callback(data);},1000);}fetchData(function(data){ console.log(data);});// 数组高阶函数const numbers =[1,2,3,4,5];// mapconst doubled = numbers.map(n=> n *2); console.log(doubled);// [2, 4, 6, 8, 10]// filterconst evens = numbers.filter(n=> n %2===0); console.log(evens);// [2, 4]// reduceconst sum = numbers.reduce((acc, n)=> acc + n,0); console.log(sum);// 15// findconst found = numbers.find(n=> n >3); console.log(found);// 4// someconst hasEven = numbers.some(n=> n %2===0); console.log(hasEven);// true// everyconst allPositive = numbers.every(n=> n >0); console.log(allPositive);// true// forEach numbers.forEach(n=> console.log(n));

七、对象和数组

7.1 对象

// 对象字面量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和setterconst user ={_name:'张三',getname(){returnthis._name;},setname(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 数组

// 数组创建const arr1 =[1,2,3];const arr2 =newArray(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];[...newSet(unique)];// [1, 2, 3, 4]

八、ES6+新特性

8.1 let和const

// let - 块级作用域for(let i =0; i <3; i++){ console.log(i);// 0, 1, 2}// console.log(i); // 错误:i不存在// const - 常量constPI=3.14159;// PI = 3.14; // 错误:不能重新赋值// const 对象const person ={name:'张三'}; person.name ='李四';// 正确// person = {}; // 错误:不能重新赋值

8.2 箭头函数

// 基本语法constadd=(a, b)=> a + b;// 单参数constsquare=x=> x * x;// 多行代码constgreet=name=>{const greeting =`Hello, ${name}!`;return greeting;};// 返回对象(需要括号)constcreatePerson=(name, age)=>({ name, age });// 箭头函数不绑定thisconst obj ={name:'张三',greet:function(){setTimeout(()=>{ console.log(this.name);// '张三'},1000);}};

8.3 模板字符串

const name ='张三';const age =25;// 基本用法const greeting =`Hello, ${name}!`; console.log(greeting);// 'Hello, 张三!'// 多行字符串const message =` 你好,${name} 今年${age}岁 `;// 表达式const result =`${name}${age >18?'成年':'未成年'}`;// 标签模板functionhighlight(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 解构赋值

// 数组解构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:'张三'};// 函数参数解构functiongreet({ 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 展开运算符

// 数组展开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 }// 函数参数展开functionsum(...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

// Promise基础const promise =newPromise((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.allconst 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/awaitasyncfunctionfetchData(){try{const result =await promise; console.log(result);// '成功'}catch(error){ console.error(error);}}fetchData();// async函数返回PromiseasyncfunctionasyncFunction(){return'返回值';}asyncFunction().then(result=> console.log(result));// '返回值'// 并行执行asyncfunctionparallel(){const[result1, result2]=await Promise.all([ promise1, promise2 ]); console.log(result1, result2);// 1, 2}parallel();

8.7 Class类

// 基本类classPerson{constructor(name, age){this.name = name;this.age = age;}greet(){ console.log(`Hello, ${this.name}!`);}staticcreateAnonymous(){returnnewPerson('匿名',0);}}const person =newPerson('张三',25); person.greet();// 'Hello, 张三!'const anonymous = Person.createAnonymous();// 继承classStudentextendsPerson{constructor(name, age, grade){super(name, age);this.grade = grade;}study(){ console.log(`${this.name}正在学习`);}greet(){super.greet(); console.log(`我是${this.grade}年级学生`);}}const student =newStudent('李四',20,3); student.greet();// 'Hello, 李四!' '我是3年级学生' student.study();// '李四正在学习'// Getter和SetterclassUser{constructor(name){this._name = name;}getname(){returnthis._name;}setname(value){this._name = value;}}const user =newUser('张三'); console.log(user.name);// '张三' user.name ='李四'; console.log(user.name);// '李四'

8.8 模块化

// 导出// math.jsexportconstPI=3.14159;exportfunctionadd(a, b){return a + b;}exportfunctionsubtract(a, b){return a - b;}// 默认导出exportdefaultfunctionmultiply(a, b){return a * b;}// 导入// main.jsimport 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 其他新特性

// Symbolconst sym =Symbol('description');const obj ={[sym]:'value'};// Proxyconst 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 =newProxy({}, handler); proxy.name ='张三';// 'Setting name to 张三' console.log(proxy.name);// 'Getting name' '张三'// Reflectconst obj ={name:'张三'}; Reflect.get(obj,'name');// '张三' Reflect.set(obj,'age',25);// true// Mapconst map =newMap(); map.set('key','value'); map.get('key');// 'value' map.has('key');// true map.delete('key');// true// Setconst set =newSet([1,2,3,3]); set.add(4); set.has(3);// true set.delete(3);// true// WeakMapconst weakMap =newWeakMap();const key ={}; weakMap.set(key,'value'); weakMap.get(key);// 'value'// WeakSetconst weakSet =newWeakSet();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.assignconst 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]// 数组填充newArray(5).fill(0);// [0, 0, 0, 0, 0]// 指数运算符2**3;// 8 Math.pow(2,3);// 8

九、DOM操作

9.1 选择元素

// 选择单个元素 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 修改元素

// 获取和设置属性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 创建和删除元素

// 创建元素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 事件处理

// 添加事件监听const button = document.getElementById('myButton'); button.addEventListener('click',function(event){ console.log('按钮被点击'); console.log(event);});// 移除事件监听functionhandleClick(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遍历

// 父子关系 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 回调函数

// 基本回调functionfetchData(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

// 创建Promiseconst promise =newPromise((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链functionfetchUser(id){returnnewPromise(resolve=>{setTimeout(()=>{resolve({ id,name:'张三'});},1000);});}functionfetchPosts(userId){returnnewPromise(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.allconst 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

// 基本用法asyncfunctionfetchData(){try{const response =awaitfetch('https://api.example.com/data');const data =await response.json(); console.log(data);}catch(error){ console.error(error);}}fetchData();// async函数返回PromiseasyncfunctionasyncFunction(){return'返回值';}asyncFunction().then(result=> console.log(result));// '返回值'// 并行执行asyncfunctionparallel(){const[result1, result2]=await Promise.all([fetchUser(1),fetchUser(2)]); console.log(result1, result2);}// 顺序执行asyncfunctionsequential(){const user1 =awaitfetchUser(1);const user2 =awaitfetchUser(2); console.log(user1, user2);}// 错误处理asyncfunctionwithErrorHandling(){try{const data =awaitfetchData();return data;}catch(error){ console.error('发生错误:', error);returnnull;}finally{ console.log('清理资源');}}

10.4 Generator函数

// 基本用法function*generator(){yield1;yield2;yield3;}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 offibonacci()){if(num >100)break; console.log(num);}

十一、错误处理

11.1 try-catch-finally

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

11.2 错误类型

// Error - 基础错误thrownewError('普通错误');// TypeError - 类型错误thrownewTypeError('类型错误');// ReferenceError - 引用错误thrownewReferenceError('引用错误');// SyntaxError - 语法错误thrownewSyntaxError('语法错误');// RangeError - 范围错误thrownewRangeError('范围错误');// URIError - URI错误thrownewURIError('URI错误');// EvalError - Eval错误thrownewEvalError('Eval错误');

11.3 自定义错误

classCustomErrorextendsError{constructor(message){super(message);this.name ='CustomError';}}thrownewCustomError('自定义错误');

11.4 全局错误处理

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

十二、JavaScript最佳实践

12.1 代码规范

// 使用const和let,避免varconstPI=3.14159;let count =0;// 使用语义化的变量名const userName ='张三';const userAge =25;// 使用一致的命名风格const firstName ='张';const lastName ='三';const fullName =`${firstName}${lastName}`;// 函数名使用动词开头functiongetUserData(){}functionvalidateInput(){}functionhandleSubmit(){}// 避免全局变量// ❌ 不好 globalVar ='value';// ✅ 好const myModule ={localVar:'value'};// 使用严格模式'use strict';// 避免使用eval和with// ❌ 不好eval('console.log("hello")');// ✅ 好 console.log('hello');

12.2 性能优化

// 避免在循环中创建函数// ❌ 不好for(let i =0; i <1000; i++){ document.getElementById('item'+ i).addEventListener('click',function(){ console.log(i);});}// ✅ 好functionhandleClick(i){returnfunction(){ 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);// 防抖和节流// 防抖functiondebounce(func, wait){let timeout;returnfunction(...args){clearTimeout(timeout); timeout =setTimeout(()=>func.apply(this, args), wait);};} window.addEventListener('resize',debounce(function(){ console.log('窗口大小改变');},300));// 节流functionthrottle(func, limit){let inThrottle;returnfunction(...args){if(!inThrottle){func.apply(this, args); inThrottle =true;setTimeout(()=> inThrottle =false, limit);}};} window.addEventListener('scroll',throttle(function(){ console.log('滚动');},300));

12.3 安全性

// 避免innerHTML,使用textContent// ❌ 不好 element.innerHTML = userInput;// ✅ 好 element.textContent = userInput;// 输入验证functionvalidateInput(input){// 去除HTML标签const sanitized = input.replace(/<[^>]*>/g,'');// 限制长度return sanitized.substring(0,100);}// 防止XSSfunctionescapeHtml(unsafe){return unsafe .replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;");}// 使用HTTPS// API请求使用HTTPSfetch('https://api.example.com/data');// 验证API响应asyncfunctionfetchData(){try{const response =awaitfetch('https://api.example.com/data');if(!response.ok){thrownewError('网络响应不正常');}const data =await response.json();// 验证数据结构if(!data ||typeof data !=='object'){thrownewError('无效的数据格式');}return data;}catch(error){ console.error('获取数据失败:', error);throw error;}}

12.4 可维护性

// 模块化// utils.jsexportfunctionformatDate(date){return date.toISOString();}exportfunctionvalidateEmail(email){const regex =/^[^\s@]+@[^\s@]+\.[^\s@]+$/;return regex.test(email);}// api.jsimport{ formatDate }from'./utils.js';exportasyncfunctionfetchUserData(userId){const response =awaitfetch(`/api/users/${userId}`);const data =await response.json();return{...data,formattedDate:formatDate(newDate(data.createdAt))};}// 使用注释/** * 计算两个数字的和 * @param {number} a - 第一个数字 * @param {number} b - 第二个数字 * @returns {number} 两个数字的和 */functionadd(a, b){return a + b;}// 使用常量constAPI_URL='https://api.example.com';constMAX_RETRY_COUNT=3;constTIMEOUT_MS=5000;// 错误处理asyncfunctionfetchData(){try{const response =awaitfetch(API_URL);if(!response.ok){thrownewError(`HTTP error! status: ${response.status}`);}returnawait response.json();}catch(error){ console.error('获取数据失败:', error);throw error;}}

十三、实战示例

13.1 待办事项应用

classTodoApp{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:newDate().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>删除</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 =newTodoApp();

13.2 API请求封装

classApiClient{constructor(baseURL){this.baseURL = baseURL;this.defaultHeaders ={'Content-Type':'application/json'};}asyncrequest(endpoint, options ={}){const url =`${this.baseURL}${endpoint}`;const config ={...options,headers:{...this.defaultHeaders,...options.headers }};try{const response =awaitfetch(url, config);if(!response.ok){thrownewError(`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 =newURLSearchParams(params).toString();const url = queryString ?`${endpoint}?${queryString}`: endpoint;returnthis.request(url,{method:'GET'});}post(endpoint, data){returnthis.request(endpoint,{method:'POST',body:JSON.stringify(data)});}put(endpoint, data){returnthis.request(endpoint,{method:'PUT',body:JSON.stringify(data)});}delete(endpoint){returnthis.request(endpoint,{method:'DELETE'});}}// 使用示例const api =newApiClient('https://api.example.com');asyncfunctionloadData(){try{const users =await api.get('/users'); console.log(users);}catch(error){ console.error('加载用户失败');}}asyncfunctioncreateUser(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开发的道路上越走越远!

Read more

(第三篇)Spring AI 实战进阶:从0开发IDEA插件版AI代码助手(Java全栈+上下文感知)

(第三篇)Spring AI 实战进阶:从0开发IDEA插件版AI代码助手(Java全栈+上下文感知)

前言 作为 Java 开发者,我们每天都在重复编写 CRUD 代码、调试语法错误、优化性能问题 —— 这些机械性工作占用了大量时间,而市面上的通用 AI 代码助手(如 Copilot)往往无法精准感知项目上下文(比如项目的包结构、依赖版本、数据库表结构),生成的代码需要大量修改才能落地。 笔者近期基于 Spring AI+IDEA 插件开发了一款定制化 AI 代码助手:后端基于 Spring AI 整合 JavaParser、Maven API 实现代码解析与生成,前端通过 IDEA 插件提供对话窗口和一键插入代码功能,支持需求描述→完整代码生成代码优化、上下文感知、补全三大核心能力。本文将从实战角度,完整拆解这款 AI 代码助手的开发全流程,所有代码均为生产环境可直接复用的实战代码,同时结合可视化图表清晰呈现核心逻辑,希望能帮你打造专属的 AI

By Ne0inhk
个人所得税的APP模拟器,纯java版代码开源,截图录屏都可以【仅供参考】

个人所得税的APP模拟器,纯java版代码开源,截图录屏都可以【仅供参考】

文件下载地址:https://wenshushu.vip/pan/index.php?id=36    提取码:7bf9 给大家分享一个用纯Java实现的个人所得税计算模拟器,包含完整的GUI界面和核心计算逻辑,适合Java学习者和税务计算需求者参考使用。 一、项目简介 这是一个使用Java Swing开发的个人所得税计算模拟器,模拟了官方个税APP的核心功能,包括: · 综合所得年度汇算计算 · 税率表查询 · 专项扣除项目设置 · 税务计算结果展示 项目特点: · 100%纯Java实现,无第三方依赖 · 完整GUI界面,支持用户交互 · 详细的代码注释 · 遵循2023年最新个税政策 二、核心代码实现 1. 主程序入口 ```java package com.tax.calculator; import javax.swing.*; /**  * 个人所得税计算模拟器 - 主程序  * @author TaxDeveloper  * @version

By Ne0inhk

JavaScript性能优化实战:流畅应用秘籍

一、性能优化的重要性 1. 用户体验的核心:流畅度与响应速度 2. 性能对业务指标的影响(转化率、留存率) 3. 现代 Web 应用的性能挑战 4. 本文目标:提供可落地的优化方案 二、性能瓶颈分析与度量 1. 关键性能指标 (Web Vitals) * LCP (Largest Contentful Paint):最大内容渲染时间 * FID (First Input Delay):首次输入延迟 * CLS (Cumulative Layout Shift):累积布局偏移 * 如何测量这些指标(Chrome DevTools, Lighthouse, Web Vitals API) 2. 浏览器开发者工具剖析 * Performance 面板:记录和分析运行时性能 * Network

By Ne0inhk
Elasticsearch核心概念与Java客户端实战 构建高性能搜索服务

Elasticsearch核心概念与Java客户端实战 构建高性能搜索服务

目录 🎯 先说说我被ES"虐惨"的经历 ✨ 摘要 1. 为什么选择Elasticsearch? 1.1 从数据库的痛苦说起 1.2 Elasticsearch的优势 2. ES核心架构解析 2.1 集群架构 2.2 索引与分片 3. Java客户端实战 3.1 客户端选型对比 3.2 RestHighLevelClient配置 3.3 Spring Data Elasticsearch配置 4. 索引设计最佳实践 4.1 索引生命周期管理 4.2 映射设计技巧 5. 查询优化实战 5.1 查询类型对比 5.

By Ne0inhk