js 笔记

116 阅读4分钟

数组

获取数组最后一个元素:

const a = [1,3,5,7,9];
console.log(a.at(-1)); // 9(倒数第一个值)
console.log(a.at(-2)); // 7(倒数第二个值)
console.log(a.at(0)); // 1(第一个值)

通过解构操作交换值

let a = 1; 
let b = 2; 
[a, b] = [b, a]
a; // 2;
b; // 1;

解构数组、字符串

let [x, y] = [1, 2]; // 相当于 let x = 1, y = 2;
let [first, ...rest] = "Hello"; // first == "H"; rest == ["e", "l", "l", "o"];

操作运算符

?? 空置合并运算符: 左边的值为 undefined 或者 null 时才会返回右边的值。

console.log(undefined ?? 5); // 5;
console.log(null ?? 3); // 3;
console.log('' ?? 7); // '';
console.log(0 ?? 10); // 0;

|| 运算符: 左边的值为假值时返回右边的值 (0, '', undefined, null, false 等都为假值)。

console.log('' || 'hello wolrd'); // 'hello wolrd';
console.log(0 || 9); // 9;

?. 可选链运算符: 允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 运算符的功能类似于 . 链式运算符,不同之处在于,在引用为空(null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。

const data = {
    x: {
        xVal: 10;
    }
}

console.log(data?.y); // undefined;
console.log(data?.y?.yVal); // undefined;
console.log(data?.x); // {xVal: 10};
console.log(data?.x?.xVal); // 10;
let a = {
    x: 10, 
    y: () => {
        console.log(20);
    }
};

a?.y(); // 20;
a.y?.(); // 20;

??= 空值赋值运算符: 当??=左侧的值为null、undefined的时候,才会将右侧的值赋值给左侧变量。其他所有值都不会进行赋值。

let a = null;
let b = 10;
a ??= 90;
b ??= 12;
console.log(a); // 90;
console.log(b); // 10;

+ 操作符

1 + 2; // 3;
"hello" + " " + "there"; // "hello there";
"1" + "2"; // "12";
"1" + 2; // "12";
"2" * "5"; // 10;
3 * "5"; // 15;
true + true; // 2;
2 + null; // 2;
2 + undefined; // NaN;
1 + 2 + " blind mice"; // "3 blind mice";
1 + (2 + " blind mice"); // "12 blind mice";

&& 与操作符: 逻辑与的特性是有假即假,全真为真,具有短路效果,如果&& 左边的表达式为false,就返回false,不会再判断&&右边的表达式了。

const a = true && false; // false;
const b = {} && 5; // 5;
const c = 0 && 3; // 0;
const d = undefined && true; // undefined;

delete 操作符

let a = {x: 10, y: 20, z: 30};
let b = { ...a };
delete b.x;
console.log(a); // { x: 10, y: 20, z: 30 };
console.log(b); // { y: 20, z: 30 };

let c = [10, 20, 30];
delete c[1];
console.log(c); // [10, undefined, 30];

eval( )

如果参数是表达式,则 eval() 计算表达式。如果参数是一个或多个 JavaScript 语句,则 eval() 执行这些语句。

变量名用作方法名

const f1 = (x)=>console.log(x); // 20;
const methodName = 'f1';

eval(methodName + '(20)')

动态变量

const a = 1;
const name = 'a';

console.log(eval(name)) // 1;

void 操作符

let counter = 0;
const increment = () => void counter++;
increment(); // undefined;
counter; // 1;

new Function("return " + d)( )

这种方式能将字符串解析成json对象(new Function("","return "+json))( );

const a = new Function("return " + '[{ id: 10, name: "lucy" }]')();

console.log(a); // [{ id: 10, name: "lucy" }];

pako.js 压缩

pako.gzip( encodeURIComponent(JSON.stringify(d)), { to: "string" } )

zip(str){
    const binaryString = pako.gzip(str, { to: 'string' });
    return btoa(binaryString);
},

btoa( ) 与 atob( )

btoa( ) 方法用于解码使用 base-64 编码的字符串;
atob( ) 方法用于创建一个 base-64 编码的字符串。

JS 设置对象默认属性

const f = (opts = { }) => {
    const newOpts = Object.assign({x: 10, y: 20}, opts);
    console.log(newOpts);
}

f({y: 25, z: 30}); // { x: 10, y: 25, z: 30 };
const f = (opts = { }) => {
    const defaultOpts = {x: 10, y: 20};
    const newOpts = {...defaultOpts, ...opts};
    console.log(newOpts);
}

f({y: 25, z: 30}); // { x: 10, y: 25, z: 30 };

获取数组、对象的键和值

使用 Object.keys() 方法获取 javascript 对象的键

const fruitsArr1 = ["Apple", "Orange", "Mango", "Banana"];
const fruitsObj2 = { 0: "Apple", 4: "Orange", 2: "Mango", 3: "Banana"};
const fruitsObj3 = { "id": "1", "name": "mango", "color": "yellow"};

console.log(Object.keys(fruitsArr1)); // ['0', '1', '2', '3'];
console.log(Object.keys(fruitsObj2)); // ['0', '2', '3', '4'];
console.log(Object.keys(fruitsObj3)); // ['id', 'name', 'color'];

使用Object.values快速获取对象键值

let obj = {
    a: 1,
    b: 2
};
let values = Object.values(obj)

console.log(values); // [1, 2];

Object.entries(obj) 将整个对象拆分为小数组。每个数组由 [key, value] 形式的键值对组成。

const fruitsArr1 = ["Apple", "Orange", "Mango", "Banana"];
const fruitsObj2 = { 0: "Apple", 4: "Orange", 2: "Mango", 3: "Banana"};
const fruitsObj3 = { "id": "1", "name": "mango", "color": "yellow"};

console.log(Object.entries(fruitsArr1)); // [["0", "Apple"], ["1", "Orange"], ["2", "Mango"], ["3", "Banana"]]
console.log(Object.entries(fruitsObj2)); // [["0", "Apple"], ["2", "Mango"], ["3", "Banana"], ["4", "Orange"]]
console.log(Object.entries(fruitsObj3)); // [["id", "1"], ["name", "mango"], ["color", "yellow"]]

for 循环【常用】

const obj = { "id": "1", "name": "mango", "color": "green"};
for(let i in obj) {
    console.log(i); // 'id', 'name', 'color';
    console.log(obj[i]); // '1', 'mango', 'green';
}

判断对象是否具有属性

in Operator

const a = [1,2,3];
console.log(0 in a); // true;

const a = {x: 1, y: 2, z: 3};
console.log('x' in a); // true;

Object.hasOwn( )方法

const a = [1,2,3];
console.log(Object.hasOwn(a, 0)); // true;

const a = {x: 1, y: 2, z: 3};
console.log(Object.hasOwn(a, 'x')); // true;

hasOwnProperty( ) 方法

const a = {x: 1, y: 2, z: 3};
console.log(a.hasOwnProperty('x')); // true;

const a = [1, 2, 3];
console.log(a.hasOwnProperty(0)); // true;

Reflect.has( )方法

const a = [1,2,3];
console.log(Reflect.has(a, 0)); // true;

const a = {x: 1, y: 2, z: 3};
console.log(Reflect.has(a, 'x')); // true;

JS 执行机制

一道JS题,让我更深刻的理解了JS的执行机制

let i = 0; 
function x() { 
    i++; return 10; 
};
i += x(); 
console.log(i); // 10
let i = 0; 
function x() { 
    i++; return 10; 
};
i = x() + i; 
console.log(i); // 11