JavaScript
JavaScript
第三章--类型、值、变量
3.10 变量声明与赋值
3.10.1 let,const
// let可以声明的同时赋值,也可以只声明,只声明的变量值为undefined let i,num; let b=10; //const声明常量时必须赋值,且规定全部大写 cosnt MESSAGE = 10
3.10.2 var
- 只有函数作用域和全局作用域,没有块作用域
if (true) { var test = true; // 使用 "var" 而不是 "let" } alert(test); // true,变量在 if 结束后仍存在
- let和const声明的全局变量和常量不是全局对象的属性,而var声明的是全局对象的属性,可以使用globalThis. 引用
3.10.3 解构赋值
let [x,y] = [1,2]; [x,y]=[y,x]; 可以使返回为数组的函数异常便捷
第四章--表达式与操作符
4.2 对象和数组初始化程序
4.3 函数定义表达式
4.4 属性访问表达式
语法
object.property object['property']
属性名称
属性名称必须是字符串或符号 Symbol。这意味着非字符串对象不能用来作为一个对象属性的键。任何非字符串对象,包括 Number,都会通过 toString 方法,被转换成一个字符串
var object = {}; object['1'] = 'value'; console.log(object[1]); // object[1]里的1是字符串'1' // 若方括号里的是对象,则都转换为字符串"[object Object]"
4.4.1 条件式属性访问
expression ?. identifier expression ?. [expression]
null,undefined是仅有的两个没有属性的值
当求a.b时,若a是null或undefined,则会报TypeError
使用?.则结果为undefiend
若 ?. 的左侧子表达式求值为null或undefined,则整个表达式立即求值为undefined
4.5 调用表达式
4.5.1条件式调用表达式
function square(x,log){ log?.(x); return x*x; }
第二个参数是一个可选的函数,有定义则可调用,但是 ?. 只会检测左侧是不是null或undefined,若square接收到两个数值,仍然会抛出错误
4.6 对象创建表达式
相比于调用表达式多了个new
new Object() new Object(2,3) new Object // 不给构造参数传参
4.7 操作符概述
4.8 算术表达式
4.8.1 +操作符
有字符串就转成字符串
4.8.2 一元算术操作符
4.8.3 位操作符
4.9 关系表达式
4.13 其他操作符
4.13.2 先定义 ??
含义相当于 (a!==null&&a!==undefined) ? a : b
4.13.3 typeof
返回操作数的对象
typeof x; typeof null // => object typeof undefined // => undefined
第五章-语句
5.3 条件语句
5.3.1 if语句
5.3.2 else if
5.3.3 switch
5.4 循环语句
5.4.4 for/of 循环
专门用于 可迭代对象,数组,字符串,迭代,映射
数组迭代是实时的,如果循环体中有改变数组,可能会影响迭代的输出
for/of 与对象
对象不可迭代,若想迭代对象的属性
- for/in循环
- Object.keys()
Object.keys()返回一个对象属性名的数组
let o = {x:1,y:2,z:3}; let sun=0; for( let i of Object.keys(o)){ sum+=i; }
Object.entries()返回一个数组的数组,每个内部数组标识对象的一个属性的键值对
let o = {x:1,y:2,z:3}; let sun=""; for( let [i,j] of Object.entries(o)){ sum+=i+j; }
for/of 与字符串
let str={}; for(let letter of "abcdef"){ if(str[letter]){ str[letter]++; }else{ str[letter]=2; } }
for/of 与Set和Map
Set,对Set中的每个元素都遍历一次
let str = "Na na na na sa"; let wordSet = new Set(str.split(" ")); let num = []; for (let letter of wordSet) { num.push(letter); } console.log(num) // [ 'Na', 'na', 'sa' ]
Map,对Map中每个键值对遍历一次
let map = new Map([[1, "one"]]) for (let [key, value] of map) { console.log(key); console.log(value) } // 1,one
for/await与异步迭代-12,13章
async function printStream(stream){ for await (let chunk of stream){ console.log(chunk) } }
5.4.5 for/in
与of不一样,in后面可以跟任意对象,操作数组一般用for/of,但是不会枚举对象的所有属性,不会枚举名字为符号的属性,对于名字为字符串的属性,只会便利可枚举的属性
5.5 跳转语句
5.5.1语句标签
// 给statement添加标签,程序的任何地方都可以通过这个名字引用 identifier: statement
5.5.2 break语句
// 可以直接跳出名为labelname的语句 break : labelname
5.5.3 continue语句
// 执行下一次循环 continue : labelname
5.5.4 return
5.5.5 yield
只能用在ES6的生成器函数中,以回送生成的值序列中的下一个值,同时又不会真正返回
function* range(from, to) { for (let i = from; i <= to; i++) { yield i; } } for (let num of range(1, 9)) { console.log(num); }
5.5.6 throw-try-catch-finally
只要执行了try语句,就会执行finally语句
5.5.7 "use strict"
在脚本或函数体的开头,位于所有其他真正的语句之前,表示之后的代码时严格代码
第六章--对象
6.2 创建对象
方法:
- 对象字面量
- new 关键字
- Object.create()
6.2.1对象字面量
let obj={}; let obj={ "main test":"1213", author:{ firstname:"12", surname:"34", }, } // author属于对象内的对象
6.2.2 new 关键字
// 构造函数 let obj=new Object(); let obj=new Array();
6.2.3 Object.create()
用于创建新对象,使用第一个参数作为新对象的原型
let obj =Object.create({x:1,y:2}); // 创建一个空对象 let obj=Object.create(Object.prototype)
6.3 查询和设置属性
6.3.2 继承
查询属性会用到继承链,而设置属性时不影响继承链
6.4 删除属性
delete只删除自有属性,不删除继承属性
6.5 测试属性
in
对象包含相应名字的自有属性或继承属性,则返回true
hasOwnProperty()
测试对象是否有给定名字的属性,即只有自有属性.对继承的属性返回false
propertyIsEnumerable()
传入的命名属性是自有属性且enumerable属性为true,才返回true
6.6 枚举属性
Object.keys()返回对象可枚举自有属性名的数组
6.7 扩展对象
Object.assign()
接收两个或多个,第一个为目标对象,后为来源对象,第一个来源对象的属性会覆盖目标对象同名属性,第二个来源对象会覆盖第一个来源对象的属性
let A = { a: 1 } let B = { a: 2, b: 3 } let C = { a: 3, b: 4, c: 5 } Object.assign(A, B, C) console.log(A) // A { a: 3, b: 4, c: 5 }
只复制不存在的属性
function merge(target, ...sources) { for (let source of sources) { for (let key of Object.keys(source)) { if (!(key in target)) { target[key] = source[key]; } } } return target; } console.log(merge({ x: 1 }, { x: 2, y: 3 })) // { x: 1, y: 3 }
6.8 序列化
JSON.stringify:将对象的状态转换为字符串
JOSN.parse:恢复为对象
6.10 对象字面量扩展语法
6.10.1 简写属性
let x=1,y=2; let p={ x:x, y:y, }; ES6: let p={x,y};
6.10.4 扩展操作符
可以在对象中使用扩展操作符 ... 把已有对象的属性复制到新对象中,这种方法仅在对象字面量中有效
只扩展自有操作符
let pos={x:1,y:2}; let rec={z:3}; let end={...pos, ...rec}; end.x+end.y+end.z=6
6.10.5 简写方法
let p={ area: function(){return 1;}, } ==> let p={ area() {return 1;}, }
第七章--数组
7.1创建数组
7.1.1 数组字面量
let a=[]; let b=[2,3,4]; let c=["a",true,22.2] let d=[1,,3] // 允许末尾出现逗号,所以e长度是2 let e=[,,]
7.1.2 扩展操作符
扩展操作符是创建数组(浅)副本的一种便捷方式,可以用于任何可迭代对象
let a=[1,2,3]; let b=[0, ...a,4] // b=[0,1,2,3,4]
7.1.3 Array()构造函数
let a = new Array();// 无参数 let a = new Array(10);// 指定长度为10 let a = new Array(1,2,3,"awdaw");
7.1.4 Array.of()
括号中是新的数组元素
7.1.5 Array.from()
第一个参数为可迭代对象或类数组对象,并返回包含该对象元素的新数组
let c = Array.from(a); let c = [...a];// 效果一样
也可以接受第二个参数,若第二个参数传入了一个函数,则新建数组时,所有元素都会传入函数,将函数的返回值作为新元素
7.4 数组长度
如果给一个索引为i的数组元素赋值,而i大于或等于数组当前的length,length会被设置为i+1
如果将length设置为一个小于当前值的非负整数n,则任何索引大于或等于n的数组元素都会被剔除
7.6 迭代数组
for/of, forEach()
let up = ""; let a = [..."hello"]; a.forEach(letter => { up += letter.toUpperCase(); }); console.log(up);
7.7 多维数组
7.8 数组方法
7.8.1 数组迭代器方法
接受三个函数,第一个为数组元素的值,第二个为数组元素的索引,第三个为数组
forEach()
let d = [1, 2, 3, 4, 5]; let sum = 0; d.forEach(value => { sum += value }); // console.log(sum) let a = [] d.forEach(function (v, i, a) { a[i] = v; console.log(a[i]) });
map()
把调用它的数组的每个元素分别传给我们指定的函数,返回这个函数的返回值构成构成的数组
传入的应该是返回值,且map返回的是新数组,不会改变原来的数组
let a = [1, 2, 3]; a.map(x => x * x); for (let i of a) { console.log(i) }
filter()
返回一个数组,该数组包含调用它的数组的子数组.传给这个方法的函数应该是一个断言函数,即返回true或false的函数,返回的数组始终是稠密的
find和findIndex
同filter()一样,里面的函数应该是一个断言函数,但是当查找到第一个符合条件的值后,就停止迭代,find()返回值,findIndex()返回索引,没找到,就返回undefined和-1
every()与some()
every(),只有在断言函数对数组的所有元素都返回true时才返回true
some(),只要有一个元素返回true,就返回true
reduce()与reduceRight()
reduce()使用指定的函数归并数组元素,最终产生一个值;reduceRight()从右至左
// reduce接收两个参数,第一个是函数,第二个是初始值 let a = [1, 2, 3, 4, 5]; a.reduce((x, y) => x + y, 0) for (let i of a) { console.log(i) } // 若没有第二个参数,默认为数组的第一个元素作为初始值 a.reduce((x,y) => (x > y) ? x : y)
7.8.2 使用flat()和flatMap()打平数组
flat()打平数组并返回一个新数组
let a = [1, 2, [3, 4]] // 打平1级,参数为打平多少级 let b = a.flat(1) console.log(b)
flatMap()与map类似,只是返回的数组会自动被打平,a.flatMap(f)效率高于a.map(f).flat()
7.8.3 concat()添加数组
concat()方法创建并返回新数组,新数组包含调用concat()方法的数组的元素,以及传给concat的参数.如果参数有数组,拼接的是数组的元素不是数组
7.8.4 push(),pop(),shift(),unshift()实现栈和队列操作
push()添加在数组的末尾 pop()弹出数组末尾的元素 shift()删除开头元素 unshift()末尾添加 unshift(1) //=>[1] unshift(2) //=>[2,1] unshift(1,2) //=>[1,2]
7.8.5 slice(),splice(),fill(),copyWithin()
slice(index1,index2) //返回切片,index1是起始的索引,index2是结束的索引,但不包含,若为-1,表示倒数第一个元素 //不会修改原数组
splice(index1,index2,...indexn) // 第一个参数为起始位置,第二个为长度 // 后续参数为要插入的元素 // 会修改原数组
fill(index1,index2,index3) // 第一个参数为要填充的值 // 第二个和第三个是起始位置和结束位置,不包括结束位置
copyWithin(target,start,end) // 将start起始的,end结束(不包括end)的元素插入到target位置,不改变数组的长度
7.8.7 数组到字符串的转换
join() let a=[1,2,3]; a.join() // "1,2,3" a.join(" ") // "1 2 3" a.join("") // "123"
7.9 类数组对象
类数组对象不会继承Array.prototype,所以无法在他们上面调用数组方法,可以使用Function.call()调用
Array.prototype.join.call() Array.prototype.map.call()
第八章--函数
8.1 定义函数
8.1.1 函数声明
可以声明在任何地方
function name(x){}
8.1.2 函数表达式
函数名对定义为表达式的函数而言是可选的,不能在定义前引用
const square=function(x){return x*x;}; const square=function(x) fact{return x*x;}; [1,2,3].sort(function(a,b){return a-b;});
8.1.3 箭头函数
是表达式而非语句,可以从定义自己的环境获取上下文(this)
// 基本形式 const sum=(x,y)=>{return x+y;}; // 若只有return语句 const sum= (x,y) => x+y; // 若只有一个参数 const sum = x => x*x; // 没有参数就要用空括号表示 const sum = () => 42; // 若返回对象,用{}括起来 const f = x => {return {value:x}}; const f = x => ({value:x})
8.1.4 嵌套函数
嵌套函数可以访问包含自己的函数(或更外层)的参数和变量
function f1(a,b){ function f2(x){return x*x;}; return f1(a)+f2(b); }
8.2 函数调用
8.2.2 方法调用
// 有一对象o和函数f // 给o定义一个名为m的方法 o.m=f; // o使用f o.m();
如果嵌套函数被当做方法来调用,this值就是调用它的方法,若被当做函数来调用,this值要么是全局对象(非严格模式),要么是undefined(严格模式)
let o = { m: function () { let self = this; console.log(this === o); f(); function f() { console.log(this === o); console.log(self === o); } } } o.m(); // true false true
为了解决这个问题,将f改为箭头函数
let o = { m: function () { let self = this; console.log(this === o); // 箭头函数可以获取上下文 const f = () => { console.log(this === o); console.log(self === o); } f(); } } o.m();
或者,调用嵌套函数的bind()方法,定义一个在指定对象上被隐式调用的新函数
const f = (function(){ this===o; // true }).bind(this);
8.3 函数实参和形参
8.3.1 可选形参与默认值
传入的实参可以少于形参的个数,可选形参应放到参数列表的最后,可选形参可以设置默认值
function f(a,b=[]) const f1=(width,height=width*2)=>({width,height})
8.3.2 剩余形参与可变长度实参列表
剩余形参能够编写在调用时传入比形参多任意数量的实参,剩余形参的值始终是数组
function maxx(first = -Infinity, ...rest) { let maxv = first; for (let n of rest) { if (n > maxv) { maxv = n; } } return maxv; } console.log(maxx(1, 2, 3, 100, -1))
Arguments对象
在ES6之前,使用Arguments类数组对象获取剩余形参
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具