JS 里我才知道的东西 [译]

论坛 期权论坛 期权     
前端速报   2019-7-20 10:23   2786   0
我告诉大家一个写作心得,文章是靠改的。我的文章通常要改六七次,看上去像一气呵成,其实花费很多精力。
—— 《木心专访》
译文原链:air.ghost.io/js-things-i…
导读:2017年底,本文作者 Nick 通读了 MDN 文档,发现了一些之前不知道的 JS 特性和 API,于是写了一篇简短的小文。作者说:“这份简短的清单,对你可能并没有用,却阐释了 JS 学习之路永无止境的道理”。
注:文章翻译时,有删改。
[h1]Label 语句[/h1]在 JS 里可以为 for 循环和代码块标记名称。在 for 循环内部,可以使用
  1. break
复制代码
  1. continue
复制代码
指向此标记名称;而在代码块中,只能使用
  1. break
复制代码
终结某个标记块的进一步执行。
  1. loop1: // 外层循环标记为 "loop1"
复制代码
  1. for (let i = 0; i < 3; i++) { // "loop1"
复制代码
  1.    loop2: // 内层循环标记为 "loop2"
复制代码
  1.    for (let j = 0; j < 3; j++) { // "loop2"
复制代码
  1.       if (i === 1) {
复制代码
  1.          continue loop1; // 在此终止上层 "loop1" 循环的此次迭代、进入下一次迭代
复制代码
  1.          // break loop1; // 结束上层 "loop1" 循环
复制代码
  1.       }
复制代码
  1.       console.log(`i = ${i}, j = ${j}`);
复制代码
  1.    }
复制代码
  1. }
复制代码
  1. [/code][code]/*
复制代码
  1. 输出:
复制代码
  1. [/code][code]i = 0, j = 0
复制代码
  1. i = 0, j = 1
复制代码
  1. i = 0, j = 2
复制代码
  1. i = 2, j = 0
复制代码
  1. i = 2, j = 1
复制代码
  1. i = 2, j = 2
复制代码
  1. */
复制代码
而标记了名称的代码块中只能使用
  1. break
复制代码
关键字:
  1. foo: {
复制代码
  1.   console.log('第一条 log');
复制代码
  1.   break foo;
复制代码
  1.   console.log('这条 log 不会被打印出来的');
复制代码
  1. }
复制代码
  1. console.log('第二条 log');
复制代码
  1. [/code][code]/*
复制代码
  1. 输出:
复制代码
  1. [/code][code]第一条 log
复制代码
  1. 第二条 log
复制代码
  1. */
复制代码
  1. [/code]
  2. [code]void 操作符
复制代码
作者在阅读 JS since 1996 的时候,知道了
  1. void
复制代码
操作符,受到所有浏览器的支持,MDN 的解释是:
  1. void
复制代码
操作符会计算后面给定的表达式,然后返回
  1. undefined
复制代码
这样我们就多了 IIFE 的另一种写法:
  1. [/code][list][*][*][*][*][*][*][*][*][*][/list][code]void function iife() {
复制代码
  1.     console.log('你好啊');
复制代码
  1. }();
复制代码
  1. [/code][code]// 跟下面是一样的
复制代码
  1. [/code][code](function iife() {
复制代码
  1.     console.log('你好~');
复制代码
  1. })()
复制代码
  1. [/code][code]void
复制代码
操作符不管后面表达式的计算结果如何,总是返回
  1. undefined
复制代码
  1. [/code][list][*][*][*][*][*][*][*][*][*][*][*][/list][code]const word = void function iife() {
复制代码
  1.   return 'hello';
复制代码
  1. }();
复制代码
  1. [/code][code]// word 的值是 `undefined`
复制代码
  1. [/code][code]const word = (function iife() {
复制代码
  1.   return 'hello';
复制代码
  1. })();
复制代码
  1. [/code][code]// 这里 word 的值是 `'hello'
复制代码
  1. void
复制代码
还可与
  1. async
复制代码
结合使用,可以使用它作为异步代码入口点。
  1. [/code][list][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][/list][code]void async function() {
复制代码
  1.     try {
复制代码
  1.         const response = await fetch('air.ghost.io');
复制代码
  1.         const text = await response.text();
复制代码
  1.         console.log(text);
复制代码
  1.     } catch(e) {
复制代码
  1.         console.error(e);
复制代码
  1.     }
复制代码
  1. }()
复制代码
  1. [/code][code]// 或者还是坚持原来的写法 :)
复制代码
  1. [/code][code](async () => {
复制代码
  1.     try {
复制代码
  1.         const response = await fetch('air.ghost.io');
复制代码
  1.         const text = await response.text();
复制代码
  1.         console.log(text);
复制代码
  1.     } catch(e) {
复制代码
  1.         console.error(e);
复制代码
  1.     }
复制代码
  1. })();
复制代码
  1. [/code][h1][b]逗号运算符[/b][/h1]来自于 MDN 的好解释:
  2. [quote]逗号运算符会计算每一个操作数的结果(从左到右),然后返回最后一个操作数的计算结果。
  3. [/quote][code]
复制代码
  1. function myFunc() {
复制代码
  1.   let x = 0;
复制代码
  1.   return (x += 1, x); // 等同于 return ++x;
复制代码
  1. }
复制代码
  1. console.log(myFunc()) // 1
复制代码
  1. [/code][code]y = false, true; // 这条语句的执行结果是 true
复制代码
  1. console.log(y); // y 的值是 false
复制代码
  1. [/code][code]z = (false, true); // 等号右侧表达式的值是 true
复制代码
  1. console.log(z); // z 的值是 true
复制代码
  1. [/code][code]/*
复制代码
  1. 输出:
复制代码
  1. [/code][code]1
复制代码
  1. false
复制代码
  1. true
复制代码
  1. */
