ES6《学习笔记》

本文摘自:http://es6.ruanyifeng.com/#docs/intro
感谢:阮一峰,CSDN,极客学院,慕课网
作用:学习记录,技术分享

ES6简介:
1.ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现。ECMAScript 2015 简称 ES6
2.Node 是 JavaScript 的服务器运行环境
3.新版本语言只是在原有基础上新增了一些语法糖,执行时还会转化成ES5!目的为了方便程序员使用,让代码更规范!
4.各大浏览器的最新版本对Es6的支持已经超过六90%(这也是ES6的缺点,低版本的浏览器不支持!)

一.Babel转码器
1.简介:Babel 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码,从而在现有环境执行。这 意味着,你可以用 ES6 的方式编写程序,又不用担心现有环境是否支持。
2.安装:$ npm install --save-dev @babel/core
3.例子:

// 转码前
input.map(item => item + 1);

// 转码后
input.map(function (item) {
  return item + 1;
});

二.变量申明 Let 和 Const 命令
ES5 只有两种声明变量的方法:var命令和function命令。
ES6 一共有 6 种声明变量的方法:var命令、function命令、let、const命令、import命令和class命令。

1.Let命令的基本用法

1.1ES6新增的let命令,用来申明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效并且不允许重复声明。如下:

{
  let a = 10;
  var b = 1;
}

a // ReferenceError: a is not defined.
b // 1

原本JS只有函数作用域,没有块级作用域。ES6 新增了let变量声明命令,声明的变量仅在块级作用域内有效

1.2不存在的变量提升
var 申明变量的时候会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。

console.log(a); // 输出undefined
var a = 2;

按照正常的逻辑,变量需要在生明后使用!为了纠正这种做法解决强迫症,let 命令改变了语法行为。

console.log(b); // 报错ReferenceError
let b = 2;

1.3 暂时性死区

使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”。

缺点:typeof不再是一个百分之百安全的操作。
typeof是一个运算符,有2种使用方式:typeof(表达式)和typeof 变量名,第一种是对表达式做运算,第二种是对变量做运算。

优点:规范编码习惯

1.4使用场景

for (let i = 0; i < 10; i++) {
  // ...
}
console.log(i);

//var 声明变量i
var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

//let 声明变量i
var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
// abc
// abc
// abc

2.const命令

2.1与let 相同的地方 不存在变量提升、会有暂时性死区、不允许重复声明

2.2 const声明一个只读的常量。一旦声明,常量的值就不能改变,且只在声明所在的块级作用域内有效。
这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.

const foo;

三.变量的解构赋值

简介:解构不仅可以用于数组,还可以用于对象。
解构赋值的规则是
1.解构成对象,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。
2. 解构成数组,等号右边必须为可迭代对象

1.1.数组的结构赋值
数组的解构赋值是指,左边是一个数组,右边也是数组,按照对应的位置对左边的变量进行赋值。

let [a, [b], c] = [1, [2,3], 4];  
//a=1, b=2, c=4

如果等号右边的值或转为对象以后,不具备 (Interator ES6迭代器) 接口,或者本身不具备Interator接口,则会报错。

let [a] = 1;
let [a] = false;
let [a] = NaN;
let [a] = undefined;
let [a] = null;
let [a] = {};
 
// 以上都会报错,前面五个转为对象后不具备Interator接口,最后一个本身不具备Interator接口

1.2.对象的解构赋值
变量必须与属性同名,才能取到对应的值:

let {a, b} = {a:1, b:2};
//a=1, b=2
 
let {c} = {a:1, b:2};
//c=undefined

使用ES6 和 不使用ES6 区别:

当需要获取某个对象的属性值时,需要单独获取:

var data = $('body').data(); // data有house和mouse属性
var house = data.house;
var mouse = data.mouse;

一次性获取对象的子属性:

var { house, mouse} = $('body').data()

对于数组也是一样的:

