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

  1. 只有函数作用域和全局作用域,没有块作用域
if (true) {
var test = true; // 使用 "var" 而不是 "let"
}
alert(test); // true,变量在 if 结束后仍存在
  1. let和const声明的全局变量和常量不是全局对象的属性,而var声明的是全局对象的属性,可以使用globalThis. 引用

3.10.3 解构赋值

let [x,y] = [1,2];
[x,y]=[y,x];
可以使返回为数组的函数异常便捷

第四章--表达式与操作符

4.2 对象和数组初始化程序

4.3 函数定义表达式

4.4 属性访问表达式

属性访问器 - JavaScript | MDN

语法

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 与对象

对象不可迭代,若想迭代对象的属性

  1. for/in循环
  2. 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 创建对象

方法:

  1. 对象字面量
  2. new 关键字
  3. 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类数组对象获取剩余形参

posted @   K-L  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示