[译] 一些ES6的小技巧

[译] 一些ES6的小技巧

大家好,又见面了,我是全栈君。

原文: Check out these useful ECMAScript 2015 (ES6) tips and tricks

有任何错误请在评论指出,感激不尽。

EcmaScript 2015 (ES6) 已经出现了很多年了,我们可以使用它的一些新特性。

1.设置必须的函数参数

ES6 提供了 默认的参数值,可以让你在函数的参数中指定默认值当参数没有传递其值的时候。

const required = () => {
   
   throw new Error('Missing parameter')};
//The below function will trow an error if either "a" or "b" is missing.
const add = (a = required(), b = required()) => a + b;
add(1, 2) //3
add(1) // Error: Missing parameter.
复制代码

在这个例子中,我们对函数 add 的参数 ab 设置了一个默认值,这个默认值为一个函数。当函数 add 被执行时,且参数 ab 有一个没有传递值的时候,这个 required 函数就会执行,我们就会得到一个报错 Error: Missing parameter.

2.非常强力的”reduce”

Array 的方法 reduce 是一个有非常多用处的函数。 它一个非常具有代表性的作用是将一个数组转换成一个值。但是你可以用它来做更多的事。

? Tip: 这些小技巧的的初始值都是一个数组或者一个对象而不是一个像字符串之类的简单的值

2.1 使用reduce做到同时有map和filter的作用

假设有这样的一个场景,你有一个list,里面有一些item, 你需要更新这些item, 更新完以后你需要使用filter来过滤掉你不需要的item。但是这样的话你需要遍历这个数组两次!

const numbers = [10, 20, 30, 40];
const doubledOver50 = numbers.reduce((finalList, num) => {
  
  num = num * 2; //double each number (i.e. map)
  
  //filter number > 50
  if (num > 50) {
    finalList.push(num);
  }
  return finalList;
}, []);
doubledOver50; // [60, 80]
复制代码

在这个例子里面,我们想要让数组里面的值翻倍,然后我们只想要里面大于 50 的元素。注意一下我们是如何使用 reduce 方法做到同时有让元素的值翻倍,然后过滤的。

2.2 使用”reduce”代替”map”和”filter”

在原文中没有体现这部分代码,只说了注意2.1的代码。在这里我添加一下这部分代码:

2.2.1 使用”reduce”代替”map”
function map(arr, exec) {
    var res = arr.reduce((res, item, index) => {
        var newItem = exec(item, index)
        res.push(newItem)
        return res
    }, [])
    return res
}

[1, 2, 3].map((item) => item * 2) // [2, 4, 6]

map([1, 2, 3], item => item * 2) // [2, 4, 6]
复制代码
2.2.2 使用”reduce”代替”filter”
function filter(arr, exec) {
    var res = arr.reduce((res, item, index) => {
        if (exec(item, index)) {
            res.push(item)
        }
        return res
    }, [])
    return res
}

[1, 2, 3].filter((item, index) => index < 2) // [1, 2]
filter([1, 2, 3], (item, index) => index < 2) // [1, 2]
复制代码

2.3 使用”redece”来判断括号是否匹配

这也是个例子来说明 reduce 这个函数功能的强大。给你一串字符串,你想要知道这串字符串的括号是否是匹配的。

常规的做法是使用栈来匹配,但是这里我们使用 reduce 就可以做到,我们只需要一个变量 counter ,这个变量的初始值是 0 , 当遇到 ( 的时候,counter ++ 当遇到 ) 的时候, counter -- 。 如果括号是匹配的,那么这个 counter 最终的值是0

//Returns 0 if balanced.
const isParensBalanced = (str) => {
  return str.split('').reduce((counter, char) => {
    if(counter < 0) { //matched ")" before "("
      return counter;
    } else if(char === '(') {
      return ++counter;
    } else if(char === ')') {
      return --counter;
    }  else { //matched some other char
      return counter;
    }
    
  }, 0); //<-- starting value of the counter
}
isParensBalanced('(())') // 0 <-- balanced
isParensBalanced('(asdfds)') //0 <-- balanced
isParensBalanced('(()') // 1 <-- not balanced
isParensBalanced(')(') // -1 <-- not balanced
复制代码

2.4 计算数组中元素出现的次数(将数组转为对象)

如果你想计算数组中元素出现的次数或者想把数组转为对象,那么你可以使用 reduce 来做到。

var cars = ['BMW','Benz', 'Benz', 'Tesla', 'BMW', 'Toyota'];
var carsObj = cars.reduce(function (obj, name) { 
   obj[name] = obj[name] ? ++obj[name] : 1;
  return obj;
}, {});
carsObj; // => { BMW: 2, Benz: 2, Tesla: 1, Toyota: 1 }
复制代码

