前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES6相关

ES6相关

作者头像
4O4
发布2022-04-25 17:05:43
1.5K0
发布2022-04-25 17:05:43
举报
文章被收录于专栏:404404

ES6相关

ECMA介绍

...

let、const

...

解构赋值

...

字符串以及字符串模板

...

函数默认参数、箭头函数、剩余参数

...

数组循环

...

数组新增方法

...

对象简洁语法及新增对象

...

Promise

...

模块化

...

类和继承

...

Symbol和generator

...

async、await

...

Set和WeakSet数据结构

1. Set
代码语言:javascript
复制
// set 数据结构(类数组,无数值下标)
let setArr = new Set ()

// 添加值
setArr.add('a')
setArr.add('b')
setArr.add('c')

// 以上可以写成
let setArr = new Set ().add('a').add('b').add('c')

console.log(setArr)

// 删除值
setArr.delete('b')
console.log(setArr)

// 判断该值是否存在
console.log(setArr.has('a'))    // true
console.log(setArr.has('b'))    // false

// 输出元素个数
console.log(setArr.size)        // 2

// 清空元素
setArr.clear()

// 循环遍历数据
for(let item of setArr){
	console.log(item)
}  // a , c  默认遍历values

// 循环遍历数据
for(let item of setArr.values()){
	console.log(item)
}  // a , c

// 循环遍历下标
for(let item of setArr.keys()){
	console.log(item)
}  // a , c

// 循环遍历
for(let item of setArr.entries()){
	console.log(item)
}  // ["a", "a"] , ["c", "c"]

// 循环遍历
setArr.forEach((value,index) => {
   console.log(value,index)
})  // a a , c c

// 存放数组
let set = new Set()
let json = {
  a: 1,
  b: 2,
  c: 3
}
let json2 = {
  a: 1,
  b: 2,
  c: 3
}
set.add(json).add(json2)
set.forEach((item) => console.log(item))  // {a: 1, b: 2, c: 3} , {a: 1, b: 2, c: 3}

用途:

代码语言:javascript
复制
// 数组去重
let arr = [1, 2, 3, 4, 6, 7, 9, 8, 5, 4, 6, 7, 8, 4, 5, 6, 2]
let newArr = [...new Set(arr)]
console.log(newArr)      // [1, 2, 3, 4, 6, 7, 9, 8, 5]
代码语言:javascript
复制
// 映射新数组
let set = new Set([1, 2, 3, 4, 5])
set = new Set([...set].map(val => val * 2))
console.log(set)     // Set(5) {2, 4, 6, 8, 10}   
代码语言:javascript
复制
// 过滤
let set = new Set([1, 2, 3, 4, 5])
set = new Set([...set].filter(val => val % 2 == 0))
console.log(set)     // Set(2) {2, 4}
2. WeakSet
代码语言:javascript
复制
// 存放数组
let wSet = new WeakSet()
let json = {
  a: 1,
  b: 2,
  c: 3
}
let json2 = {
  a: 1,
  b: 2,
  c: 3
}
set.add(json).add(json2)
console.log(wSet)  // WeakSet {{…}, {…}}

总结:

  • Set ( [ ] ) 存放数组
  • WeakSet ( { } ) 存放json
  • WeakSet 没有size
  • 避免初始化时赋值,应使用add添加值

Map和WeakMap数据结构

1.Map
代码语言:javascript
复制
// 新建Map
let map = new Map ()
let json = {
  name: 'zephyr',
  age: 22
}

// 设置值
map.set('a',"aaa")
map.set(json,"aaa")
map.set('aaa',json)

// 输出值
console.log(map)   // Map(3) {"a" => "aaa", {…} => "aaa", "aaa" => {…}}

// 删除值
map.delete('aaa')
// 获取值
console.log(map.get('aaa'))    // undefined

// 判断值
console.log(map.has('aaa'))    // false

// 清空Map
map.clear()
console.log(map)    // Map(0) {}

// for...of循环Map
for(let [k,v] of map){
  console.log(k,v)
}       // a aaa , {name: "zephyr", age: 22} "aaa" , aaa {name: "zephyr", age: 22}

// forEach循环Map
map.forEach((k,v) => console.log(k,v))   //aaa a , aaa {name: "zephyr", age: 22} , {name: "zephyr", age: 22} "aaa"
2.WeakMap

