Block scopes and the var/let/const keywords
- Always use the
const
keyword to define variables - Only use the
let
keyword when you absolutely need it - Never use the
var
keyword
Arrow functions and closures
const doSomething = () => {
// Function Scope
};
箭头函数可以访问它们的定义环境,而常规函数可以访问它们的调用环境。可以通过 this 访问
this.whoIsThis = 'TOP'; // Identify this scope
// 1) Defining
const fancyObj {
whoIsThis: 'FANCY', // Identify this object
regularF: function () {
console.log('regularF', this.whoIsThis);
},
arrowF: () => {
console.log('arrowF', this.whoIsThis);
},
};
// 2) Calling
console.log('TOP-LEVEL', this.whoIsThis); // It's "TOP" here
fancyObj.regularF(); // Output #1 (Fancy)
fancyObj.arrowF(); // Output #2 (Top)
fancyObj.regularF.call({whoIsThis: 'FAKE'}); // Output #3 (Fake)
fancyObj.arrowF.call({whoIsThis: 'FAKE'}); // Output #4 (Top)
有些情况下可以进行缩写
const square = (a) => {
return a * a;
};
const square = (a) => a * a;
const square = a => a * a;
The literal notations
const arr = [item0, item1, item2, ...];
const greeting = "Hello World";
const html = `
<div>
${Math.random()}
</div>
`;
${}
语法会执行内部语句
Destructuring arrays and objects
// 1) Destructure array items
const [first, second,, fourth] = [10, 20, 30, 40];
// 2) Destructure object properties
const { PI, E, SQRT2 } = Math;
可以从数组或对象中提取出来值
const circle = {
label: 'circleX',
radius: 2,
};
const circleArea = ({ radius }, [precision = 2]) =>
(Math.PI * radius * radius).toFixed(precision);
// 从 circle 中提取出来 radius,从数组中提取出来 precision
console.log(
circleArea(circle, [5]) // 12.56637
);
The rest/spread syntax
const [first, ...restOfItems] = [10, 20, 30, 40];
使用三个逗点提取出之后的元素
const array2 = [newItem0, ...array1, newItem1, newItem2];
const object2 = {
...object1,
newP1: 1,
newP2: 2,
};
浅拷贝数组或者对象
Shorthand and dynamic properties
const mystery = 'answer';
const InverseOfPI = 1 / Math.PI;
const obj = {
p1: 10, // Plain old object property (don't abbreviate)
f1() {}, // Define a shorthand function property
InverseOfPI, // Define a shorthand regular property
f2: () => {}, // Define an arrow function property
[mystery]: 42, // Define a dynamic property
};
对于 mystery,JavaScript 将首先计算[]中的表达式,无论该表达式计算得到什么结果,都将成为对象的新属性。
当需要使用属性名来定义一个对象,以保存当前作用域中具有完全相同名称的值时,可以只写一个。
Promises and async/await
promise是一个对象,它可能在程序中的稍后时间交付数据,或者它可能崩溃并交付错误。
const fetchData = () => {
fetch('https://api.github.com').then(resp => {
resp.json().then(data => {
console.log(data);
});
});
};
fetch 方法返回一个 promise 对象,然后使用 .then 提供一个回调函数。
可以进行简化。只需等待异步调用,它将直接返回响应对象。然后,您可以在 json() 方法上等待来访问已解析的 json 数据。
const fetchData = async () => {
const resp = await fetch('https://api.github.com');
const data = await resp.json();
console.log(data);
};
Modules import/export
如果 X.js 需要 Y.js 里面的一个函数
// Y.js
export const functionY() {
}
如果 X.js 和 Y.js 在一个文件夹下
// X.js
import { functionY } from './Y';
// functionY();
Map, filter, and reduce
在很多情况下这三个方法可以省去 for/while 循环的使用。
[4, 2, 0].map(e => e * e);
// Result: [16, 4, 0]
map 方法使用其回调函数的返回值来构造一个新数组。 每个回调函数调用的返回值成为新构造(映射)数组中的新值。
[4, 7, 2, 5, 0, 11].filter(e => e%2 === 0)
// Result: [4, 2, 0]
filter 方法使用其回调函数的返回值来确定当前项是否应保留在新构造(筛选)数组中。如果回调函数返回true,则该项保留。
[16, 4, 0].reduce((acc, curr) => acc + curr, 0);
// Result: 20
reduce方法使用稍微不同的回调函数。这个函数接收两个参数,而不是一个。除了常规的current item元素(在所有示例中都命名为e)之外,这个元素还接收一个累加器值(在示例中命名为acc)。acc的初始值是reduce的第二个参数(本例中为0)
Conditional expressions
在 JSX 中使用三元表达式
<div>
{condition ? valueX : valueY}
</div>
Timeouts and intervals
超时和间隔是浏览器 API 的一部分。它们并不是 JavaScript 语言本身的一部分,但是它们与诸如 setTimeout 和 setInterval 这样的 JavaScript 函数一起使用。
setTimeout 将在其延迟值之后一次调用其回调函数,而 setInterval 将在每次调用之间使用其延迟值重复调用其回调函数。
setTimeout(() => {
console.log('Hello Timeout!');
}, 3000);
setInterval(() => {
console.log('Hello Interval!');
}, 3000);
setInterval 调用通常有一个“退出”条件。setTimeout 和 setInterval 都返回它们创建的计时器对象的“ id”,并且可以使用该 id 值停止它们。您可以使用 clearTimeout(id)调用来停止一个超时对象,使用 clearInterval(id)来停止一个 interval 对象。
let count = 0;
const intervalId = setInterval(() => {
count = count + 1
console.log('Hello Interval!');
if (count === 3) {
clearInterval(intervalId);
}
}, 3000);
网友评论