news 2026/4/23 17:27:04

JavaScript学习笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript学习笔记

JavaScript学习笔记

  • JS简介
  • 书写语法
    • 一、基础语法规则(必遵守)
    • 二、变量声明
  • 数据类型
  • 运算符
  • 循环控制语句
    • 一、条件语句
    • 二、循环语句
  • 数组操作
    • 1. 新增元素(末尾 / 开头 / 指定位置)
    • 2. 删除元素(末尾 / 开头 / 指定位置)
    • 3. 修改元素(直接赋值 / 批量修改)
    • 4. 查找元素(索引 / 值)
  • 函数
    • 一、函数的核心概念
    • 二、函数的声明方式
    • 三、函数参数处理
    • 四、函数的返回值
  • 对象操作
    • 一、对象的基础概念
    • 二、对象的创建方式
    • 三、对象属性的增删改查
    • 四、对象的遍历
  • 总结

JS简介

JavaScript(简称 JS)是一种轻量级、解释型或即时编译的编程语言,主要用于网页开发,实现动态交互效果。作为 Web 三大核心技术之一(HTML、CSS、JavaScript),它可直接嵌入 HTML 页面,由浏览器执行。

书写语法

一、基础语法规则(必遵守)

  1. 大小写敏感
    JS 严格区分大小写,let num = 1let Num = 1是两个不同变量。

  2. 语句结束符

  • 分号 ; 是语句结束符,建议显式添加(避免自动分号插入 ASI 的坑);
  • 换行也可作为语句分隔,但易出错(如 return 后换行)。
  1. 注释
  • 单行注释:// 注释内容
  • 多行注释:/* 多行注释 换行也可以 */
  1. 空白符
    空格、制表符、换行符等空白符会被忽略,合理使用可提升可读性

  2. 标识符命名规则
    标识符(变量 / 函数 / 对象属性名等)需遵守:

  • 首字符:字母(a-z/A-Z)、下划线_、美元符$;
  • 后续字符:可加数字;
  • 不能是 JS 关键字 / 保留字(如let、if、function、class等)。
letuserName="张三";// 小驼峰(变量/函数)let_age=20;// 下划线开头let$price=99;// 美元符开头// let 123num = 1; // 错误:数字开头// let if = 5; // 错误:关键字

二、变量声明

JS 有 3 种声明方式,ES6 + 新增let/const,替代老旧的var

声明方式作用域提升特性重复声明重新赋值
var函数级 / 全局变量提升(初始化 undefined)允许允许
let块级({})暂时性死区(无提升)禁止允许
const块级({})暂时性死区(无提升)禁止禁止
// var(不推荐)vara=1;vara=2;// 允许重复声明// let(推荐:可变变量)letb=10;b=20;// 允许重新赋值// let b = 30; // 错误:重复声明// const(推荐:不可变常量,声明时必须赋值)constPI=3.14159;// PI = 3.14; // 错误:禁止重新赋值constobj={name:"李四"};obj.name="王五";// 允许修改对象属性(const仅保证引用不变)