var [col1, col2]  = $('.column');

四.字符串的扩展

1.模板字符串

传统的 JavaScript 语言,输出模板通常是这样写的(下面使用了 jQuery 的方法)。

$('#result').append(
  'There are <b>' + basket.count + '</b> ' +
  'items in your basket, ' +
  '<em>' + basket.onSale +
  '</em> are on sale!'
);

上面这种写法相当繁琐不方便,ES6 引入了模板字符串解决这个问题

$('#result').append(`
  There are <b>${basket.count}</b> items
   in your basket, <em>${basket.onSale}</em>
  are on sale!
`);

模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。


var name = 'Your name is ' + first + ' ' + last + '.'

ES6的写法更加简洁、直观。

var name = `Your name is ${first} ${last}.`

优点:大括号内部可以放入任意的 JavaScript 表达式,可以进行运算,以及引用对象属性。
模板字符串之中还能调用函数。

缺点:前面提到标签模板里面,可以内嵌其他语言。但是,模板字符串默认会将字符串转义,导致无法嵌入其他语言。

五.对象属性

1.属性的简洁表示法
ES6 允许直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

const aa= 'ceshi';
const bb= {aa};
bb // {aa: "ceshi"}
// 等同于
const bb = {aa: aa};

上面代码表明,ES6 允许在对象之中,直接写变量。这时,属性名为变量名, 属性值为变量的值。下面是另一个例子。

function f(x, y) {
  return {x, y};
}

// 等同于

function f(x, y) {
  return {x: x, y: y};
}

f(1, 2) // Object {x: 1, y: 2}

2.属性名表达式
JavaScript 定义对象的属性,有两种方法。

// 方法一
obj.foo = true;
// 方法二
obj['a' + 'bc'] = 123;

上面代码的方法一是直接用标识符作为属性名,方法二是用表达式作为属性名,这时要将表达式放在方括号之内。
但是,如果使用字面量方式定义对象(使用大括号),在 ES5 中只能使用方法一(标识符)定义属性。

var obj = {
  foo: true,
  abc: 123
};

ES6 允许字面量定义对象时,用方法二(表达式)作为对象的属性名,即把表达式放在方括号内。

let propKey = 'foo';

let obj = {
  [propKey]: true,
  ['a' + 'bc']: 123
};

六.箭头函数

ES6 允许使用“箭头”(=>)定义函数。

var f = v => v;
this.s1 = 0;
this.s2 = 0;

// 箭头函数
ceshi(() => this.s1++, 1000);

// 普通函数
ceshi(function () { });

七.Promise

简介:Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。

1.基本用法
ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。

下面代码创造了一个Promise实例。

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

八. Set 和 Map
参考文献:https://blog.csdn.net/u011666411/article/details/79878932
10.1 Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。

Set 对象方法

var mySet = new Set();
mySet.add(1);
mySet.add("foo");
 
mySet.size;       // 2
mySet.has("foo"); // true
 
mySet.clear();
 
mySet.size;       // 0
mySet.has("bar")  // false

迭代Set对象

// 迭代整个set
// 按顺序输出:1, "some text" 
for (let item of mySet) console.log(item);
 
// 按顺序输出:1, "some text" 
for (let item of mySet.keys()) console.log(item);
 
// 按顺序输出:1, "some text" 
for (let item of mySet.values()) console.log(item);
 
// 按顺序输出:1, "some text" 
//(键与值相等)
for (let [key, value] of mySet.entries()) console.log(key);
 
// 转换Set为Array (with Array comprehensions)
var myArr = [v for (v of mySet)]; // [1, "some text"]
// 替代方案(with Array.from)
var myArr = Array.from(mySet); // [1, "some text"]
 
// 如果在HTML文档中工作,也可以:
mySet.add(document.body);
mySet.has(document.querySelector("body")); // true
 
