大家好,很高兴又见面了,我是"前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!
JavaScript 是一种使用原型链的语言。 早期像面向对象这样的概念都是通过原型链来做的,比较复杂,Class 终于在 ES6 中引入了。
class Animal {
constructor(name, color) {
this.name = name;
this.color = color;
}
// This is a property on the prototype chain
toString() {
console.log('name:' + this.name + ', color:' + this.color);
}
}
var animal = new Animal('myDog', 'yellow');
animal.toString();
console.log(animal.hasOwnProperty('name')); //true
console.log(animal.hasOwnProperty('toString')); // false
console.log(animal.__proto__.hasOwnProperty('toString')); // true
class Cat extends Animal {
constructor(action) {
super('cat', 'white');
this.action = action;
}
toString() {
console.log(super.toString());
}
}
var cat = new Cat('catch');
cat.toString();
console.log(cat instanceof Cat); // true
console.log(cat instanceof Animal); // true
每个模块都有自己的命名空间,避免冲突,使用 import 和 export 来导入导出,默认将 .js 文件视为模块。
() => {…}是函数的缩写,有了箭头函数再也不用写 var self = this, var that = this 等类代码。
const add = (a, b) => {
return a + b;
};
const res = add(1, 2); // 3
const minus = (a, b) => a - b;
const res1 = minus(5, 1); // 4
如果函数不传参数,则使用默认值,更简洁。
function example(height = 5, width = 6) {
const newH = height * 2;
const newW = width * 4;
return newH + newW;
}
example(); // 34 (5*2 + 6*4)
以前,长字符串的组合使用+号连接,可读性差,使用模板字符串更容易阅读。
const firstName = 'water';
const lastName = 'fish';
// not use template literal
const name = 'Hello, My name is' + firstName + ', ' + lastName;
// use template literal
const nameWithLiteralString = `Hello, My name is ${firstName}, ${lastName}`;
const arr = [1, 2, 3, 4, 5];
const [one, two, three] = arr;
console.log(one); // 1
console.log(two); // 2
...
// To skip certain values
const [first,,,,last] = arr;
console.log(first); // 1
console.log(last); // 5
// Objects can also be destructurized and assigned
const student = {
name: 'waterfish',
age: 28,
};
const {name, age, city} = student;
console.log(name); // "waterfish"
console.log(age); // "28"
const arr1 = ['A', 'B'];
const arr2 = ['0', ...arr1, '1', '2'];
conslog.log(arr2); // ["0", "A", "B", "1", "2"]
用三个点…表示,Array 可以扩展,而如果是 Object,则根据 key-value 进行扩展。
因为构成 newCustomer 对象属性的 name、age 的 key、value 相同,所以省略 value。
const name = 'waterfish',
age = 28;
// Before ES6, we must write like this
const customer = {
name: name,
age: age,
}; // // {name: 'waterfish', age: 28}
// After ES6, we can do it
const newCustomer = {
name,
age,
}; // // {name: 'waterfish', age: 28}
Promise 是一种解决异步(非同步)写法的方案,比原来的 callback 写法更优雅。使用 Promise 可以解决 hell callback。
const waitSecond = new Promise((resolve, reject) => {
setTimeout(resolve, 1000);
});
waitSecond
.then(() => {
console.log('hello after 1 second.');
// output this line after 1 second
return waitSecond;
})
.then(() => {
console.log('World after 2 sceond.');
// output this line after 2second
});
ES8(ES2017)发布了一个更完美的 async,await,直接让异步的写法看起来像同步的。
用于判断数组中是否包含指定值,如果包含则返回 true,否则,返回 false。因为返回布尔值,比 indexOf 的语义化更加清晰。
const arr = [1, 2, 3, 4, 5];
arr.include(3); // true
if (arr.include(3)) { ... }
// ... Equivalent to the previous writing of indexOf
arr.indexOf(3); // 2 (return its array position)
// If you want to write it in the if, you must add `> -1`, which is not as clear as the include in ES7 in terms of semantics
if (arr.indexOf(3) > -1) { ... }
console.log(2 ** 10); // 1024
// equal to
console.log(Math.pow(2, 10)); // 1024
异步函数是使用 async 关键字声明的函数,其中允许使用 await 关键字。 async 和 await 关键字使基于 Promise 的异步行为能够以更简洁的方式编写,避免显式配置 Promise 链的需要。
async test() {
try {
const result = await otherAsyncFunction();
console.log(result); // output result
} catch(e) {
console.log(e); // Can catch errors if otherAsyncFunction() throws an error
}
}
返回对象自身属性的所有值,不包括继承的值。
const exampleObj = { a: 1, b: 2, c: 3, d: 4 };
console.log(Object.value(exampleObj)); // [1, 2, 3, 4];
// To do the same thing before, use the following notation. much verbose
const values = Object.keys(exampleObj).map((key) => exampleObj[key]);
返回一个可枚举的键,value 中存储的是键的值。
const Obj = { a: 1, b: 2, c: 3, d: 4 };
console.log(Object.entries(Obj)); // [["a", 1], ["b", 2], ["c", 3], ["d", 4]];
// Usually used with for
for (const [key, value] of Object.entries(Obj)) {
console.log(`key: ${key}, value: ${value}`);
}
// key: a, value: 1
// key: b, value: 2
// key: c, value: 3
// key: d, value: 4
您可以在字符串的开头或结尾添加额外的内容,并将其填充到指定的长度。过去,这些功能通常是通过 lodash 等通用帮助工具包引入 的。
String.padStart(fillingLength, FillingContent);
// If the content to be filled is too much and exceeds the "fill length",
// it will be filled from the leftmost to the upper limit of the length,
// and the excess will be truncated
最常用的情况应该是金额,填指定长度,不足补 0。
// padStart
'100'.padStart(5, 0); // 00100
// If the content to be padded exceeds the "padding length". Then fill in from the left to the upper limit of the length
'100'.padStart(5, '987'); // 98100
// padEnd
'100'.padEnd(5, 9); // 10099
// If the content to be padded exceeds the "padding length". Then fill in from the right to the upper limit of the length
'100'.padEnd(5, '987'); // 10098
ECMAScript 2017 支持函数参数中的尾随逗号。
function f(p) {}
function f(p) {}
(p) => {};
(p) => {};
获取您自己的描述符,一般开发业务需求通常不会使用这些描述符。
const exampleObj = { a: 1, b: 2, c: 3, d: 4 };
Object.getOwnPropertyDescriptors(exampleObj);
// {a: {…}, b: {…}, c: {…}, d: {…}}
// a: {value: 1, writable: true, enumerable: true, configurable: true}
// b: {value: 2, writable: true, enumerable: true, configurable: true}
// c: {value: 3, writable: true, enumerable: true, configurable: true}
// d: {value: 4, writable: true, enumerable: true, configurable: true}
// __proto__: Object
SharedArrayBuffer 是原始二进制数据的固定长度缓冲区,类似于 ArrayBuffer。可用于在共享内存上创建数据,与 ArrayBuffer 不同,SharedArrayBuffer 不能分离。
Atomics 对象提供一组静态方法来对 SharedArrayBuffer 执行原子操作。如果一个多线程同时在同一个位置读写数据,原子操作保证了正在操作的数据符合预期:即在上一个子操作结束后执行下一个,操作不中断。
可以说是针对 Node.Js 中多线程 Server 的开发而加强的功能,在前端开发中使用的机会相当低,目前 Chrome 已经支持。
在异步函数中,有时需要在同步 for 循环中使用异步(非同步)函数。for 循环本身还是同步的,整个 for 循环会在循环中的异步函数执行完之前执行完,然后里面的异步函数会一个一个执行。ES9 加入了异步迭代器,允许 await 配合使用 for 循环逐步执行异步操作。
async function process(array) {
for await (const i of array) {
doSomething(i);
}
}
无论是成功(.then())还是失败(.catch()),都会在 Promise 之后执行的代码。
function process() {
process1()
.then(process2)
.then(process3)
.catch((err) => {
console.log(err);
})
.finally(() => {
console.log(`it must execut no matter success or fail`);
});
}
const myObject = {
a: 1,
b: 2,
c: 3,
};
const { a, ...r } = myObject;
// a = 1
// r = { b: 2, c: 3 }
// Can also be used in function input parameters
function restObjectInParam({ a, ...r }) {
console.log(a); // 1
console.log(r); // {b: 2, c: 3}
}
restObjectInParam({
a: 1,
b: 2,
c: 3,
});
const arr1 = [1, 2, [3, 4]];
arr1.flat(); // [1, 2, 3, 4]
const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat(); // [1, 2, 3, 4, [5, 6]]
// Pass in a number in flat, representing the flattening depth
arr2.flat(2); // [1, 2, 3, 4, 5, 6]
下面是 flatMap 方法:
let arr = ['water', '', 'fish'];
arr.map((s) => s.split(''));
// [["w", "a", "t", "e", "r"], [""], ["f", "i", "s", "h"]
arr.flatMap((s) => s.split(''));
// ["w", "a","t","e","r", "", "f", "i", "s", "h"]
trimStart() 方法从字符串的开头删除空格,trimLeft() 是该方法的别名。
const greeting = ' Hello world! ';
console.log(greeting);
// expected output: " Hello world! ";
console.log(greeting.trimStart());
// expected output: "Hello world! ";
trimEnd() 方法删除字符串末尾的空格,trimRight() 是该方法的别名。
const greeting = ' Hello world! ';
console.log(greeting);
// expected output: " Hello world! ";
console.log(greeting.trimEnd());
// expected output: " Hello world!";
将键值对列表转换为对象。
const entries = new Map([
['foo', 'bar'],
['baz', 42],
]);
const obj = Object.fromEntries(entries);
console.log(obj);
// expected output: Object { foo: "bar", baz: 42 }
matchAll() 方法返回一个迭代器,遍历将字符串与正则表达式匹配的所有结果,包括捕获组。
const regexp = /t(e)(st(d?))/g;
const str = 'test1test2';
const array = [...str.matchAll(regexp)];
console.log(array[0]);
// expected output: Array ["test1", "e", "st1", "1"]
console.log(array[1]);
// expected output: Array ["test2", "e", "st2", "2"]
const theBiggestInt = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);
// ↪ 9007199254740991n
const hugeString = BigInt('9007199254740991');
// ↪ 9007199254740991n
const hugeHex = BigInt('0x1fffffffffffff');
// ↪ 9007199254740991n
const hugeBin = BigInt(
'0b11111111111111111111111111111111111111111111111111111'
);
// ↪ 9007199254740991n
Promise.allSettled() 方法返回一个 Promise,当所有给定的 Promise 都已完成或被拒绝时,该 Promise 就会完成,其中每个对象都描述每个 Promise 的结果。
当您有多个不依赖于彼此成功完成的异步任务时,或者当您总是想知道每个 Promise 的结果时通常会使用它。
相反,如果任务相互依赖、或者您希望其中任何一个 Promise 失败后则立即拒绝,则由 Promise.all() 返回的 Promise 可能更合适。
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) =>
setTimeout(reject, 100, 'foo')
);
const promises = [promise1, promise2];
Promise.allSettled(promises).then((results) =>
results.forEach((result) => console.log(result.status))
);
// expected output:
// "fulfilled"
// "rejected"
const username = user?.name || 'guest';
在 JavaScript 中,0、null 或 undefined 会自动转为 false,但有时候希望将返回值设置为 0。
const username = user.level ?? 'no level';
// output 0. if level is not available, it becomes 'no level'.
el.onclick = () => {
import(`/js/logger.js`)
.then((module) => {
module.doSomthing();
})
.catch((err) => {
handleError(err);
});
};
全局 globalThis 属性包含全局 this 值,类似于全局对象。
function canMakeHTTPRequest() {
return typeof globalThis.XMLHttpRequest === 'function';
}
console.log(canMakeHTTPRequest());
// expected output (in a browser): true
Promise.any() 接受一个可迭代的 Promise 对象,每当可迭代对象中的任何一个 Promise fullfill 时它都返回一个 Promise,其中包含已 fullfill 的 Promise 的值。如果所有的 Promise reject 则返回 AggregateError 对象,其是 ERROR 对象的一个子类,默认搜集所有 Error 并分组。
const p1 = new Promise((resolve) => {
setTimeout(() => {
resolve('p1 resolved value');
}, 1000);
});
const p2 = new Promise((resolve) => {
setTimeout(() => {
resolve('p2 resolved value');
}, 500);
});
const p3 = new Promise((resolve) => {
setTimeout(() => {
resolve('p3 resolved value');
}, 1800);
});
Promise.any([p1, p2, p3]).then((value) => {
console.log(value);
}); // p2 resolved value
在开发过程中,可以使用在 ES2020 引入的逻辑运算符 ||、&& 和 ?? (Nullish coalescing operator)来解决一些问题。而 ES2021 会提出 ||= , &&= , ??= ,概念类似于 += :
let b = 2;
b += 1;
// equal to b = b + 1
let a = null;
a ||= 'some random text'; // a become to'some random text'
// equal a = a || 'some random text'
let c = 'some random texts';
c &&= null; // c become to null
// equal to c = c && null
let d = null;
d ??= false; // d become to false
// equal to d = d ?? false
WeakRef 对象持有对对象的弱引用,称为其目标或引用对象。对对象的弱引用是不会阻止对象被垃圾收集器回收的引用。
普通(或强)引用将对象保存在内存中,当一个对象不再具有任何强引用时,JavaScript 引擎的垃圾收集器可能会销毁该对象并回收其内存,如果发生这种情况,您将无法再从弱引用中获取对象。
期待不一样的东西
原文链接:https://medium.com/@
waterfish/from-es6-to-es13-f72d4840986a文字封面图片:https://app.daily.dev/posts/5k4Dlnc3E
页面更新:2024-03-13
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号