作者建议前往MDN学习,查看更多例子MDN

// 我也去看了一眼MDN,发现reduce真是个黑科技,promise串行这个应用非常秒啊。

3.对象解构

3.1 移除不想要的属性

有时候你想要移除对象中的一些不需要的属性,这个对象可能是包含了某些敏感的信息或者只是因为这个对象太大了。我们可以使用解构来代替去遍历这些属性。

let {_internal, tooBig, ...cleanObject} = {
   
   el1: '1', _internal:"secret", tooBig:{}, el2: '2', el3: '3'};
console.log(cleanObject); // {el1: '1', el2: '2', el3: '3'}
复制代码

在这个例子中,我们想要移除 _internaltooBig 这两个属性,我们可以将他们分配给变量 _internaltooBig 中,剩下的属性存放在 cleanObject 中,这就是我们想要的。

3.2 在函数参数中使用嵌套对象解构

var car = {
  model: 'bmw 2018',
  engine: {
    v6: true,
    turbo: true,
    vin: 12345
  }
}
const modelAndVIN = ({model, engine: {vin}}) => {
  console.log(`model: ${model} vin: ${vin}`);
}
modelAndVIN(car); // => model: bmw 2018 vin: 12345
复制代码

在这个例子中 engine 是一个嵌套在 car 里面的对象,如果我们只需要 engine 里面的属性 vin 我们可以这样做。

3.3 合并对象

ES6 新增了一个扩展运算符,... 使用三个点来表示,它经常用来解构数组的值, 但是它也可以用在对象中。

在这个例子中,我们在一个新的对象中使用扩展运算符,后面一个对象的属性值会把前面一个对象的属性值覆盖。

第二个对象中的属性 bc 的值把第一个对象中属性 bc 的值覆盖掉了

let object1 = { a:1, b:2,c:3 }
let object2 = { b:30, c:40, d:50}
let merged = {…object1, …object2} //spread and re-add into merged
console.log(merged) // {a:1, b:30, c:40, d:50}
复制代码

4.Sets

4.1 使用set来对数组去重

在ES6可以很方便的使用Set来对数组去重,因为Set表示的是一个集合,一个元素会在集合里面出现过一次。

let arr = [1, 1, 2, 2, 3, 3];
let deduped = [...new Set(arr)] // [1, 2, 3]
复制代码
4.2 使用Array的方法

可以通过(…)扩展运算符将 Set 转换成 Array 这样我们就可以在 Set 使用所有 Array 的方法了。

这个例子展示了如何在 Set 中使用 filter 方法

let mySet = new Set([1,2, 3, 4, 5]);
var filtered = [...mySet].filter((x) => x > 3) // [4, 5]
复制代码

5.数组的解构

5.1 交换2个值

let param1 = 1;
let param2 = 2;
//swap and assign param1 & param2 each others values
[param1, param2] = [param2, param1];
console.log(param1) // 2
console.log(param2) // 1
复制代码

5.2 函数返回多个值

async function getFullPost(){
  return await Promise.all([
    fetch('/post'),
    fetch('/comments')
  ]);
}
// const [post, comments] = getFullPost();
const [post, comments] = await getFullPost();
// 注释掉的那一行是作者写的,但是我跑不通,我觉得getFullPost是个Promise,所以需要加await。
复制代码

我们使用 async\await 来获取2个接口的数据 /post/comments , 函数返回的是一个数组,所以可以使用解构来获得这两个接口的返回值。

作者原文章的内容就到这里,但是我想补充一下map。

6. Map

在对象中的 key 只能是 string 没办法接受一个 Object 当作 key 会被自动转换成字符串,例子如下:

const data = {};
const element = document.getElementById('myDiv');

data[element] = 'metadata';
data['[object HTMLDivElement]'] // "metadata"
复制代码

所以对于键值对的数据解构,mapObject 更加合适。

6.1 在map中使用对象当作key

const M = new Map()
let o = {
   
   p: 'Hello World'}
M.set(o, 'hello world')
M.get(o) // hello world
let O = {
   
   p: 'Hello World'}
M.get(O) // undefined
复制代码

注意: O != o 所以这个 M.get(O)undefined

6.2 WeakMap的作用

在普通的map中,如果一个 object 被当作 key 引用了,当除了map以外,其他的变量都丢掉对这个 object 的引用,那map还是会阻止垃圾回收机制去回收这个 object 这就会导致内存泄漏。所以就有了WeakMap。

字面意思,WeakMap里面的key是弱引用,并且 WeakMap中只能以 Object 当作 key 因为其他的你都可以用 Map搞啊~~那么 WeakMap的几个小技巧。

6.2.1 使用DOM节点作为键名
let myElement = document.getElementById('logo');
let myWeakmap = new WeakMap();

