ES6学习笔记

Posted 糖goblin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6学习笔记相关的知识,希望对你有一定的参考价值。

1、ES6

1.1、什么是ES6

编程语言javascript是ECMAScript的实现和扩展 。ECMAScript是由ECMA(一个类似W3C的标准组织)参与进行标准化的语法规范。ECMAScript定义了:

语言语法 – 语法解析规则、关键字、语句、声明、运算符等。

类型 – 布尔型、数字、字符串、对象等。

原型和继承

内建对象和函数的标准库JSONMath数组方法对象自省方法等。

ECMAScript标准不定义html或CSS的相关功能,也不定义类似DOM(文档对象模型)的Web API,这些都在独立的标准中进行定义。ECMAScript涵盖了各种环境中JS的使用场景,无论是浏览器环境还是类似node.js的非浏览器环境。

ECMAScript标准的历史版本分别是1、2、3、5。

那么为什么没有第4版?其实,在过去确实曾计划发布提出巨量新特性的第4版,但最终却因想法太过激进而惨遭废除(这一版标准中曾经有一个极其复杂的支持泛型和类型推断的内建静态类型系统)。

ES4饱受争议,当标准委员会最终停止开发ES4时,其成员同意发布一个相对谦和的ES5版本,随后继续制定一些更具实质性的新特性。这一明确的协商协议最终命名为“Harmony”,因此,ES5规范中包含这样两句话

ECMAScript是一门充满活力的语言,并在不断进化中。

未来版本的规范中将持续进行重要的技术改进

2009年发布的改进版本ES5,引入了Object.create()Object.defineProperty()getterssetters严格模式以及JSON对象。

ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,2015年6月正式发布。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

1.2、语法新特性

1.2.1、新的变量声明

  1. 我们都是知道在ES6以前,var关键字声明变量。无论声明在何处,都会被视为声明在函数的最顶部(不在函数内即在全局作用域的最顶部)。这就是函数变量提升,例如:
function aa() {
    if(bool) {
        var test = \'hello man\'
        } else {
            console.log(test)
        }
}
  • 以上的代码实际上是:
function aa() {
    var test // 变量提升
    if(bool) {
        test = \'hello man\'
    } else {
        //此处访问test 值为undefined
        console.log(test)
    }
    //此处访问test 值为undefined
}
  • 所以不用关心bool是否为true or false。实际上,无论如何test都会被创建声明。
  1. 我们通常用let和const来声明,let表示变量、const表示常量。let和const都是块级作用域。怎么理解这个块级作用域?在一个函数内部 ,在一个代码块内部。看以下代码
function aa() {
    if(bool) {
        let test = \'hello man\'
        } else {
            //test 在此处访问不到
            console.log(test)
        }
}
  1. const 用于声明常量,看以下代码
const name = \'lux\'
name = \'joe\' 	//再次赋值此时会报错

Assignment to constant variable:对常量变量的赋值

1.2.2、模板字符串

  1. es6模板字符简直是开发者的福音啊,解决了ES5在字符串功能上的痛点。

    第一个用途,基本的字符串格式化。将表达式嵌入字符串中进行拼接。用${}来界定。

