前言

Web架构师养成系列共15篇,每周更新一篇,主要分享、探讨目前大前端领域(前端、后端、移动端)企业中正在用的各种成熟的、新的技术。
部分文章也会分析一些框架的底层实现,让我们做到知其然知其所以然。
本篇文章阅读需要时长:约15分钟

一、ECMAScript 6/7/8简介

ECMAScript 6.0,简称ES6,第一个版本是在2015年6月进行发布,所以也称之为《ECMAScript 2015 标准》(简称 ES2015)。

JavaScript是ECMAScript的一种实现(分支),遵循ECMAScript标准的。目前主流浏览器已经可以完美兼容和使用ES6。ES7/8部分新特性也已经被用于我们的实际开发中。

 
image

本篇主要讲解ES6的知识点,内容如下:let和const、解构赋值、字符串操作、函数、数组API、集合、对象拷贝、延展操作符、对象补充、Generator、Proxy、Reflect。

二、let和const

ES6新增了let和const来声明变量,主要是解决var声明变量所造成的困扰和问题:

  var不能用于定义常量

  var可以重复声明变量

  var存在变量提升

  var不支持块级作用域

而let和const解决了以上问题,具体操作如下:

1)不可以重复声明变量

let site = 'itLike';

let site = 'itLike'; 

console.log(site);

运行结果:

Identifier 'site' has already been declared

2)不存在变量提升

 console.log(site);
 let site = 'itLike';
运行结果: site is not defined

3)可以定义常量

不能给常量重新赋值,但如果是引用类型的话可以进行修改。

// 自然对数的底

const E = 2.718;

E = 2.71; 

console.log(E);

运行结果: 

Assignment to constant variable.

//  引用类型

const LK = {

   name:'itLike', 

   intro: '喜欢IT, 就上撩课(itLike.com)'

};

LK.name = '撩课';

console.log(LK);

运行结果:
 
image

4) 块级作用域

如果用var定义变量,变量是通过函数或者闭包拥有作用域;但,现在用let定义变量,不仅仅可以通过函数/闭包隔离,还可以通过块级作用域隔离。
块级作用域用一组大括号定义一个块,使用 let 定义的变量在大括号的外部是访问不到的,此外,let声明的变量不会污染全局作用域。

{let site = 'itLike';}

console.log(site);

运行结果:

site is not defined

if(1){  let str = '小撩'; }

console.log(str);

运行结果: 

str is not defined

5)案例运用

高级排他实现(不再使用闭包)

 
image

三、解构赋值

用于分解js中对象的结构。

1) 用于数组的结构

//  普通写法

let nameArr = ['撩课', '小撩', '小煤球'];

let name1 = nameArr[0];

let name2 = nameArr[1];

let name3 = nameArr[2];

//  解构写法

let [name1, name2, name3] = nameArr;

console.log(name1, name2, name3);

2)对象的解构

//  写法1

let {name, age, sex}

 = {name: '小煤球', age: 1, sex: '公'};

// 结果: 小煤球 1 公

console.log(name, age, sex);

//  写法2: 解构重命名

let {name: lkName, age: lkAge, sex: lkSex}

= {name: '小煤球', age: 1, sex: '公'};

// 结果: 小煤球 1 公

console.log(lkName, lkAge, lkSex);  

//  写法3: 可以设置默认值

let {name, age, sex = '公'} 

= {name: '小煤球', age: 1};

console.log(sex);  // 公

//  写法4:省略解构

let [, , sex] = ['小煤球', 1, '公 '];

console.log(sex);

3) 应用场景

在封装ajax的GET和POST请求时, 就可以运用到解构的知识点,代码如下:

 
image

四、延展操作符

1)延展数组

  let arr1 = [ 'a', 'b', 'c'];

  let arr2 = [1, 2, 3];

  let result = [...arr1, ...arr2];

  console.log(result); 

   //  [ "a", "b", "c", 1, 2, 3 ]