myWeakmap.set(myElement, {
   
   timesClicked: 0});

myElement.addEventListener('click', function() {
  let logoData = myWeakmap.get(myElement);
  logoData.timesClicked++;
}, false);
复制代码

以上例子来自 Ruanyifeng

我们用WeakMap来存DOM节点的某些状态,当这个DOM节点被删除时,myElement失去了引用,全世界都失去了引用,WeakMap里面所存的状态就会消失,所以不会存在内存泄漏的问题。

6.2.2 使用WeakMap来部署私有属性

我们都知道,在JS中实现实例的私有属性是比较困难的,有个办法是使用闭包,但是闭包有个问题,实例被强引用,不能被垃圾回收机制处理。如下代码:

var Person = (function() {
    var privateData = {},
        privateId = 0;
    function Person(name) {
        Object.defineProperty(this, "_id", { value: privateId++ });
        privateData[this._id] = {
            name: name
        };
    }
    Person.prototype.getName = function() {
        return privateData[this._id].name;
    };
    return Person;
}());
复制代码

privateData对每个实例都是强引用,所以垃圾回收机制是处理不了的。

我们可以用weakMap很好的解决这个问题。

var privateData = new WeakMap();
var Person = (function() {
    function Person(name) {
        privateData.set(this, { name: name });
    }
    Person.prototype.getName = function() {
        return privateData.get(this).name;
    };
    return Person;
}());
复制代码

以上代码weakMap不会对实例造成强引用,也就是说,垃圾回收机制是可能把这个实例回收掉的,如果没有其他人对这个实例保持着引用,是会被回收的,也就不会导致内存泄露了。

以上例子来自JavaScript实现私有属性

转载于:https://juejin.im/post/5ac23113f265da23906c2fbc

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107603.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Pytorch-BN层详细解读

    Pytorch-BN层详细解读Pytorch-BN层BN解决了InternalCovariateShift问题机器学习领域有个很重要的假设:独立同分布假设,即假设训练数据和测试数据是满足相同分布的。我们知道:神经网络的训练实际上就是在拟合训练数据的分布。如果不满足独立同分布假设,那么训练得到的模型的泛化能力肯定不好。再来思考一个问题:为什么传统的神经网络要求将数据归一化(训练阶段将训练数据归一化并记录均值和方差,测试…

    2022年10月14日
    2
  • 大数据采集技术概述

    大数据采集技术概述大数据采集是指从传感器和智能设备、企业在线系统、企业离线系统、社交网络和互联网平台等获取数据的过程。数据包括RFID数据、传感器数据、用户行为数据、社交网络交互数据及移动互联网数据等各种类型的结构化、半结构化及非结构化的海量数据。不但数据源的种类多,数据的类型繁杂,数据量大,并且产生的速度快,传统的数据采集方法完全无法胜任。所以,大数据采集技术面临着许多技术挑战,一方面需要保证数据…

    2022年6月24日
    27
  • webots自学笔记(一)软件界面和简单模型仿真

    webots自学笔记(一)软件界面和简单模型仿真由于毕设研究需要使用webots软件,在学习使用webots的过程花费了很多时间。由于这个软件基本没有什么中文资料,所以想把自己所学到的一些东西写下来,如有什么错误的地方,大家可以批评指正。1.界面

    2022年8月3日
    5
  • css图片居中(水平居中和垂直居中)

    css图片居中(水平居中和垂直居中)css 图片居中 水平居中和垂直居中 css 图片居中分 css 图片水平居中和垂直居中两种情况 有时候还需要图片同时水平垂直居中 下面分几种居中情况分别介绍 css 图片水平居中利用 margin 0auto 实现图片水平居中利用 margin 0auto 实现图片居中就是在图片上加上 css 样式 margin 0auto 如下 divstyle text align center width 500px border greensolid1p divstyle text align center width 500px border greensolid1p

    2025年6月23日
    4
  • 可以下载离线地图的软件_bt软件下载器

    可以下载离线地图的软件_bt软件下载器百度网盘:https://pan.baidu.com/s/1Nj6NcU1F2Y1f0kP9KgUlxg提取码:bxgh打开百度网盘并解压以后,你得到的东西是这些:第一先点击:MapTileDownloader_Ultimate_1.9.5.ext然后剩下几步都是默认安装就行;注意最后一步:先不要勾选接下来打开你安装的文件(从解压的文件里面把…

    2022年9月20日
    2
  • Idea激活码最新教程2020.3.1版本,永久有效激活码,亲测可用,记得收藏

    Idea激活码最新教程2020.3.1版本,永久有效激活码,亲测可用,记得收藏Idea 激活码教程永久有效 2020 3 1 激活码教程 Windows 版永久激活 持续更新 Idea 激活码 2020 3 1 成功激活

    2025年5月22日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号