专栏名称: yongli92
Financial Software Developer
目录
相关文章推荐
重庆城市圈  ·  明星夫妻,正式宣告离婚! ·  昨天  
OSC开源社区  ·  宇树王兴兴早年创业分享引围观 ·  4 天前  
OSC开源社区  ·  2024: 大模型背景下知识图谱的理性回归 ·  4 天前  
程序员小灰  ·  DeepSeek做AI代写,彻底爆了! ·  5 天前  
舜网  ·  演员鹿晗关晓彤,热搜第一! ·  3 天前  
舜网  ·  演员鹿晗关晓彤,热搜第一! ·  3 天前  
51好读  ›  专栏  ›  yongli92

我未曾见过的 JS 特性

yongli92  · 掘金  ·  · 2018-02-01 02:39

正文

我未曾见过的 JS 特性

有一天我正在阅读 MDN 文档,发现了一些我之前压根没有意识到在 JS 中存在的特性和 API。这里我罗列了一些,不管它们是否有用,JS 的学习永无止境。

标记语句

有多少人知道在 JS 里你可以给 for 循环和语句块命名?反正我不知道…… 命名完新名称之后你可以在 for 循环中的 break continue 之后、语句块中的 break 之后使用新名称。

loop1: // 标记 "loop1" 
for (let i = 0; i < 3; i++) { // "loop1"
   loop2: // 标记 "loop2"
   for (let j = 0; j < 3; j++) { // "loop2"
      if (i === 1) {
         continue loop1; // 继续外层的 "loop1" 循环
         // break loop1; // 中止外层的 "loop1" 循环
      }
      console.log(`i = ${i}, j = ${j}`);
   }
}

/* 
 * # 输出
 * i = 0, j = 0
 * i = 0, j = 1
 * i = 0, j = 2
 * i = 2, j = 0
 * i = 2, j = 1
 * i = 2, j = 2
 */

下面是语句块命名的例子,在语句块中你只能在 break 之后使用新命名。

foo: {
  console.log('one');
  break foo;
  console.log('这句打印不会被执行');
}
console.log('two');

/*
 * # 输出
 * one
 * two
 */

"void" 运算符

我一度以为我已经了解了所有的运算符,直到我看到了这一个。它从 1996 年 起就存在于 JS 了。所有的浏览器都支持,并且它也很容易理解,引用自 MDN:

void 运算符对给定的表达式进行求值,然后返回 undefined。

使用它,你可以换一种方式来写立即调用的函数表达式(IIFE),就像这样:

void function iife() {
	console.log('hello');
}();

// 和下面等效

(function iife() {
    console.log('hello');
})()

使用 void 的一个注意点是,无论给定的表达式返回结果是什么,void 运算符的整体结果都是空的(undefined)!

const word = void function iife() {
	return 'hello';
}();

// word 是 `undefined`

const word = (function iife() {
	return 'hello';
})();

// word 是 "hello"

你也可以和 async 一起使用 void ,这样你就能把函数作为异步代码的入口:

void async function() { 
    try {
        const response = await fetch('air.ghost.io'); 
        const text = await response.text();
        console.log(text);
    } catch(e) {
        console.error(e);
    }
}()

// 或者保持下面的写法

(async () => {
    try {
        const response = await fetch('air.ghost.io'); 
        const text = await response.text();
        console.log(text);
    } catch(e) {
        console.error(e);
    }
})();

逗号运算符

在学习了逗号运算符之后,我意识到了之前我并不完全清楚其工作原理。下面是来自 MDN 的引用:

逗号运算符对它的每个操作数求值(从左到右),并返回最后一个操作数的值。

function myFunc() {
  let x = 0;
  return (x += 1, x); // 等价于 return ++x;
}

y = false, true; // console 中得到 true
console.log(y); // false,逗号优先级低于赋值

z = (false, true); // console 中得到 true
console.log(z); // true,括号中整体返回 true

配合 条件运算符

逗号运算符中的最后一个值作为返回给条件运算符的值,因此你可以在最后一个值前面放任意多个表达式。在下面的例子中,我在返回的布尔值之前放了打印语句。

const type = 'man';

const isMale = type === 'man' ? (
    console.log('Hi Man!'),
    true
) : (
    console.log('Hi Lady!'),
    false
);

console.log(`isMale is "${isMale}"`);

国际化 API

即使在最有利的情况下,国际化还是很难做好。幸好还有一套大部分浏览器都支持得不错的 API 。其中我最爱的一个特性就是日期格式化,见下面的例子:

const date = new Date();

const options = {
  year: 'numeric', 
  month: 'long', 
  day: 'numeric'
};

const formatter1 = new Intl.DateTimeFormat('es-es', options);
console.log(formatter1.format(date)); // 22 de diciembre de 2017

const formatter2 = new Intl.DateTimeFormat('en-us', options);
console.log(formatter2.format(date)); // December 22, 2017

管道操作符

在此篇成文之时,该功能只有 Firefox 58 及以上版本通过传入启动参数来支持,不过 Babel 已经有一个针对它的 插件提议 。它看起来应该是受到 bash 的启发,我觉得很棒!

const square = (n) => n * n;
const increment = (n) => n + 1;

// 不使用管道操作符
square(increment(square(2))); // 25

// 使用管道操作符
2 |> square |> increment |> square; // 25

值得一提

Atomics

当数据被多个线程共享时,原子操作确保正在读和写的数据是符合预期的,即下一个原子操作一定会在上一个原子操作结束之后才会开始。这有利于保持不同线程间的数据同步(比如主线程和另一条 WebWorker 线程)。

我很喜欢如 Java 等其它语言中的原子性。我预感当越来越多的人使用 WebWorkers,将操作从主线程分离出来时,原子操作的使用会越来越广泛。

Array.prototype.reduceRight

好吧,我之前从未见过这个,因为它基本等同于 Array.prototype.reduce() + Array.prototype.reverse() 并且你很少需要这么做。但如果你有这需求的话, reduceRight 是最好的选择!

const flattened = [[0, 1], [2, 3], [4, 5]].reduceRight(function(a, b) {
    return a.concat(b);
}, []);

// flattened array is [4, 5, 2, 3, 0, 1]

setTimeout() 参数

这个早就存在了,但如果我早点知道的话,我大概可以省去很多的 .bind(...)

setTimeout(alert, 1000, 'Hello world!');

/*
 * # alert 输出
 * Hello World!
 */

function log(text, textTwo) {
    console.log(text, textTwo);
}

setTimeout(log, 1000, 'Hello World!'






请到「今天看啥」查看全文