码迷,mamicode.com
首页 > 其他好文 > 详细

【前端学习】ECMAScript 6入门

时间:2020-05-25 19:20:41      阅读:60      评论:0      收藏:0      [点我收藏+]

标签:poi   text   out   ble   NPU   用途   console   函数的参数   big   

ECMAScript 6入门

let和const命令

  1. let命令声明的变量只在let命令所在的代码块内有效
  2. let所声明的变量一定要在声明后使用,否则报错
  3. 块级作用域的出现,实际上使得广泛应用的匿名立即执行函数表达式(匿名IIFE)不再必要了
  4. const只能保证指向实际数据的指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了
  5. ES6规定,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性

变量的解构赋值

  1. 对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,而对象的属性没有次序
  2. 对象的解构赋值可以取到继承的属性
  3. 字符串也可以解构赋值,类似数组的对象都有一个length属性,还可以对这个属性解构赋值
  4. 解构赋值的规则是:只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错
  5. 函数的参数也可以使用解构赋值,下面是一个使用默认值的函数参数解构例子:
function move({x = 0, y = 0} = {}) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
  1. 可以使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括号
  2. 变量的解构赋值可以用于从函数返回多个值:
// 返回一个数组
function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一个对象
function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

字符串的扩展

  1. ES6为字符串添加了遍历器接口,使得字符串可以被for...of循环遍历
for (let codePoint of ‘foo‘) {
  console.log(codePoint)
}
  1. 如果使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中
  2. 模板字符串中,可以使用<%...%>放置JavaScript代码,使用<%= ... %>输出JavaScript表达式
let template = `
<ul>
  <% for (let i = 0; i < data.supplies.length; i++) { %>
    <li><%= data.supplies[i] %></li>
  <% } %>
</ul>
`
  1. 模板字符串可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。如果模板字符里面有变量,就会先将模板字符串处理成多个参数,再调用函数
let a = 5;
let b = 10;

function tag(s, v1, v2) {
  console.log(s[0]);
  console.log(s[1]);
  console.log(s[2]);
  console.log(v1);
  console.log(v2);
  return ‘OK‘;
}
tag`Hello ${ a + b } world ${ a * b }`;
// "Hello "
// " world "
// ""
// 15
// 50
// "OK"

字符串的新增方法

  1. codePointAt()方法是测试一个字符由两个字节还是由四个字节组成的最简单方法
  2. ES6提供了新的字符串方法includes()startsWith()endsWith()
  3. ES2017引入了字符串补全长度的功能,padStart()用于头部补全,padEnd()用于尾部补全
  4. ES2019对字符串实例新增了trimStart()trimEnd()两个方法,用于消除空格

正则的扩展

  1. ES6可以使用第二个参数为正则对象指定修饰符,但返回的正则表达式会忽略原有正则表达式的修饰符,只使用新指定的修饰符
  2. ES6对正则表达式添加了u修饰符,含义为“Unicode模式”,用来正确处理大于\uFFFF的Unicode字符。利用这一点,可以写出一个正确返回字符串长度的函数
function codePointLength(text) {
  var result = text.match(/[\s\S]/gu);
  return result ? result.length : 0;
}

var s = ‘????‘;
s.length  // 4
codePointLength(s)  // 2
  1. ES6对正则表达式添加了y修饰符,它的设计本意就是让头部匹配的标志^在全局匹配中都有效
  2. ES6新增了dotAll模式,即点(dot)代表一切字符
  3. 先行断言指的是,x只有在y前面才匹配,必须写成/x(?=y)/,先行否定断言指的是,x只有不在y前面才匹配,必须写成/x(?!y)/。后行断言正好相反,x只有在y后面才匹配,必须写成/(?<=y)x/。后行否定断言指的是x只有不在y后面才匹配,必须写成/(?<!y)x/,下面是几个例子:
/\d+(?=%)/.exec(‘100% of US presidents have been male‘) // [‘100‘]
/\d+(?!%)/.exec(‘that\‘s all 44 of them‘) // [‘44‘]
/(?<=\$)\d+/.exec(‘Benjamin Franklin is on the $100 bill‘)  // [‘100‘]
/(?<!\$)\d+/.exec(‘it\‘s worth about €90‘)  // [‘90‘]
  1. 后行断言的组匹配,与正常情况下结果是不一样的,其反斜杠引用也与通常的顺序相反,必须放在对应的那个括号之前
  2. ES2018引入了一种新的类的写法\p{...}\P{...},允许正则表达式匹配符合Unicode某种属性的所有字符
  3. ES2018引入了具名组匹配,允许为每一个组匹配指定一个名字。字符串替换时,使用$<组名>引用具名组
const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;

const matchObj = RE_DATE.exec(‘1999-12-31‘);
const year = matchObj.groups.year;  // 1999
const month = matchObj.groups.month;  // 12
const day = matchObj.groups.day;  // 31

数值的扩展

  1. ES6在Number对象上,新提供了Number.isFinite()Number.isNaN()两个方法
  2. Number.EPSILON可以用来设置“能够接受的误差范围”,它的实质是一个可以接受的最小误差范围
function withinErrorMargin (left, right) {
  return Math.abs(left - right) < Number.EPSILON * Math.pow(2, 2);
}

