5个也许你并不熟悉的Javascript特性
1. 作用域
只要写过JS的肯定知道作用域是什么,但是你知道一个{}
就能创造一个作用域吗?
const a = 1;
{
const a = 2;
console.log(a); // 2
}
console.log(a); // 1
这个特性看起来似乎没什么用处,但其实有一些特定场合还是很有用处的,比如在一个switch语句里面。比如我们有如下代码,根据a
的值打印不同的结果:
// 代码会报错result被重复定义
const a = 1;
switch (a) {
case 1:
const result = a * 2;
console.log(result);
break;
case 2:
const result = a / 2;
console.log(result);
break;
case 3:
const result = a + 2:
console.log(result);
break;
}
如果我们想要达到预期的效果,我们可以这么写:
const a = 1;
switch (a) {
case 1:
{
const result = a * 2;
console.log(result);
break;
}
case 2:
{
const result = a / 2;
console.log(result);
break;
}
case 3:
{
const result = a + 2:
console.log(result);
break;
}
}
2. in
关键字
写过JS的朋友或多或少接触过in
关键字,有一些场合我们可以用它来判断某个object是否有某个指定的属性。比如代码如下:
const person = {
name: 'Paul',
age: 36
};
if (person.name) {
console.log('此人有个名字');
}
if ('name' in person) {
console.log('此人有名字属性');
}
//此人有个名字
//此人有名字属性
代码原本的想法是只要我们有person.name
属性,就打印出那两条信息。但如果我们赋值person.name = ''
, 我们只能打印出"此人有名字属性",因为空字符串无法通过第一个if语句的判断。也许有人会说那我们可以使用person.name != null
来判断,那如果我们赋值person.name = null
或者person.name = undefined
的话呢?如果我们真想通过第一条if语句的判定条件,那就要穷举不少情况来进行判定。
第二条语句可以帮我们解决这个问题,不论name
属性的值到底是什么,只要有这个属性,这条if语句总是能通过判定。除非我们移除这条属性,比如delete person.name
。
3. 模板字面量函数 Template Literal Functions
考虑如下代码:
const name = 'Paul';
const age = 36;
console.log(`我叫${name},今年${age}岁。`);
// 我叫Paul,今年36岁
我们可以创建一个函数,做一点修改:
const name = 'Paul';
const age = 36;
const custom = (strings) => {
console.log(strings);
return "Hi"
}
console.log(custom`我叫${name},今年${age}岁。`);
// [ '我叫', ',今年', '岁。' ]
// Hi
所以我们可以通过这个方法去做一些事情,比如我们想要给所有的变量添加一点格式,比如name
和age
加粗。那我们可以这么做:
const bold = (strings, ...values) => {
return values.reduce((finalString, value, index) => {
return `${finalString}<strong>${value}</strong>${strings[index + 1]}`
}, strings[0]);
}
const name = 'Paul';
const age = 36;
console.log(bold`我叫${name},今年${age}岁。`);
// 我叫<strong>Paul</strong>,今年<strong>36</strong>岁。
4. generator function
只要接触过redux-saga
那你肯定知道generator是什么,就不多解释了。如果不了解的话可以先google一下。
不只是在redux-saga
里面我们可以用这个,有时候我们也可以用它来做一些别的事情,比如生成id:
function* idGenerator () {
let id = 1;
while (true) {
yield id;
id++;
}
}
const generator = idGenerator();
console.log(generator.next()); // 1
console.log(generator.next()); // 2
console.log(generator.next()); // 3
console.log(generator.next()); // 4
5. 动态加载模块 Dynamic Module Imports
有时候我们考虑到性能,并不想一开始的时候就加载所有的模块,我们希望只有在需要这个模块的时候才加载它。
if(true) {
import('./modules.js').then(({ default: printValue }) => printValue());
}
再进一步,比如我们想在某个事件触发的时候才加载这个模块并运行其中的函数:
document.addEventListner('click', () => {
import('./modules.js').then(({ default: printValue }) => printValue());
});
采用async/await
之后:
document.addEventListner('click', async () => {
const { default: printValue } = import('./modules.js');
printValue();
});