WeakMap 的 key 只能是 Object 类型。 原始数据类型是不能作为 key 的(比如 Symbol)。

代码语言:javascript
复制
var wm1 = new WeakMap(),
    wm2 = new WeakMap(),
    wm3 = new WeakMap();
var o1 = {},
    o2 = function(){},
    o3 = window;

wm1.set(o1, 37);
wm1.set(o2, "azerty");
wm2.set(o1, o2); // value可以是任意值,包括一个对象
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // 键和值可以是任意对象,甚至另外一个WeakMap对象
wm1.get(o2); // "azerty"
wm2.get(o2); // undefined,wm2中没有o2这个键
wm2.get(o3); // undefined,值就是undefined

wm1.has(o2); // true
wm2.has(o2); // false
wm2.has(o3); // true (即使值是undefined)

wm3.set(o1, 37);
wm3.get(o1); // 37
wm3.clear();
wm3.get(o1); // undefined,wm3已被清空
wm1.has(o1);   // true
wm1.delete(o1);
wm1.has(o1);   // false

总结:

Set 里面是数组,没有重复值,没有key,没有get方法;

Map对json功能增强,key可以是任意类型值。

数值的变化

代码语言:javascript
复制
// 二进制 (binary)
let a = 0b010101
console.log(a)   // 21

// 八进制 (octal)
let b = 0o666
console.log(b)   // 438

// 判断NaN
Number.isNaN(NaN) --> true

// 判断Number
Number.isFinite(1.5) --> true
Number.isFinite(true) --> false

// 判断整数
Number.isInteger(1) --> true
Number.isInteger(1.5) --> false
1.安全整数:

js安全整数: [ -(2^53-1),(2^53-1)] ,此范围外计算将丢失精度。

代码语言:javascript
复制
let a = 2 ** 53
console.log(Number.isSafeInteger(a))         // false
console.log(Number.isSafeInteger(a - 1))     // true

let a = 2 ** 53 - 1
console.log(a)                               // 9007199254740991
console.log(Number.MAX_SAFE_INTEGER)         // 9007199254740991
2.Math新增方法

Math.abs(),Math.sqrt(),Math.sin()...

代码语言:javascript
复制
// 截取,只保留整数部分
Math.trunc(1.1)    // 1
Math.trunc(1.9)    // 1

// 判断正负
Math.sign(1)         // 1
Math.sign(1.5)       // 1
Math.sign(-1)        // -1
Math.sign(-1.5)      // -1
Math.sign(0)         // 0
Math.sign(-0)        // -0
Math.sign('aaa')     // NaN

// 计算立方根
Math.cbrt(27)        // 3

ES2018 (ES9) 新增

1.命名捕获
代码语言:javascript
复制
// 语法 (?<name>)
let str = '2019-03-30'
let reg = /(\d{4})-(\d{2})-(\d{2})/
console.log(str.match(reg))   // ["2019-03-30", "2019", "03", "30", index: 0, input: "2019-03-30", groups: undefined]

// 使用命名捕获
let str = '2019-03-30'
let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
let dateArr = str.match(reg).groups
console.log(dateArr)     // { year: "2019", month: "03", day: "30" }

let { year, month, day} = str.match(reg).groups
console.log(year, month, day)    // 2019 03 30
2.反向引用命名捕获
代码语言:javascript
复制
// 普通反向引用
\1  \2  $1  $2

// 反向引用命名捕获语法 (\<name>)
let reg = /^(?<zephyr>welcome)-\k<zephyr>$/
let str = 'a-a'
let str2 = 'zephyr-zephyr'
let str3 = 'welcome-welcome'
console.table(reg.test(str),reg.test(str3),reg.test(str3))    // false true true

Proxy代理的使用

1.定义

Proxy是设计模式之一(代理模式),常用于扩展(增强)对象的一些功能。

例如VUE中的:Vue.config.keyCodes.enter = 65;

2.用途
  • 增强对象
  • 拦截
  • 预警
  • 上报
  • 扩展功能
  • 统计

...

代码语言:javascript
复制
new Proxy (target, handler)  // 被代理的对象,对代理对象进行的操作

// 实例
let obj = {
  name: 'zephyr'
}

console.log(obj.name)
let newObj = new Proxy(obj, {
  get(targrt, property) {
    // console.log(targrt, property)
    console.log(`你访问了${property}属性!`)
    return targrt[property]
  }
})