2)延展对象

  let smallDog = {name:'小煤球', age: 1};

  let bigDog = {name: 'Python', age: 2};

  let dog = {...smallDog, ...bigDog};

  console.log(dog);  

  // {name: "Python", age: 2}

注意: 如果对象中的属性一致, 会被覆盖

3)开发应用场景

  function getMinValue() {

       console.log(Math.min(...arguments));

  }

  getMinValue(1, -99, 22, 10, 9);   //  -99

五、字符串操作

新增字符串方法

1) startsWith()

判断字符串是否以 XX 开头

let url = 'http://www.itlike.com';

console.log(url.startsWith('http'));  // true

2) endsWith()

判断字符串是否以 XX 结尾

let file = 'index.html';

console.log(file.endsWith('html'));  // true

3) includes()

判断字符串中是否包含 XX

let str = 'liaoke';

console.log(str.includes('ao')); // true

4) repeat()

拷贝n份

let title = '撩课在线';

console.log(title.repeat(100));

5) padStart() / padEnd()

padStart()用于头部补全,

padEnd()用于尾部补全; 

第一个参数用来指定字符串的最小长度,

第二个参数是用来补全的字符串。

//  "2030111111"

let y1 = '2030'.padEnd(10, '1'); 

//   "2030-11-22"

let y2 = '11-22'.padStart(10, '2030-MM-DD');  

console.log(y1, y2);

模板字符串

1) 模板字符串