//es5 
var name = \'lux\'
console.log(\'hello\' + name)
//es6
const name = \'lux\'
console.log(`hello ${name}`) //hello lux
  1. 第二个用途,在ES5时我们通过反斜杠(\\)来做多行字符串或者字符串一行行拼接。ES6反引号(``)直接搞定。
// es5
var msg = "Hi \\
man!"
// es6
const template = `<div>
<span>hello world</span>
</div>`

1.2.3、函数默认参数

  1. ES6为参数提供了默认值。在定义函数时便初始化了这个参数,以便在参数没有被传递进去时使用。
  2. 看例子代码
function action(num = 200) {
    console.log(num)
}
action() //200
action(300) //300

1.2.4、箭头函数

ES6很有意思的一部分就是函数的快捷写法。也就是箭头函数。

箭头函数最直观的三个特点。

  • 不需要function关键字来创建函数
  • 省略return关键字
  • 继承当前上下文的 this 关键字

1、基本函数

function funcName(params) {
    return params + 2;
}
funcName(2);

2、使用箭头函数

var funcName = (params) => params + 2
funcName(2)

3、箭头函数基本语法

(parameters) => { statements }
  • 如果没有参数,那么可以进一步简化:
() => { statements }
  • 如果只有一个参数,可以省略括号:
parameters => { statements }
  • 如果返回值仅仅只有一个表达式(expression), 还可以省略大括号:
parameters => expression
 
// 等价于:
function (parameters){
  return expression;
}

例如:

var double = num => num * 2
double(2);
double(3);

4、没有局部this的绑定,和一般的函数不同,箭头函数不会绑定this。 或则说箭头函数不会改变this本来的绑定。

4.1、我们用一个例子来说明:

function Count() {
  this.num = 0;
}
var a = new Count();

4.2、因为使用了关键字new构造,Count()函数中的this绑定到一个新的对象,并且赋值给a。通过console.log打印a.num,会输出0。

console.log(a.num);

4.3、我们来看一下输出结果:如果我们想每过一秒将a.num的值加1,该如何实现呢?可以使用setInterval()函数。

function Count() {
  this.num = 0;
  this.timer = setInterval(function add() {
    this.num++;
    console.log(this.num);
  }, 1000);
}
var b = new Count();

4.4、你会发现,每隔一秒都会有一个NaN打印出来,而不是累加的数字。到底哪里错了呢? 实际上setInterval里面的this绑定到全局对象的。我们可以通过将this打印出来验证这一点:

function Count() {
    this.num = 100;
    setTimeout(function add(){
        this.num++;
        console.log(this);
    },1000)
}
var a = new Count();
console.log(a.num)
  • 回到之前的函数,之所以打印NaN,是因为this.num绑定到window对象的num,而window.num未定义。

4.5、那么,我们如何解决这个问题呢?使用箭头函数!使用箭头函数就不会导致this被绑定到全局对象。

function Count(){
    this.num = 100;
    setInterval(()=>{
        this.num++
        console.log(this.num);
    },1000)
}
var a = new Count();
console.log(a.num)
  • 通过Count构造函数绑定的this将会被保留。在setInterval函数中,this依然指向我们新创建的b对象。

4.6、为了验证刚刚的说法,我们可以将 Count函数中的this绑定到that, 然后在setInterval中判断this和that是否相同。

function Counter() {
  var that = this;
  this.timer = setInterval(() => {
    console.log(this === that);
  }, 1000);
}
var b = new Counter();
  • 总结正如我们期望的,打印值每次都是true。最后,结束刷屏的打印:

5、箭头函数写代码拥有更加简洁的语法;不会绑定this。

1.2.5、对象初始化简写

  1. ES5我们对于对象都是以键值对的形式书写,是有可能出现键值对重名的。例如
function people(name, age) {
    return {
        name: name,
        age: age
    };
}
  1. 以上代码可以简写为
function people(name, age) {
    return {
        name,
        age
    };
}

1.2.6、解构

  1. 数组和对象是JS中最常用也是最重要表示形式。为了简化提取信息,ES6新增了解构,这是将一个数据结构分解为更小的部分的过程
  2. ES5我们提取对象中的信息形式如下
const people = {
    name: \'lux\',
    age: 20
}
const name = people.name
const age = people.age
console.log(name + \' --- \' + age)
  1. 是不是觉得很熟悉,没错,在ES6之前我们就是这样获取对象信息的,一个一个获取。现在,ES6的解构能让我们从对象或者数组里取出数据存为变量,例如
//对象
const people = {
    name: \'lux\',
    age: 20
}
const { name, age } = people
console.log(`${name} --- ${age}`)
//数组
const color = [\'red\', \'blue\']
const [first, second] = color
console.log(first) //\'red\'
console.log(second) //\'blue\'

1.2.7、Spread Operator

ES6中另外一个好玩的特性就是Spread Operator 也是三个点儿...接下来就展示一下它的用途。 组装对象或者数组

//数组
const color = [\'red\', \'yellow\']
const colorful = [...color, \'green\', \'pink\']
console.log(colorful) //[red, yellow, green, pink]

//对象
const alp = { fist: \'a\', second: \'b\'}
const alphabets = { ...alp, third: \'c\' }
console.log(alphabets) //{ "fist": "a", "second": "b", "third": "c"

1.2.8、import 和 export

  1. import导入模块、export导出模块
  2. 创建文件lib.js
let fn0=function(){
    console.log(\'fn0...\');
}
export {fn0}
  1. 创建文件demo9.js
import {fn0} from \'./lib\'
fn0();
  1. 注意:node(v8.x)本身并不支持import关键字,所以我们需要使用babel的命令行工具来执行
babel-node demo9
  1. 使用export default 导出一个对象

    Exports.obj={}

export default {
    a:20,
    say(){
        console.log(this.a);
    } 
};
  1. 导入的名字可以自定义

    Let obj = require(“./vue”);

import v from \'./vue\'
v.say();

1.2.9、Array.some()

  1. some()方法测试数组中的某个元素是否通过了由提供的函数实现的测试。
  2. 语法
array.some(callback[, thisObject]);
  • callback - 测试每个元素的函数。

  • thisObject - 执行回调时用作此对象的对象。

  • 如果某个元素通过了测试,则返回true,否则返回false。

  1. 案例
function isBigEnough(element, index, array) {
    return (element >= 10);
}
var retval = [2, 5, 8, 1, 4].some(isBigEnough);
console.log("Returned value is : " + retval );

var retval = [12, 5, 8, 1, 4].some(isBigEnough);
console.log("Returned value is : " + retval );

1.2.10、Array.includes()

  1. Array.includes()判断是否包含某一元素,它直接返回true或者false表示是否包含某一元素,对NaN一样有效
  2. 语法
str.includes(searchString[, position])
  • searchString - 要搜索的子字符串。

  • Position - 此字符串中开始搜索searchString的位置; 默认为0。

  • 如果字符串包含子字符串,则为true ; 否则,假。

  1. 案例
let arr1 = [\'a\', \'b\', \'c\', \'d\', \'e\', \'f\', \'g\', \'h\', \'i\', \'j\', \'k\', NaN]
arr1.includes(\'c\')    // true
arr1.includes(\'z\')    // false
arr1.includes(NaN)    // true
//includes()函数的第二个参数表示判断的起始位置
arr1.includes(\'d\', 1)    // true
arr1.includes(\'d\', 3)    // true
arr1.includes(\'d\', 4)    // false
//第二个参数也可以是负数,表示从右数过来第几个,但是不改变判断搜索的方向,搜索方向还是从左到右
arr1.includes(\'k\', -1)    // false
arr1.includes(\'k\', -2)    // true
arr1.includes(\'i\', -3)    // false

以上是关于ES6学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记:python3,代码片段(2017)

es6学习笔记1

学习笔记ES6标准入门

JavaScript学习笔记 -- ES6学习 let 和const

Es6学习笔记

ES6学习笔记九:修饰器