newObj.name   // zephyr , 你访问了name属性!
3.案例

实现访问一个对象身上的属性,默认不存在时是undefined,现在要求修不存在时抛出错误(警告)信息。

代码语言:javascript
复制
let obj = {
  name: 'zephyr'
}

console.log(obj.name)
let newObj = new Proxy(obj, {
  get(targrt, property) {
    return targrt[property]
  }
})

console.log(newObj.name)   // zephyr
console.log(newObj.age)    // undefined

// 自定义捕获错误并显示提示消息
let obj = {
  name: 'zephyr'
}
console.log(obj.name)

let newObj = new Proxy(obj, {
  get(targrt, property) {
    if (property in targrt) {
      return targrt[property]
    } else {
      throw new ReferenceError(`${property}属性不在此对象上!`)
    }
  }
})

newObj.name    // zephyr
newObj.age     // Uncaught ReferenceError: age属性不在此对象上!

Reflect的使用

...

技巧

1.如何隐藏所有指定的元素
代码语言:javascript
复制
const hide2 = (el) => Array.from(el).forEach(e => (e.style.display = 'none'));
// 事例:隐藏页面上所有`<img>`元素?
hide(document.querySelectorAll('img'))
2.如何检查元素是否具有指定的类?

页面DOM里的每个节点上都有一个classList对象,程序员可以使用里面的方法新增、删除、修改节点上的CSS类。使用classList,程序员还可以用它来判断某个节点是否被赋予了某个CSS类。

代码语言:javascript
复制
const hasClass = (el, className) => el.classList.contains(className)
// 事例
hasClass(document.querySelector('p.special'), 'special') // true
3.如何切换一个元素的类?
代码语言:javascript
复制
const toggleClass = (el, className) => el.classList.toggle(className)
// 事例 移除 p 具有类`special`的 special 类
toggleClass(document.querySelector('p.special'), 'special')
4.如何获取当前页面的滚动位置?
代码语言:javascript
复制
const getScrollPosition = (el = window) => ({
  x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
  y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});
// 事例
getScrollPosition(); // {x: 0, y: 200}
5.如何平滑滚动到页面顶部
代码语言:javascript
复制
const scrollToTop = () => {
  const c = document.documentElement.scrollTop || document.body.scrollTop;
  if (c > 0) {
    window.requestAnimationFrame(scrollToTop);
    window.scrollTo(0, c - c / 8);
  }
}
// 事例
scrollToTop()

window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。

requestAnimationFrame:优势:由系统决定回调函数的执行时机。60Hz的刷新频率,那么每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿。

6.如何检查父元素是否包含子元素?
代码语言:javascript
复制
const elementContains = (parent, child) => parent !== child && parent.contains(child);
// 事例
elementContains(document.querySelector('head'), document.querySelector('title')); 
// true
elementContains(document.querySelector('body'), document.querySelector('body')); 
// false
7.如何检查指定的元素在视口中是否可见?
代码语言:javascript
复制
const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
  const { top, left, bottom, right } = el.getBoundingClientRect();
  const { innerHeight, innerWidth } = window;
  return partiallyVisible
    ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) &&
        ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
    : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
};
// 事例
elementIsVisibleInViewport(el); // 需要左右可见
elementIsVisibleInViewport(el, true); // 需要全屏(上下左右)可以见
8.如何获取元素中的所有图像?
代码语言:javascript
复制
const getImages = (el, includeDuplicates = false) => {
  const images = [...el.getElementsByTagName('img')].map(img => img.getAttribute('src'));
  return includeDuplicates ? images : [...new Set(images)];
};
// 事例:includeDuplicates 为 true 表示需要排除重复元素
getImages(document, true); // ['image1.jpg', 'image2.png', 'image1.png', '...']
getImages(document, false); // ['image1.jpg', 'image2.png', '...']
9.如何确定设备是移动设备还是台式机/笔记本电脑?
代码语言:javascript
复制
const detectDeviceType = () =>
  /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
    ? 'Mobile'
    : 'Desktop';
// 事例
detectDeviceType(); // "Mobile" or "Desktop"
10.How to get the current URL?
代码语言:javascript
复制
const currentURL = () => window.location.href
// 事例
currentURL() // 'https://google.com'
11.如何创建一个包含当前URL参数的对象?
代码语言:javascript
复制
const getURLParameters = url =>
  (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
    (a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a),
    {}
  );
// 事例
getURLParameters('http://url.com/page?n=Adam&s=Smith'); // {n: 'Adam', s: 'Smith'}
getURLParameters('google.com'); // {}
12.如何将一组表单元素转化为对象?
代码语言:javascript
复制
const formToObject = form =>
  Array.from(new FormData(form)).reduce(
    (acc, [key, value]) => ({
      ...acc,
      [key]: value
    }),
    {}
  );
// 事例
formToObject(document.querySelector('#form')); 
// { email: 'test@email.com', name: 'Test Name' }
13.如何从对象检索给定选择器指示的一组属性?
代码语言:javascript
复制
const get = (from, ...selectors) =>
  [...selectors].map(s =>
    s
      .replace(/\[([^\[\]]*)\]/g, '.$1.')
      .split('.')
      .filter(t => t !== '')
      .reduce((prev, cur) => prev && prev[cur], from)
  );
const obj = { selector: { to: { val: 'val to select' } }, target: [1, 2, { a: 'test' }] };
// Example
get(obj, 'selector.to.val', 'target[0]', 'target[2].a'); 
// ['val to select', 1, 'test']
14.如何在等待指定时间后调用提供的函数?
代码语言:javascript
复制
const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);
delay(
  function(text) {
    console.log(text);
  },
  1000,
  'later'
); 
// 1秒后打印 'later'
15.如何在给定元素上触发特定事件且能选择地传递自定义数据?
代码语言:javascript
复制
const triggerEvent = (el, eventType, detail) =>
  el.dispatchEvent(new CustomEvent(eventType, { detail }));
// 事例
triggerEvent(document.getElementById('myId'), 'click');
triggerEvent(document.getElementById('myId'), 'click', { username: 'bob' });

自定义事件的函数有 EventCustomEventdispatchEvent

代码语言:javascript
复制
// 向 window派发一个resize内置事件
window.dispatchEvent(new Event('resize'))
 
// 直接自定义事件,使用 Event 构造函数:
var event = new Event('build');
var elem = document.querySelector('#id')
// 监听事件
elem.addEventListener('build', function (e) { ... }, false);
// 触发事件.
elem.dispatchEvent(event);

CustomEvent 可以创建一个更高度自定义事件,还可以附带一些数据,具体用法如下:

代码语言:javascript
复制
var myEvent = new CustomEvent(eventname, options);
其中 options 可以是:
{
  detail: {
    ...
  },
  bubbles: true,    //是否冒泡
  cancelable: false //是否取消默认事件
}

其中 detail 可以存放一些初始化的信息,可以在触发的时候调用。其他属性就是定义该事件是否具有冒泡等等功能。

内置的事件会由浏览器根据某些操作进行触发,自定义的事件就需要人工触发。

dispatchEvent 函数就是用来触发某个事件:

代码语言:javascript
复制
element.dispatchEvent(customEvent);

上面代码表示,在 element 上面触发 customEvent 这个事件。

代码语言:javascript
复制
// add an appropriate event listener
obj.addEventListener("cat", function(e) { process(e.detail) });
 
// create and dispatch the event
var event = new CustomEvent("cat", {"detail":{"hazcheeseburger":true}});
obj.dispatchEvent(event);
使用自定义事件需要注意兼容性问题,而使用 jQuery 就简单多了:
// 绑定自定义事件
$(element).on('myCustomEvent', function(){});
 
// 触发事件
$(element).trigger('myCustomEvent');
// 此外,你还可以在触发自定义事件时传递更多参数信息:
 