0.1 + 0.2 === 0.3 // false
withinErrorMargin(0.1 + 0.2, 0.3) // true

1.1 + 1.3 === 2.4 // false
withinErrorMargin(1.1 + 1.3, 2.4) // true
  1. ES2016新增了一个指数运算符(**),它的一个特点是右结合,而不是常见的左结合
  2. ES2020引入了一种新的数据类型BigInt(大整数),只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示,但它不能与普通数值进行混合运算

函数的扩展

  1. ES6允许为函数的参数设置默认值,即直接写在参数定义的后面
  2. 参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的
let x = 99;
function foo(p = x + 1) {
  console.log(p);
}

foo() // 100

x = 100;
foo() // 101
  1. 参数默认值可以与解构赋值的默认值结合起来使用
// 写法一
// 函数参数默认值是空对象,但是设置了对象解构赋值的默认值
function m1({x = 0, y = 0} = {}) {
  return [x, y];
}

// 写法二
// 函数参数默认值是有具体属性的对象,但是没有设置对象解构赋值的默认值
function m2({x, y} = {x: 0, y: 0}) {
  return [x, y];
}

// 函数没有参数的时候
m1()  // [0, 0]
m2()  // [0, 0]

// x和y都有值的时候
m1({x: 3, y: 8})  // [3, 8]
m2({x: 3, y: 8})  // [3, 8]

// x有值,y无值的情况
m1({x: 3})  // [3, 0]
m2({x: 3})  // [3, undefined]

// x和y都无值的情况
m1({})  // [0, 0]
m2({})  // [undefined, undefined]

m1({z: 3})  // [0, 0]
m2({z: 3})  // [undefined, undefined]
  1. 通常情况下,定义了默认值的参数,应该是函数的尾参数
  2. ES6引入rest参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中
  3. 箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。this对象的指向是可变的,但是在箭头函数中,它是固定的
  4. 以下两个场合不应该使用箭头函数:
  • 定义对象的方法,且该方法内部包括this
  • 需要动态this的时候

数组的扩展

  1. 扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分割的参数序列。它主要用于函数调用
function push(array, ...items) {
  array.push(...items);
}

function add(x, y) {
  return x + y;
}

const numbers = [4, 38];
add(...numbers) // 42
  1. 扩展运算符还可以将字符串转为真正的数组,如[...‘hello‘]。这有一个重要的好处,那就是能够正确识别四个字节的Unicode字符
  2. Array.from方法支持类似数组的对象和没有部署遍历器接口(Symbol.iterator)的对象。这些对象都可以通过Array.from方法转为数组,而此时扩展运算符就无法转换
  3. indexOf方法无法识别数组的NaN成员,但是findIndex方法可以借助Object.is方法左到:
[NaN].indexOf(NaN)
// -1

[NaN].findIndex(y => Object.is(NaN, y))
// 0
  1. ES6明确将空位转为undefined
  2. ES2019明确规定,Array.prototype.sort()的默认排序算法必须稳定。这个规定已经做到了,现在JavaScript各个主要实现的默认排序算法都是稳定的

对象的扩展

  1. ES6又新增了一个类似的关键字super,指向当前对象的原型对象
  2. 对象的解构赋值用于从一个对象取值,相当于将目标对象自身的所有可遍历的(enumerable)、但尚未被读取的属性,分配到指定的对象上面。所有的键和它们的值,都会拷贝到新对象上面
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }
x // 1
y // 2
z // { a:3, b: 4 }
  1. 对象的扩展运算符等同于使用Object.assign()方法
  2. 如果想完整克隆一个对象,还拷贝对象原型的属性,可以采用下面的写法:
// 写法一
const clone1 = {
  __proto__: Object.getPrototypeOf(obj),
  ...obj
}

// 写法二
const clone2 = Object.assign(
  Object.create(Object.getPrototypeOf(obj)),
  obj
);

// 写法三
const clone3 = Object.create(
  Object.getPrototypeOf(obj),
  Object.getOwnPropertyDescriptors(obj)
)
  1. 扩展运算符的参数对象之中,如果有取值函数get,这个函数是会执行的
  2. ES2020引入了链判断运算符?.,简化层层运算
const firstName = message?.body?.user?.firstName || ‘default‘;
const fooValue = myForm.querySelector(‘input[name=foo]‘)?.value;

对象的新增方法

  1. Object.assign()方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)
  2. Object.getOwnPropertyDescriptors()方法的引入目的,主要是为了解决Object.assign()无法正确拷贝get属性和set属性的问题。它配合Object.defineProperties()方法就可以实现正确拷贝
const shallowMerge = (target, source) => Object.defineProperties(
  target,
  Object.getOwnPropertyDescriptors(source)
);
  1. Object.getOwnPropertyDescriptors()方法的另一个用途,是配合Object.create()方法,将对象属性克隆到一个新对象,这属于浅拷贝
const shallowClone = (obj) => Object.create(
  Object.getPrototypeOf(obj),
  Object.getOwnPropertyDescriptors(obj)
)

【前端学习】ECMAScript 6入门

标签:poi   text   out   ble   NPU   用途   console   函数的参数   big   

原文地址:https://www.cnblogs.com/Akatsuki-Sanjou/p/12959272.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!