// Set和Array互换
mySet2 = new Set([1,2,3,4]);
mySet2.size; // 4
[...mySet2]; // [1,2,3,4]
 
// 用forEach迭代
mySet.forEach(function(value) {
  console.log(value);
});

Set 与 Array 的联系

var myArray = ["value1", "value2", "value3"];
 
// 用Set构造器将Array转换为Set
var mySet = new Set(myArray);
 
mySet.has("value1"); // returns true
 
// 用...(展开操作符)操作符将Set转换为Array
console.log([...mySet]); // 与myArray完全一致

应用场景:Set对象数组去重

var arr=[3, 62, 3, 38, 20, 42, 14, 5, 38, 29, 42];
console.log(new Set(arr))

可以封装一个函数

function uniqueArray(arr){
    return Array.from(new Set(arr));
}

用这个函数可以数组去重。
或者如下写也可以,比较简单的数组去重

[...new Set([1,3,4,5,1,2,3,3,4,8,90,3,0,5,4,0])]

10.2 Map 对象
Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。

Map方法

var myMap = new Map();
myMap.set("bar", "baz");
myMap.set(1, "foo");
 
myMap.size;       // 2
myMap.has("bar"); // true
 
myMap.clear();
 
myMap.size;       // 0
myMap.has("bar")  // false

九 . Proxy (代理器)

简介:Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

var obj = new Proxy({}, {
	get: function (target, key, receiver) {
		console.log(`getting ${key}!`);
		return Reflect.get(target, key, receiver);
	},
	set: function (target, key, value, receiver) {
		console.log(`setting ${key}!`);
		return Reflect.set(target, key, value, receiver);
	}
});

上面代码对一个空对象架设了一层拦截,重定义了属性的读取(get)和设置(set)行为。这里暂时先不解释具体的语法,只看运行结果。对设置了拦截行为的对象obj,去读写它的属性,就会得到下面的结果。

obj.count = 1
// setting count!
++obj.count
// getting count!
// setting count!
// 2

上面代码说明,Proxy 实际上重载(overload)了点运算符,即用自己的定义覆盖了语言的原始定义。
ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。

十 class

使用构造函数创建对象:

function Point(x, y)
{
    this.x = x;
    this.y = y;
    this.add = function()
    {
        return this.x + this.y;
    };
}
var p = new Point(1, 2);
console.log(p.add()); // 输出3

使用Class定义类,更加规范,且你能够继承:

class Point
{
    constructor(x, y)
    {
        this.x = x;
        this.y = y;
    }

    add()
    {
        return this.x + this.y;
    }
}

var p = new Point(1, 2);

console.log(p.add()); // 输出3

学习重点 class, extends

class Animal {
    //constructor 方法,这就是构造方法
     constructor(){
         this.type = '赵伟'  //this关键字代表当前实例对象,
     };
     says(say){
         console.log(this.type + ' 说 ' + say)
     }
 }
 
 let demo = new Animal()

 demo.says('你好呀!');
 
 class ceshi extends Animal {   
     //entends关键字实现继承,就是继承父集animal类的所有属性和方法
     constructor(){
         super();
         //这是子类在继承父类的时候必用调用的方法,而且必须是在构造方法中调用,
         //super()指代的是父类的实例,也就是上面父类的this对象。这样才能进行this属性的修改。
         this.type = 'cat'
     }
 }
 let cat = new ceshi()

 ceshi.says('hello') //cat says hello

十一 模块化
简介:历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的require、Python 的import,甚至就连 CSS 都有@import,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。

ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。

1.export 命令
模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

//写法1
// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

//写法2
// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export { firstName, lastName, year };

export命令除了输出变量,还可以输出函数或类(class)。

export function multiply(x, y) {
  return x * y;
};

1.2 import 命令

// main.js
import { firstName, lastName, year } from './profile.js';

function setName(element) {
  element.textContent = firstName + ' ' + lastName;
}

2.export default 命令
为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值