$( "p" ).on( "myCustomEvent", function( event, myName ) {
  $( this ).text( myName + ", hi there!" );
});
$( "button" ).click(function () {
  $( "p" ).trigger( "myCustomEvent", [ "John" ] );
});
16.如何从元素中移除事件监听器?
代码语言:javascript
复制
const off = (el, evt, fn, opts = false) => el.removeEventListener(evt, fn, opts);
const fn = () => console.log('!');
document.body.addEventListener('click', fn);
off(document.body, 'click', fn);
17.如何获得给定毫秒数的可读格式?
代码语言:javascript
复制
const formatDuration = ms => {
  if (ms < 0) ms = -ms;
  const time = {
    day: Math.floor(ms / 86400000),
    hour: Math.floor(ms / 3600000) % 24,
    minute: Math.floor(ms / 60000) % 60,
    second: Math.floor(ms / 1000) % 60,
    millisecond: Math.floor(ms) % 1000
  };
  return Object.entries(time)
    .filter(val => val[1] !== 0)
    .map(([key, val]) => `${val} ${key}${val !== 1 ? 's' : ''}`)
    .join(', ');
};
// 事例
formatDuration(1001); // '1 second, 1 millisecond'
formatDuration(34325055574); 
// '397 days, 6 hours, 44 minutes, 15 seconds, 574 milliseconds'
18.如何获得两个日期之间的差异(以天为单位)?
代码语言:javascript
复制
const getDaysDiffBetweenDates = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / (1000 * 3600 * 24);
// 事例
getDaysDiffBetweenDates(new Date('2017-12-13'), new Date('2017-12-22')); // 9
19.如何向传递的URL发出GET请求?
代码语言:javascript
复制
const httpGet = (url, callback, err = console.error) => {
  const request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.onload = () => callback(request.responseText);
  request.onerror = () => err(request);
  request.send();
};
httpGet(
  'https://jsonplaceholder.typicode.com/posts/1',
  console.log
); 
// {"userId": 1, "id": 1, "title": "sample title", "body": "my text"}
20.如何对传递的URL发出POST请求?
代码语言:javascript
复制
const httpPost = (url, data, callback, err = console.error) => {
  const request = new XMLHttpRequest();
  request.open('POST', url, true);
  request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
  request.onload = () => callback(request.responseText);
  request.onerror = () => err(request);
  request.send(data);
};
const newPost = {
  userId: 1,
  id: 1337,
  title: 'Foo',
  body: 'bar bar bar'
};
const data = JSON.stringify(newPost);
httpPost(
  'https://jsonplaceholder.typicode.com/posts',
  data,
  console.log
); 
// {"userId": 1, "id": 1337, "title": "Foo", "body": "bar bar bar"}
21.如何为指定选择器创建具有指定范围,步长和持续时间的计数器?
代码语言:javascript
复制
const counter = (selector, start, end, step = 1, duration = 2000) => {
  let current = start,
    _step = (end - start) * step < 0 ? -step : step,
    timer = setInterval(() => {
      current += _step;
      document.querySelector(selector).innerHTML = current;
      if (current >= end) document.querySelector(selector).innerHTML = end;
      if (current >= end) clearInterval(timer);
    }, Math.abs(Math.floor(duration / (end - start))));
  return timer;
};
// 事例
counter('#my-id', 1, 1000, 5, 2000); 
// 让 `id=“my-id”`的元素创建一个2秒计时器
22.如何将字符串复制到剪贴板?
代码语言:javascript
复制
const el = document.createElement('textarea');
  el.value = str;
  el.setAttribute('readonly', '');
  el.style.position = 'absolute';
  el.style.left = '-9999px';
  document.body.appendChild(el);
  const selected =
    document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false;
  el.select();
  document.execCommand('copy');
  document.body.removeChild(el);
  if (selected) {
    document.getSelection().removeAllRanges();
    document.getSelection().addRange(selected);
  }
};
// 事例
copyToClipboard('Lorem ipsum'); 
// 'Lorem ipsum' copied to clipboard
23.如何确定页面的浏览器选项卡是否聚焦?
代码语言:javascript
复制
const isBrowserTabFocused = () => !document.hidden;
// 事例
isBrowserTabFocused(); // true
24.如何创建目录(如果不存在)?
代码语言:javascript
复制
const fs = require('fs');
const createDirIfNotExists = dir => (!fs.existsSync(dir) ? fs.mkdirSync(dir) : undefined);
// 事例
createDirIfNotExists('test');
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-03-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ES6相关
    • ECMA介绍
      • let、const
        • 解构赋值
          • 字符串以及字符串模板
            • 函数默认参数、箭头函数、剩余参数
              • 数组循环
                • 数组新增方法
                  • 对象简洁语法及新增对象
                    • Promise
                      • 模块化
                        • 类和继承
                          • Symbol和generator
                            • async、await
                              • Set和WeakSet数据结构
                                • Map和WeakMap数据结构
                                  • 数值的变化
                                    • ES2018 (ES9) 新增
                                      • Proxy代理的使用
                                        • Reflect的使用
                                          • 技巧
                                          领券
                                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档