复制代码
  1. [b]与条件/三目操作符结合使用[/b]
复制代码
逗号运算符表达式总是返回最后一个值,因此在条件运算符的判断中,我们可以在最后一个值之前添加任意数量的表达式。在下面的例子中,我们在返回布尔值之前,放了一个 console log 在前面。
  1. [/code][list][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][/list][code]const type = 'man';
复制代码
  1. [/code][code]const isMale = type === 'man' ? (
复制代码
  1.     console.log('嗨,先生们!'),
复制代码
  1.     true
复制代码
  1. ) : (
复制代码
  1.     console.log('嗨,女士们!'),
复制代码
  1.     false
复制代码
  1. );
复制代码
  1. [/code][code]console.log(`isMale 的值是 "${isMale}"`);
复制代码
  1. [/code][code]/*
复制代码
  1. 输出:
复制代码
  1. [/code][code]嗨,先生们!
复制代码
  1. isMale 的值是 "true"
复制代码
  1. */
复制代码
  1. [/code][/b]
  2. [b][code]Internationalization API
复制代码

国际化 API 现在已经得到很好的支持了,我最喜欢的特性之一就是格式化时间的
  1. DateTimeFormat
复制代码
了。
  1. [/code][list][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][/list][code]const date = new Date();
复制代码
  1. [/code][code]const options = {
复制代码
  1.   year: 'numeric',
复制代码
  1.   month: 'long',
复制代码
  1.   day: '2-digit',
复制代码
  1.   hour: '2-digit',
复制代码
  1.   minute: '2-digit',
复制代码
  1.   second: '2-digit',
复制代码
  1.   hour12: false
复制代码
  1. };
复制代码
  1. [/code][code]const formatter1 = new Intl.DateTimeFormat('zh-CN', { ...options, timeZone: 'Asia/Shanghai' });
复制代码
  1. console.log(formatter1.format(date));
复制代码
  1. [/code][code]const formatter2 = new Intl.DateTimeFormat('en-US', { ...options, timeZone: 'America/New_York' });
复制代码
  1. console.log(formatter2.format(date));
复制代码
  1. [/code][code]/*
复制代码
  1. 输出:
复制代码
  1. [/code][code]2019年7月04日 10:26:03
复制代码
  1. July 03, 2019, 22:26:03
复制代码
  1. */
复制代码
Array.prototype.reduceRight
这个方法相当于是
  1. Array.prototype.reverse()
复制代码
+
  1. Array.prototype.reduce()
复制代码
的集合体。从右向左 reduce 数组。
  1. const array = [[0, 1], [2, 3], [4, 5]]
复制代码
  1. const flattened = array.reduceRight(function(a, b) {
复制代码
  1.     return a.concat(b);
复制代码
  1. }, []);
复制代码
  1. [/code][code]// 扁平化后的 `array` (即 flattened)的值为 [4, 5, 2, 3, 0, 1]
复制代码
  1. [/code][h1][b]setTimeout() 的参数[/b][/h1][code]setTimeout
复制代码
方法用于定时执行一段函数,方法的第一个参数指定触发函数执行的时间间隔(单位:毫秒)。
在调用函数时,我们可能会预先为要执行的函数,先指定前几个参数,你可能会感觉要使用
  1. .bind(...)
复制代码
方法实现此功能。然而我们不需要这么做。
  1. setTimeout
复制代码
方法第二个、第二个……使用的参数会在调用函数时,作为参数,自动在函数上使用的。
  1. setTimeout(alert, 1000, '你好,世界!');
复制代码
  1. [/code][code]/*
复制代码
  1. 输出:(alert)
复制代码
  1. [/code][code]你好,世界!
复制代码
  1. */
复制代码
  1. [/code][code]function log(text, textTwo) {
复制代码
  1.     console.log(text, textTwo);
复制代码
  1. }
复制代码
  1. [/code][code]setTimeout(log, 1000, '你好,世界!', '还有火星!');
复制代码
  1. [/code][code]/*
复制代码
  1. 输出:
复制代码
  1. [/code][code]你好,世界!还有火星!
复制代码
  1. */
复制代码
  1. [/code][h1][b]HTMLElement.dataset[/b][/h1]这是查询 HTML 自定义属性 [code]data-*
复制代码
的时候用到一个很方便的 API。不过有一些命名限制,大家知道 HTML 属性是不区分大小写的,自定义属性的命名方式采用 dash-case 的形式,而在 JS 里查询时,则是使用对应的 camelCase 形式(忽略
  1. data-*
复制代码
前缀)。比如
  1. data-birth-planet
复制代码
在 JS 访问使用的是
  1. birthPlanet
复制代码
  1. [/code][list][*][/list][code]
复制代码
  1. [/code][code]现在用 JS 查询:
复制代码
  1. [/code][list][*][*][*][*][*][*][*][*][*][*][*][/list][code]let personEl = document.querySelector('#person');
复制代码
  1. [/code][code]console.log(personEl.dataset) // DOMStringMap {name: "john", birthPlanet: "earth"}
复制代码
  1. console.log(personEl.dataset.name) // john
复制代码
  1. console.log(personEl.dataset.birthPlanet) // earth
复制代码
  1. [/code][code]// 使用编程的方式添加自定义属性
复制代码
  1. personEl.dataset.foo = 'bar';
复制代码
  1. console.log(personEl.dataset.foo); // bar
复制代码
  1. // 删除自定义属性
复制代码
  1. delete personEl.dataset.foo
复制代码
译者:zhangbao90s
https://juejin.im/post/5d1d5a36e51d4576bc1a0e61
本文对你有帮助?请分享给更多人!
关注「前端速报」,提升前端技能!


点1个“在看”,少n个bug!
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:25
帖子:5
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP