ES6技巧初级

一、ES6简介

一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系?

要讲清楚这个问题,需要回顾历史。1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。

该标准从一开始就是针对 JavaScript 语言制定的,但是之所以不叫 JavaScript,有两个原因。一是商标,Java 是 Sun 公司的商标,根据授权协议,只有 Netscape 公司可以合法地使用 JavaScript 这个名字,且 JavaScript 本身也已经被 Netscape 公司注册为商标。二是想体现这门语言的制定者是 ECMA,不是 Netscape,这样有利于保证这门语言的开放性和中立性。

因此,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 JScript 和 ActionScript)。日常场合,这两个词是可以互换的。

ECMAScript 2015(简称 ES2015)这个词,也是经常可以看到的。它与 ES6 是什么关系呢?

ES6ECMAJavaScript制定的第6个标准版本。

标准委员会最终决定,标准在每年6月正式发布并作为当年的正式版本,接下来的时间里就在此版本的基础上进行改动,直到下一年6月草案就自然变成新一年的版本,这样一来就无需以前的版本号,只要用年份标记即可。ECMAscript 2015是在2015年6月发布ES6的第一个版本。以此类推,ECMAscript 2016是ES6的第二个版本、 ECMAscript 2017是ES6的第三个版本。ES6既是一个历史名词也是一个泛指,含义是5.1版本以后的JavaScript下一代标准,目前涵盖了ES2015ES2016ES2017ES2018ES2019ES2020

所以有些文章上提到的ES7(实质上是ES2016)、ES8(实质上是ES2017)、ES9(实质上是ES2018)、ES10(实质上是ES2019)、ES11(实质上是ES2020),实质上都是一些不规范的概念。从ES1到ES6,每个标准都是花了好几年甚至十多年才制定下来,你一个ES6到ES7,ES7到ES8,才用了一年,按照这样的定义下去,那不是很快就ES20了。用正确的概念来说ES6目前涵盖了ES2015ES2016ES2017ES2018ES2019ES2020

二、声明

1、 变量提升

什么是变量提升
JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明。

var存在变量提升

function fn() {
   //var a
    if (true) {
        console.log(a + ' now')
    }
    else {
        var a = 1
        console.log(2)
    }
}

fn() // a -> undefined

2、for循环的作用域

var a = [];
for(var i = 0; i < 10;i++){
   var q = i;
   a[i] = function(){
       console.log(q)
   }
}
a[0]()
	
其中,由于for循环并不是一个函数体,所以for循环中定义的变量q和i是作用域for循环所在的函数体,和a同级,
i++ 和  q=i 并不是重新定义变量,只是重复赋值,最终循环结束,i = 10,q=9;  
由于function(){console.log(q)} 并不是立即执行,所以这里的q一直是存储的内存引用,最终所有的a[i]()都是输出 9
不过,在es6中新增了let命令声明变量,用法和var类似,不过let所声明的变量,只在let命令所在的代码块有效果,for循环的计数器中就很适合let命令
var a=[];
for(let i = 0; i < 10; i++){
   let q = i;
   a[i] = function(){
       console.log(q)
   }
}
a[6]()    //这里会输出   6  let声明的变量仅在块级作用域有效,所以这里的i只在本轮循环有效果,每次循环的i其实都是一个新的变量

三、解构

字符串解构const [a, b, c, d, e] = "hello"

数值解构const { toString: s } = 123

布尔解构const { toString: b } = true

对象解构

  • 形式:const { x, y } = { x: 1, y: 2 }
  • 默认:const { x, y = 2 } = { x: 1 }
  • 改名:const { x, y: z } = { x: 1, y: 2 }

数组解构

  • 规则:数据结构具有Iterator接口可采用数组形式的解构赋值
  • 形式:const [x, y] = [1, 2]
  • 默认:const [x, y = 2] = [1]

函数参数解构

  • 数组解构:function Func([x = 0, y = 1]) {}
  • 对象解构:function Func({ x = 0, y = 1 } = {}) {}

应用场景

  • 交换变量值:[x, y] = [y, x]
  • 返回函数多个值:const [x, y, z] = Func()
  • 定义函数参数:Func([1, 2])
  • 提取JSON数据:const { name, version } = packageJson
  • 定义函数参数默认值:function Func({ x = 1, y = 2 } = {}) {}
  • 遍历Map结构:for (let [k, v] of Map) {}
  • 输入模块指定属性和方法:const { readFile, writeFile } = require("fs")

👓Tips 1: 从对象中取值

const obj = {
    a:1,
    b:2,
    c:3,
    d:4,
    e:5,
}

1️⃣ 属性名是想要的

const {a,b,c,d,e} = obj;
const f = a + d;
const g = c + e;

2️⃣ 属性名不是想要的

const {a:a1} = obj;
console.log(a1);// 1

3️⃣ 补充

ES6的解构赋值虽然好用。但是要注意**解构的对象不能为undefinednull。**否则会报错,故要给被解构的对象一个默认值。

const {a,b,c,d,e} = obj || {};

四、扩展运算符

1、复制数组/对象(浅拷贝)

const arr1 = [1,2,3];
const arr2 = [...arr1];
console.log(arr2);
// [ 1, 2, 3 ]

2、合并数组/对象

const a = [1,2,3];
const b = [1,5,6];
const c = [...new Set([...a,...b])];//[1,2,3,5,6] 利用set去重
arr.push(...arr1)

const obj1 = {
  a:1,
}
const obj2 = {
  b:1,
}
const obj = {...obj1,...obj2};//{a:1,b:1}

3、向数组/对象中添加元素

let arr1 = ['this', 'is', 'an'];
arr1 = [...arr1, 'array'];
console.log(arr1);
// [ 'this', 'is', 'an', 'array' ]

const user = {
  firstname: 'Chris',
  lastname: 'Bongers'
};
const output = {...user, age: 31};

4、Math()

const arr1 = [1, -1, 0, 5, 3];
const max1 = Math.max(arr1);
console.log(max1);
// NaN
const max2 = Math.max(...arr1);
console.log(max2);
// 5

5、传参

const myFunc = (x1, x2, x3) => {
  console.log(x1);
  console.log(x2);
  console.log(x3);
};
const arr1 = [1, 2, 3];
myFunc(...arr1);
// 1
// 2
// 3

//接受无数个参数的函数
const myFunc = (...args) => {
  console.log(args);
};

6、展开字符串

const str = 'Hello';
const arr = [...str];
console.log(arr);
// [ 'H', 'e', 'l', 'l', 'o' ]

7、解构对象

const user = {
  firstname: 'Chris',
  lastname: 'Bongers',
  age: 31
};

const {firstname, ...rest} = user;
console.log(firstname);
console.log(rest);
// 'Chris'
// { lastname: 'Bongers', age: 31 }

五、字符串模板

const name = '小明';
const score = 59;
const result = `${name}${score > 60?'的考试成绩及格':'的考试成绩不及格'}`;

六、函数

1、回调函数

A callback is a function that is passed as an argument to another function and is executed after its parent function has completed.

function f1(callback){
    callback();
    console.log('f1');
}
function f2(){
    console.log('f2');
}
f1(f2);// f2 f1

2、箭头函数

之前

hello = function() {
  return "Hello World!";
}

用了箭头函数之后:

hello = () => {
  return "Hello World!";
}

如果函数只有一个语句,并且该语句返回一个值,则可以去掉括号和 return 关键字:

箭头函数默认返回值:

hello = () => "Hello World!";

传参

hello = (val) => "Hello " + val;

事实上,如果只有一个参数,您也可以略过括号:

不带括号的箭头函数:

hello = val => "Hello " + val;

七、数组

1、去重

new Set()会把重复的数据过滤到,得到一个类数组的对象

Array.from()可以把类数组的对象转换为真正的数组对象

let a = [1,2,2,3,3,4,5];
let b = Array.from(new Set(a))
console.log(b) // [1,2,3,4,5]

2、过滤