模板字符串用反引号(`)包含,变量用${}括起来; 在开发中使用是非常灵活的。

 let name = '小煤球';
let sex = '公';
let result = `我叫 ${name} , 我是 ${sex} 的`;
console.log(result);
// 我叫 小煤球 , 我是 公 的

2) 模板字符串遍历插入

 
image

3) 模板字符串实现原理

let name = '小煤球';
let sex = '公';
let result = `我叫 ${name} , 我是 ${sex} 的`;
result = result.replace(/\${([^}]*)}/g);
console.log(result);

六、函数操作

1) 设置默认参数

function logPerson(name, sex = '男', age = 20) {
console.log(name);
console.log(sex);
console.log(age);
} // undefined 男 20 logPerson();

2)延展参数转化

 let logName = function (arg1, ...arg2) {
console.log(arg1, arg2);
};
// 宋小宝 , ["赵薇", "王菲", "那英"]
logName('宋小宝', '赵薇', '王菲', '那英');

3)箭头函数

箭头函数简化了函数的的定义方式;
一般以 "=>" 操作符左边为输入的参数;
而右边则是进行的操作以及返回的值 inputs => output。

 ["赵薇", "王菲", "那英"].forEach(
val => console.log(val)
);

注意:

1)多个参数要用()包起来,函数体有多条语句需要用{}包起来;
2)箭头函数根本没有自己的this,所以内部的this就是外层代码块的this。 正是因为它没有this,从而避免了this指向的问题;
3)箭头函数中没有arguments对象。

 
image

注意:

1)let声明的变量不会放在window上
2)对象不是作用域

 let site = 'like.com';

 let obj = {

    site: '撩课',
func: () => { // this指向window
console.log(this);
// undefined console.log(this.site); } }; let func = obj.func; func();

七、数组新增方法

ES6中在原有数组的方法上又新增了一些好用的方法,比如:forEach、findIndex、find、map、reduce、filter、every、some等。

1)Array.from()

将一个数组或者类数组变成新数组,是浅拷贝操作。

let oldArr = [

    '小煤球', 10, 

     {df1: '小Python',  df2: '土豆'}

 ];

 let newArr = Array.from(oldArr);

 console.log(newArr === oldArr); // false

2)Array.of()

创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。

  // [8]

  console.log(Array.of(8));

  // [1, 2, 3]

  console.log(Array.of(1, 2, 3));

  // [ , , , , , , ]

  console.log(Array(8));

  // [1, 2, 3]

  console.log(Array(1, 2, 3));

3)Array.fill()

用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。
语法结构:arr.fill(value[, start[, end]])

  let array1 = [1, 2, 3, 4, 5];

  // 用 撩 替换 索引[2,5]中的内容

  console.log(array1.fill('撩', 2, 5));

  // 用 撩 替换 索引[1]中的内容

  console.log(array1.fill('撩', 1));

  // 用 撩 替换 数组中所有内容

  console.log(array1.fill('撩'));

运行结果:

 
image

八、对象操作

8.1 属性简写

如果对象中属性值和变量名一样,并且属性的值就是变量表示值,则简写。

 
image

8.2 super

通过super可以调用prototype上的属性或方法。

 
image

8.3 Object.is

对比两个值是否相等

> console.log(Object.is(Array, Object));

**8.4  Object.setPrototypeOf**

将一个指定的对象的原型设置为另一个对象或者null

  let dog1 = { name: '小煤球' };

  let obj = {name: 'xxx'};

  Object.setPrototypeOf(dog1, obj);

  let dog2 = {

      __proto__: obj

  };

  console.log(dog1.__proto__.name);

  console.log(dog2.__proto__.name);

**8.5 对象拷贝-深拷贝和浅拷贝**

**1)浅拷贝**

  Object.assign拷贝

  let obj1 = { dog1: { name: '小煤球' } };

  let obj2 = { name: '小Python' };

  let obj = {};

  Object.assign(obj, obj1, obj2);

  console.log(obj);

  延展拷贝

  let obj1 = { dog1: { name: '小煤球' } };

  let obj2 = { name: '小Python' };

  console.log({ ...obj1, ...obj2 });

2)深拷贝

  JSON.parse和JSON.stringify

  let obj1 = { dog1: { name: '小煤球' } };

  let obj2 = { name: '小Python' };

  console.log(JSON.parse(JSON.stringify({ ...obj1, ...obj2 })));

递归调用实现

 
image

九、类操作

在之前定义类是通过构造函数来操作的,es6新增了class关键字,此时,我们也可以像其它语言一样来创建各种类了。

class Person{

constructor(name, age){

    this.name = name;

    this.age = age;

}

print(){

    console.log('我叫' + this.name + ',今年' + this.age + '岁');

}

}

类的继承

小案例:五彩小球

运行效果:

 
image

核心代码:

 
image
 
image

十、集合操作

1set

一个Set是一堆东西的集合,Set有点像数组,不过跟数组不一样的是,Set里面不能有重复的内容;

> // 创建一个集合

  let set = new Set(['张三', '李四', '王五', '张三', '李四']);

  console.log(set);

  // 一个属性

  console.log(set.size);

  // 四个方法

  // add

  console.log(set.add('刘德华').add('旋之华'));

  console.log(set);

  // delete

  console.log(set.delete('张三'));

  console.log(set.delete('李四'));

  console.log(set);

  // has

  console.log(set.has('张三'));

  console.log(set.has('张三1'));

  // clear

  console.log(set.clear()); // undefined

  console.log(set);

2)map

Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现。
如果你需要“键值对”的数据结构,Map比Object更合适。
它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
实例属性和方法:size、set、get、has、delete、clear

  // 创建一个Map

  let obj1 = {a: 1}, obj2 = {b: 2};

  const  map = new Map([

      ['name', '张三'],

      ['age', 18],

      ['sex', '男'],

      [obj1, '今天天气很好'],

      [obj2, '适合敲代码'],

      [[1,2], 'hhh']

  ]);

  console.log(map);

  console.log(map.size);

  // set和get

  map.set('friends', ['赵六', '力气']).set(['dog'], '小花');

  console.log(map);

  console.log(map.get('name'));

  console.log(map.get(obj1));

  // delete

  map.delete(obj1);

  console.log(map.delete('xxxx'));

  console.log(map);

  // has

  console.log(map.has(obj1));

  console.log(map.has(obj2));

  // clear

  map.clear();

  console.log(map);

  // 遍历

  map.forEach(function (value, index) {

     console.log(index + ':' + value);

  });

  // 注意事项

  map.set({}, '呵呵呵呵呵');

  map.set({}, '哈哈哈哈');

  console.log(map);

  console.log({} === {});

十一、Generator

为什么要使用generator?

开发中, 比如在做网络请求时我们会进行异步调用,为了保证调用顺序的正确性,通常我们会用回调函数,也可以采用Promise相关的技术来操作。
还有一种常用的解决方案,它就是Generator生成器函数。
顾名思义,它是一个生成器,它也是一个状态机,内部拥有值及相关的状态,生成器返回一个迭代器Iterator对象,我们可以通过这个迭代器,手动地遍历相关的值、状态,保证正确的执行顺序。

1)声明

Generator的声明方式类似一般的函数声明,只是多了个*号,并且一般可以在函数内看到yield关键字。

  function* showNames() {

      yield '张三';

      yield '李四';

      return '王五';

  }

  let show = showNames();

   // {done: false, value: "张三"}

  console.log(show.next());

  // {done: false, value: "李四"}

  console.log(show.next()); 

  // {done: true, value: "王五"}

  console.log(show.next()); 

  // {done: true, value: undefined}

  console.log(show.next());

迭代器有一个next方法,每次执行的时候会返回一个对象,对象里面有两个属性,一个是value表示返回的值,还有就是布尔值done,表示是否迭代完成。

2)模拟实现

 
image

十二、Proxy&&Reflect (了解)

从语法角度讲JavaScript不支持重载。
原因很简单,JS中函数可以传入任意类型、任意个数的参数,
通通可以通过在函数内使用this.arguments获得。
这样,就无法实现同名函数参数列表不同实现不同功能。
当然,在实际使用过程中,可以人为去检测传入实参的个数及类型,来进行不同操作。
但是,这不能叫做重载。
ES6带来了Proxy和Reflect,配合使用可以实现重载。
Proxy用于修改某些操作的默认行为,相当于对原始想进行的操作进行“包装”;
Reflect对象的方法与Proxy对象的方法一一对应,这使得Proxy对象可以方便的调用对应的Reflect方法完成默认行为。

set实现:

 
image

PS: 什么时重载?

简单说,就是函数或者方法有相同的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。

获取代码,有疑惑、答疑,加我微信yejh9522沟通交流即可;下篇更新预告: ES7/8新特性,Async和Promise

撩课-Web架构师养成系列第一篇的更多相关文章

  1. 撩课-Web架构师养成系列(第二篇)-async

    前言 Web架构师养成系列共15篇,每周更新一篇,主要分享.探讨目前大前端领域(前端.后端.移动端)企业中正在用的各种成熟的.新的技术.部分文章也会分析一些框架的底层实现,让我们做到知其然知其所以然. ...

  2. WEB架构师成长系列索引

    WEB架构师成长系列索引 http://www.cnblogs.com/seesea125/archive/2012/04/17/2453256.html

  3. WEB架构师成长之路-架构师都要懂哪些知识 转

    Web架构师究竟都要学些什么?具备哪些能力呢?先网上查查架构师的大概的定义,参见架构师修炼之道这篇文章,写的还不错,再查查公司招聘Web架构师的要求. 总结起来大概有下面几点技能要求: 一. 架构师有 ...

  4. WEB架构师成长之路之三-架构师都要懂哪些知识

    Web架构师究竟都要学些什么?具备哪些能力呢?先网上查查架构师的大概的定义,参见架构师修炼之道这篇文章,写的还不错,再查查公司招聘Web架构师的要求. 总结起来大概有下面几点技能要求: 一. 架构师有 ...

  5. WEB架构师成长之路 三

    Web架构师究竟都要学些什么?具备哪些能力呢?先网上查查架构师的大概的定义,参见架构师修炼之道这篇文章,写的还不错,再查查公司招聘Web架构师的要求. 总结起来大概有下面几点技能要求: 一. 架构师有 ...

  6. 【转载】WEB架构师成长之路

    本人也是coding很多年,虽然很失败,但也总算有点失败的心得,不过我在中国,大多数程序员都是像我一样,在一直走着弯路,如果想成为一个架构师,就必须走正确的路,否则离目标越来越远,正在辛苦工作的程序员 ...

  7. Web 架构师的能力(转)

    文/刘如鸿 最近和几个朋友在谈到时下流行的Web 2.0,也提到了其中最重要的角色——架构师.多方各有争执,不外乎是因为背景和视角的缘故,包括架构一词,本身就从建筑学借鉴而来,至于架构师,则可以 简单 ...

  8. 架构师成长系列 | 从 2019 到 2020,Apache Dubbo 年度回顾与总结

    作者 | 刘军(陆龟)Apache Dubbo PMC 本文整理自架构师成长系列 2 月 18 日直播课程. 关注"阿里巴巴云原生"公众号,回复 "218",即 ...

  9. 深入学习jQuery选择器系列第一篇——基础选择器和层级选择器

    × 目录 [1]id选择器 [2]元素选择器 [3]类选择器[4]通配选择器[5]群组选择器[6]后代选择器[7]兄弟选择器 前面的话 选择器是jQuery的根基,在jQuery中,对事件处理.遍历D ...

随机推荐

  1. ElectronNetTest

    系统环境:Ubuntu 18.04.2 Desktop 软件环境:asp.net core 2.2,Node.js(version>8.6) Github上有人说不支持 asp.net core ...

  2. CentOS修改yum源为阿里云

    yum的工具,自动去下载某个yum仓库的 rpm软件包,并且自动搜索软件下载软件依赖,如同pip3,npm等包管理工具 yum载linux中的 yum仓库是 /etc/yum.repos.d 并且在这 ...

  3. “全栈2019”Java多线程第三十六章:如何设置线程的等待截止时间

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 下一章 "全栈2019"J ...

  4. [模板]最小割树(Gomory-Hu Tree)(luogu4897)

    给定一个\(n\)个点\(m\)条边的无向连通图,多次询问两点之间的最小割 两点间的最小割是这样定义的:原图的每条边有一个割断它的代价,你需要用最小的代价使得这两个点不连通 Input 第一行两个数\ ...

  5. 预处理命令使用详解----#if、#endif、#undef、#ifdef、#else、#elif

    预处理命令 在接触#if.#undef这类预处理指令前,大部分都都接触过#define.#include等预处理命令,通俗来讲预处理命令的作用就是在编译和链接之前,对源文件进行一些文本方面的操作,比如 ...

  6. 前端基础-html 字体标签,排版标签,超链接,图片标签

    主要内容: 字体标签: h1~h6.<font>.<u>.<b>.<strong><em>.<sup>.<sub> ...

  7. 小技巧——病毒分析中关闭ASLR

    原文来自:https://bbs.ichunqiu.com/thread-41359-1-1.html 病毒分析中关闭ASLR 分析病毒的时候,尽可能用自己比较熟悉的平台,这样可以大大地节省时间,像我 ...

  8. Java内存溢出问题总结

    使用Java那么久,在此总结一下Java中常见的内存溢出问题以及对应的解决思路 堆溢出 报错信息 java.lang.OutOfMemoryError: Java heap space 报错原因 堆中 ...

  9. day 71 crm(8) 权限组件的设置,以及权限组件的应用

    ---恢复内容开始--- 前情提要: strak 组件是增删改查组件 , 生活中,需求权限组件,  不足: 1,前后端不分离,   2, 空url也会刷新界面,造成资源浪费   3,如果角色忘记设置权 ...

  10. 在vue项目中stylus的安装及使用

    Stylus是一个CSS预处理器. Stylus安装包安装: dell@DESKTOP-KD0EJ4H MINGW64 /f/gsff-frone $ cnpm install stylus --sa ...