数据类型

  1. 基本类型(值类型)
  • 字符串(String):“abc”、‘123’、模板字符串 `(支持换行 / 插值);
  • 数字(Number):123、3.14、NaN、Infinity;
  • 布尔(Boolean):true、false;
  • 空(Null):null(表示空值);
  • 未定义(Undefined):undefined(声明未赋值)
  1. 引用类型
  • 对象(Object):{ key: value };
  • 数组(Array):[1, 2, 3];
  • 函数(Function):function() {};
  • 正则(RegExp):/^abc$/;
  • 日期(Date):new Date()。
// 字符串letstr1="hello";letstr2=`name:${userName}, age:${_age}`;// 插值// 数字letnum1=100;letnum2=0.1+0.2;// 0.30000000000000004(浮点精度问题)// 数组letarr=[1,"2",true,{a:1}];console.log(arr[0]);// 1// 对象letuser={name:"张三",age:20,sayHi:function(){// 对象方法console.log("Hi");}};user.sayHi();// 调用方法

运算符

  • 算术运算符:+、-、*、/、%(取模)。
  • 比较运算符:= =(宽松相等)、 = = =(严格相等)、>、<。
  • 逻辑运算符:&&(与)、||(或)、!(非)。
  • 三元运算符:条件 ? 表达式1 : 表达式2
5+"5";// "55"(字符串拼接)5==="5";// false(类型不同)true&&false// false
//三元算符letscore=85;letresult=score>=60?"及格":"不及格";console.log(result);// 及格

循环控制语句

一、条件语句

  1. if-else:
if(score>=90){console.log("优秀");}elseif(score>=70){console.log("良好");}else{console.log("加油");}
  1. switch:
letday=1;switch(day){case1:console.log("周一");break;// 必须break,否则穿透case2:console.log("周二");break;default:console.log("其他");}

二、循环语句

  1. for:
for(leti=0;i<5;i++){console.log(i);// 0-4}
  1. while:
letj=0;while(j<5){console.log(j);j++;}
  1. for…in(遍历对象属性 / 数组索引):
letobj={a:1,b:2};for(letkeyinobj){console.log(key,obj[key]);// a 1, b 2}
  1. for…of(遍历可迭代对象值,如数组 / 字符串):
letarr=[1,2,3];for(letvalofarr){console.log(val);// 1,2,3}

数组操作

1. 新增元素(末尾 / 开头 / 指定位置)

方法作用示例返回值
push()末尾添加 1 + 元素arr.push(4, 5)新数组长度
unshift()开头添加 1 + 元素arr.unshift(0)新数组长度
splice()指定位置插入元素arr.splice(2, 0, 'a')空数组(无删除)
letarr=[1,2,3];// 末尾新增arr.push(4);// arr → [1,2,3,4]// 开头新增arr.unshift(0);// arr → [0,1,2,3,4]// 索引2的位置插入'a'(参数:起始索引,删除数量,插入元素)arr.splice(2,0,'a');// arr → [0,1,'a',2,3,4]

2. 删除元素(末尾 / 开头 / 指定位置)

方法作用示例返回值
pop()删除末尾元素arr.pop()被删除的元素
shift()删除开头元素arr.shift()被删除的元素
splice()指定位置删除元素arr.splice(2, 1)被删除元素组成的数组
slice()截取部分元素(不修改原数组)arr.slice(1, 3)截取的新数组
letarr=[0,1,'a',2,3,4];// 删除末尾letlast=arr.pop();// last=4,arr → [0,1,'a',2,3]// 删除开头letfirst=arr.shift();// first=0,arr → [1,'a',2,3]// 删除索引2的1个元素letdel=arr.splice(2,1);// del=[2],arr → [1,'a',3]// 截取(索引1到3,左闭右开)letnewArr=arr.slice(1,3);// newArr=['a',3],原arr不变

3. 修改元素(直接赋值 / 批量修改)

  • 直接通过索引赋值:arr[索引] = 新值;
  • fill():批量填充 / 修改元素(修改原数组)。
letarr=[1,2,3];// 单个修改arr[1]='b';// arr → [1,'b',3]// 批量填充(参数:填充值,起始索引,结束索引)arr.fill(0,1,3);// arr → [1,0,0]

4. 查找元素(索引 / 值)

方法作用示例返回值
indexOf()查找值的第一个索引arr.indexOf(2)索引 /-1
lastIndexOf()查找值的最后一个索引arr.lastIndexOf(2)索引 /-1
find()查找满足条件的第一个元素arr.find(item => item > 3)元素 /undefined
findIndex()查找满足条件的第一个索引arr.findIndex(item => item > 3)索引 /-1
includes()判断是否包含某个值arr.includes(2)true/false
letarr=[1,2,3,2,4];// 查找值的索引console.log(arr.indexOf(2));// 1console.log(arr.lastIndexOf(2));// 3// 条件查找元素console.log(arr.find(item=>item>3));// 4// 条件查找索引console.log(arr.findIndex(item=>item>3));// 4// 判断是否包含console.log(arr.includes(5));// false

函数

一、函数的核心概念

函数本质是【可调用的对象】,具有以下特性:

  • 可接收参数、执行逻辑、返回值;
  • 可赋值给变量、作为参数传递、作为返回值(一等公民);
  • 有自己的作用域,隔离内部变量。

二、函数的声明方式

JS 有 4 种主流函数声明方式,适用场景不同:

声明方式语法示例提升特性适用场景
函数声明function add(a, b) { return a + b; }函数提升(可先调用后声明)全局 / 函数内通用函数
函数表达式const add = function(a, b) { return a + b; };无提升(先声明后调用)赋值给变量、作为回调
箭头函数(ES6)const add = (a, b) => a + b;无提升简洁回调、无 this 绑定场景
构造函数(极少用)const add = new Function('a', 'b', 'return a + b');无提升动态生成函数(性能差,不推荐)

示例:不同声明方式的调用

// 1. 函数声明(提升)console.log(sum(1,2));// 3(先调用后声明)functionsum(a,b){returna+b;}// 2. 函数表达式(无提升)// console.log(sub(5, 3)); // 报错:sub is not a functionconstsub=function(a,b){returna-b;};console.log(sub(5,3));// 2// 3. 箭头函数constmul=(a,b)=>a*b;// 单行返回可省略{}和returnconstdiv=(a,b)=>{// 多行需加{}和returnif(b===0)returnNaN;returna/b;};console.log(mul(2,4));// 8console.log(div(8,2));// 4

三、函数参数处理

JS 函数参数灵活,支持默认参数、剩余参数、解构参数、参数传递方式等特性:

  1. 默认参数(ES6)
    声明时指定参数默认值,调用时未传参则使用默认值:
functiongreet(name="访客",age=18){console.log(`你好,${name},年龄${age}`);}greet();// 你好,访客,年龄18greet("张三");// 你好,张三,年龄18greet("李四",20);// 你好,李四,年龄20
  1. 剩余参数(…rest,ES6)
    接收【多余的参数】为数组,替代 arguments(类数组),更灵活:
// 求和任意个数的参数functionsum(...nums){returnnums.reduce((total,num)=>total+num,0);}console.log(sum(1,2));// 3console.log(sum(1,2,3,4));// 10// 剩余参数需放在参数列表最后functionfn(a,b,...rest){console.log(a,b,rest);// 1 2 [3,4,5]}fn(1,2,3,4,5);
  1. 解构参数(ES6)
    直接解构对象 / 数组作为参数,简化参数提取:
// 解构对象参数functionprintUser({name,age,gender="男"}){console.log(`姓名:${name},年龄:${age},性别:${gender}`);}printUser({name:"张三",age:20});// 姓名:张三,年龄:20,性别:男// 解构数组参数functionprintArr([a,b,c]){console.log(a,b,c);// 1 2 3}printArr([1,2,3]);
  1. 参数传递方式
  • 基本类型(值传递):传递值的副本,函数内修改不影响外部;
  • 引用类型(引用传递):传递内存地址,函数内修改会影响外部;
// 基本类型letnum=10;functionchangeNum(n){n=20;}changeNum(num);console.log(num);// 10(无变化)// 引用类型letobj={name:"张三"};functionchangeObj(o){o.name="李四";}changeObj(obj);console.log(obj.name);// 李四(被修改)
  1. arguments 对象(类数组)
    非严格模式下,函数内可通过 arguments 获取所有传入的参数(类数组,无数组方法):
functionfn(){console.log(arguments[0]);// 1console.log(arguments.length);// 3// 转为数组:[...arguments] 或 Array.from(arguments)}fn(1,2,3);

注意:箭头函数无arguments对象,优先用剩余参数替代。

四、函数的返回值

  • 无 return 语句:默认返回 undefined;
  • return 后无值:返回 undefined;
  • return 可返回任意类型(基本类型、对象、函数);
functionfn1(){}console.log(fn1());// undefinedfunctionfn2(){return;// 等同于 return undefined}console.log(fn2());// undefined// 返回函数(高阶函数)functioncreateAdd(n){return(x)=>x+n;}constadd5=createAdd(5);console.log(add5(3));// 8

对象操作

一、对象的基础概念

  • 对象的「键」(属性名):字符串 / Symbol 类型(数字会自动转为字符串);
  • 对象的「值」(属性值):任意类型(基本类型、对象、函数);
  • 函数类型的属性称为「方法」。

二、对象的创建方式

创建方式语法示例适用场景
对象字面量(推荐)const obj = { name: "张三", age: 20 };简单对象,直接声明
构造函数const obj = new Object({ name: "张三" });动态创建(极少用)
object.create()const obj = Object.create(prototypeObj);基于原型创建对象
类(ES6)class User { constructor(name) { this.name = name; } } const obj = new User("张三");复杂对象 / 面向对象编程
// 1. 对象字面量(最常用)constuser={name:"张三",age:20,sayHi(){// 方法简写(替代 sayHi: function() {})console.log(`你好,我是${this.name}`);}};user.sayHi();// 你好,我是张三// 2. Object.create(指定原型)constproto={gender:"男"};constuser2=Object.create(proto);user2.name="李四";console.log(user2.gender);// 男(继承原型属性)// 3. 类创建(ES6)classUser{constructor(name,age){this.name=name;this.age=age;}// 类方法getInfo(){return`${this.name}${this.age}`;}}constuser3=newUser("王五",25);console.log(user3.getInfo());// 王五,25岁

三、对象属性的增删改查

  1. 访问属性(两种方式)
  • 点语法:obj.key(键为合法标识符,推荐);
  • 方括号语法:obj["key"](键含特殊字符 / 变量,必用)。
constobj={"user-name":"张三",// 含特殊字符的键age:20};// 点语法console.log(obj.age);// 20// 方括号语法(特殊字符键)console.log(obj["user-name"]);// 张三// 变量作为键constkey="age";console.log(obj[key]);// 20
  1. 添加 / 修改属性
  • 直接赋值:obj.key = value(存在则修改,不存在则添加);
  • Object.defineProperty ():精细配置属性(可枚举、可修改、可删除)。
constobj={name:"张三"};// 添加属性obj.age=20;obj["gender"]="男";console.log(obj);// { name: '张三', age: 20, gender: '男' }// 修改属性obj.name="李四";console.log(obj.name);// 李四// 精细配置属性(不可修改、不可枚举)Object.defineProperty(obj,"id",{value:1001,writable:false,// 不可修改enumerable:false,// 不可枚举(遍历不到)configurable:false// 不可删除/重新配置});obj.id=1002;// 无效果(严格模式报错)console.log(obj.id);// 1001
  1. 删除属性
  • delete obj.key:删除对象自身属性(原型属性无法删除);
  • 返回值:成功删除 / 属性不存在返回 true,不可配置属性返回 false(严格模式报错)。
constobj={name:"张三",age:20};deleteobj.age;console.log(obj);// { name: '张三' }// 不可配置属性无法删除Object.defineProperty(obj,"id",{value:1,configurable:false});console.log(deleteobj.id);// false
  1. 检查属性是否存在
方法作用示例
in 运算符检查自身 + 原型属性'age' in obj
hasOwnProperty()仅检查自身属性(推荐)obj.hasOwnProperty('age')
obj.key !== undefined检查属性值是否为 undefined(不严谨,属性值可能为 undefined)obj.age !== undefined
constproto={gender:"男"};constobj=Object.create(proto);obj.name="张三";console.log("name"inobj);// true(自身属性)console.log("gender"inobj);// true(原型属性)console.log(obj.hasOwnProperty("name"));// trueconsole.log(obj.hasOwnProperty("gender"));// false

四、对象的遍历

  1. for…in 循环(遍历可枚举属性,含原型)
constobj={name:"张三",age:20};// 遍历自身可枚举属性(过滤原型)for(letkeyinobj){if(obj.hasOwnProperty(key)){console.log(key,obj[key]);// name 张三, age 20}}
  1. Object.keys() / Object.values() / Object.entries()
  • Object.keys(obj):返回自身可枚举属性名数组;
  • Object.values(obj):返回自身可枚举属性值数组;
  • Object.entries(obj):返回自身可枚举属性的 [key, value] 数组(可解构遍历)。
constobj={name:"张三",age:20};// 遍历键console.log(Object.keys(obj));// ['name', 'age']// 遍历值console.log(Object.values(obj));// ['张三', 20]// 遍历键值对Object.entries(obj).forEach(([key,value])=>{console.log(key,value);// name 张三, age 20});
  1. Object.getOwnPropertyNames()
    返回自身所有属性名(含不可枚举,不含 Symbol):
constobj={};Object.defineProperty(obj,"id",{value:1,enumerable:false});console.log(Object.keys(obj));// [](不可枚举)console.log(Object.getOwnPropertyNames(obj));// ['id']
  1. Reflect.ownKeys()
    返回自身所有属性名(含不可枚举、Symbol):
consts=Symbol("id");constobj={[s]:1001,name:"张三"};Object.defineProperty(obj,"age",{value:20,enumerable:false});console.log(Reflect.ownKeys(obj));// [ 'name', 'age', Symbol(id) ]

总结

基于JS的HTML会有更加流畅、更加实用、更加美观等效果,注意区分JS与CSS和HTML的语法区别。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:17:13

省时90%:MinGW-w64极速配置方案对比

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个对比演示应用&#xff0c;左侧展示传统方式&#xff1a;手动下载、选择安装选项、配置环境变量等交互步骤&#xff1b;右侧展示自动化方案&#xff1a;输入安装MinGW-w64指…

作者头像 李华
网站建设 2026/4/23 12:53:25

70看看:1小时验证你的产品创意

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 输入到70看看&#xff1a;生成一个共享单车应用的MVP原型&#xff0c;包含用户注册登录、地图显示附近单车、扫码解锁和行程记录功能。使用React Native前端&#xff0c;Firebase后…

作者头像 李华
网站建设 2026/4/23 11:17:19

AI如何简化CANopen协议开发?5个自动化技巧

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个基于CANopen协议的智能代码生成工具&#xff0c;要求&#xff1a;1. 支持通过自然语言描述自动生成PDO/SDO映射配置代码 2. 能够解析标准EDS文件并生成可视化对象字典 3. 包…

作者头像 李华
网站建设 2026/4/23 14:07:08

嵌入式代码优化:实战技巧与性能提升

嵌入式代码优化实战技术文章大纲嵌入式代码优化概述嵌入式系统特点与优化需求优化目标&#xff1a;性能、功耗、内存占用常见优化场景&#xff1a;实时性要求、资源受限环境性能优化方法编译器优化选项与配置循环优化&#xff1a;展开、分块、向量化内联函数与减少函数调用开销…

作者头像 李华
网站建设 2026/4/23 12:28:22

如何轻松管理浏览器标签页:Tab-Session-Manager 完整使用指南

如何轻松管理浏览器标签页&#xff1a;Tab-Session-Manager 完整使用指南 【免费下载链接】Tab-Session-Manager WebExtensions for restoring and saving window / tab states 项目地址: https://gitcode.com/gh_mirrors/ta/Tab-Session-Manager 在当今信息爆炸的时代&…

作者头像 李华
网站建设 2026/4/23 12:46:46

5分钟验证Node.js创意:快马平台原型开发

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 快速生成一个Node.js社交媒体应用原型。核心功能包括&#xff1a;1) 用户注册/登录 2) 发帖功能 3) 点赞/评论 4) 简单的时间线。使用最简实现&#xff0c;不需要完整功能&#xff…

作者头像 李华