let a = [
    {
        name: 'kele',
        title: '可口可乐'
    },
    {
        name: 'kele',
        title: '芬达'
    },
    {
        name: 'wlg',
        title: '王老吉'
    }
]

let b = a.filter(item => item.name === 'kele');

console.log(b) //[{name: 'kele', title: '可口可乐'},{name: 'kele', title: '芬达'}]

3、判断条件

1️⃣ Array.every(callback)

是否所有元素满足条件

let a = [1,2,3,4,5];
let b = a.every(item => item > 2);
console.log(b) // false

2️⃣ Array.some(callback)

是否存在元素满足条件

let a = [1,2,3,4,5];
let b = a.some(item => item > 2);
console.log(b) // true

3️⃣Array.includes(item, finIndex)

是否包含某个元素

let a = [1,2,3,4,5];
let b = a.includes(2);
console.log(b) // true

4、查找

1️⃣ Array.find(callback)

let a = [1,2,3,4,5];
let b = a.find(item => item > 2);
console.log(b) // 3

2️⃣ Array.findIndex(callback)

let a = [1,2,3,4,5];
let b = a.findIndex(item => item > 2);
console.log(b) // 2  符合条件的为元素3 它的索引为2

5、遍历

1️⃣ for in

for in 语句循环遍历对象的属性:

const person = {fname:"John", lname:"Doe", age:25};

let text = "";
for (let x in person) {
  text += person[x];
}

for in 语句也可以遍历数组的属性:

const numbers = [45, 4, 9, 16, 25];

let txt = "";
for (let x in numbers) {
  txt += numbers[x];
}

如果索引顺序很重要,请不要在数组上使用 for in

索引顺序依赖于实现,可能不会按照您期望的顺序访问数组值。

当顺序很重要时,最好使用 for 循环、for of 循环或 Array.forEach()

2️⃣ Array.forEach()

forEach() 方法为每个数组元素调用一次函数(回调函数)。

const numbers = [45, 4, 9, 16, 25];

let txt = "";
numbers.forEach(myFunction);

//注意这里的三个参数
// 项目值
// 项目索引
// 数组本身
// 可以省略未使用的
function myFunction(value, index, array) {
  txt += value;
}

3️⃣ for of

const cars = ["BMW", "Volvo", "Mini"];

let text = "";
for (let x of cars) {
  text += x;
}

4️⃣ map

**map()** 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。

const array1 = [1, 4, 9, 16];

// pass a function to map
const map1 = array1.map(x => x * 2);

console.log(map1);
// expected output: Array [2, 8, 18, 32]

6、扁平化

1️⃣ flat

需求:多维数组=>一维数组

let ary = [1, [2, [3, [4, 5]]], 6];
arr_flat = arr.flat(Infinity);

八、对象

1、Object.values():返回以值组成的数组

const deps = {
    '采购部':[1,2,3],
    '人事部':[5,8,12],
    '行政部':[5,14,79],
    '运输部':[3,64,105],
}
let member = Object.values(deps).flat(Infinity);

2、Object.entries():返回以键和值组成的数组

const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]

// array like object
const obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]

// array like object with random key ordering
const anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]

// getFoo is property which isn't enumerable
const myObj = Object.create({}, { getFoo: { value() { return this.foo; } } });
myObj.foo = 'bar';
console.log(Object.entries(myObj)); // [ ['foo', 'bar'] ]

// non-object argument will be coerced to an object
console.log(Object.entries('foo')); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]

// iterate through key-value gracefully
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"

九、其他

1、 空值合并运算符

const nullValue = null;
const emptyText = ""; // 空字符串,是一个假值,Boolean("") === false
const someNumber = 42;

const valA = nullValue ?? "valA 的默认值";
const valB = emptyText ?? "valB 的默认值";
const valC = someNumber ?? 0;

console.log(valA); // "valA 的默认值"
console.log(valB); // ""(空字符串虽然是假值,但不是 null 或者 undefined)
console.log(valC); // 42

可以用来优化判断

if((value??'') !== ''){
  //...
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值