ES6学习笔记

ES6语法的一个特性

块级作用域:
{

}

LET命令

  1. LET声明的变量具有块级作用域的概念
    1
    2
    3
    4
    5
    6
    7
    8
    {
    console.log(typeof a)//Uncaught ReferenceError: Cannot access 'a' before initialization
    let a = 42;
    var b = 1212;
    console.log(typeof a) //number

    }
    console.log(typeof a) //underfind
  1. 不存在变量提升。在Let声明之前使用就会报错
  2. 暂时性死区:只要块级作用域内存在let命令,它所在的变量就“绑定”这个区域,不再受外部的影响
  3. 不允许重复声明

    注意:因为let的不存在变量提升和暂时性死区,因此在let之前使用该变量会报错,在此变量作用域外使用会无效。

const命令

1. const声明一个只读常量,一旦声明,常量的值就不能更改
2. const变量只声明不赋值就会报错
3. 只在作用域内生效以及不允许重复声明
4. const变量不能更改的实质是变量指向的那个内存地址所保存的数据不得改动.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 const foo = {};
foo.prop = 123;//添加一个属性,没有问题
console.log(foo.prop)
foo= 123;//就会报错


// 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }

(function () {
if (false) {
// 重复声明一次函数f
function f() { console.log('I am inside!'); }
}
f();
}());
//上面在ES6代码当中会报错,ES6规定,浏览器始兴县要遵循一些规定
//1.允许在块级作用于内声明函数
//2.函数声明类似于var ,即会提升到全局作用于函数作用于的头部
//3.同时,函数声明还会提升到所在的块级作用于的头部

注意:以上三条规则只对ES6浏览器内有效,其他环境还是将块级作用于的函数声明当做let处理

注意:在ES6中一共有6种赋值的方式,有var 和 function 命令,还有let 和const命令,以及import和class命令。var 和 function 命令声明的全局变量是顶层对象的属性;let、const和class命令声明全局变量,不属于顶层对象的属性。

变量的解构赋值

  1. 数组的解构赋值
  2. 概念:ES6允许按照一定的模式,从数组和对象中提取,对变量进行赋值
    注意:要是被赋值一边有一项没有被赋值或者赋值underfind,则被称为解构失败;要是赋值一边有三个值,被赋值一边只有两个变量,则被称为不完全解构
  3. 匹配模式其实是懒散匹配,如第6行代码,如果赋值一方对应位置有值,x就不会管默认值是10,而当赋值一边【】啥都没有的时候,才取默认值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    //模式匹配
    let [a , b, c] = [1, 2, 3]

    let [a ,[b,[c]]] = [1,[2,[3]]]

    let [x = 10] =[20] //x = 20

    对象的解构赋值
    无序性:只要变量与属性同名,就能取到正确的值。当右边没有同名的属性,那么不叫取不到值而取得underfind
    let {bar ,foo } = {foo :234, bar:123}
    //无论赋值的一方的顺序是怎么样的,赋值都不影响

    let {foo:bar} = {foo:123}
    console.log(bar);//123
    console.log(foo);// foo is not defined

    let{length} = "123" //length = 3

    //可用于嵌套
    let obj = {
    p: [
    'abcabc',
    { y: '123123' }
    ]
    };

    let { p, p: [x, { y }] } = obj;//'abcabc' '123123'

    字符串的解构赋值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    const [a,b,c,d,e] = 'hello';

    console.log(a);
    console.log(b);
    console.log(d);

    let{ length :len} = 'hello'
    console.log(len)
    // a b l 5

数值和布尔值的解构赋值

1
2
3
4
5
6
7
解构赋值时,如果等号右边是数值和布尔值,则会先转换成对象
函数参数的解构赋值
function add([x,y]){
return x + y;
}

add([1,2])

不能使用圆括号的情况:
使用场景:

  1. 交换变量的值
  2. 从函数返回多个值
1
2
3
4
5
6
function example(){
return [1,2,3];
}
let [a,b,c] = example();

console.log(a,b,c) //1 2 3
  1. 提取JSON数据–解构赋值对提取JSON对象中的数据,尤其有用

便利Map结构:
部署了Iterator接口的对象,都可以用for…of循环遍历。配合变量的解构赋值,获取键名和键值就肥肠方便

字符串的扩展

  1. 字符串的遍历器接口

    1
    2
    3
    4
    5
    6
    a = `hzfnb`;

    for(let condePoint of a ){
    console.log(condePoint)
    }
    // h z f n b
  2. 模板字符串

  3. 增强字符串:可以保留字符串在编辑器的模式 ,如果代码中的模板字符串都要用反引号表示,则前面需要用反斜杠转义

  4. 在字符串中添加变量(表达式)

    赋值

  5. ${}对变量进行抓取

  6. ${} 对变量进行运算

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    var str = 'hello';
    var newStr = `hello world`;

    var xm = {
    age :19,
    height:180,
    name :'xiaoming'
    }

    var {age ,name, height} = xm;

    var newstr =`name: ${name} age: ${age} `
    console.log(newstr);//通过对象的解构拿到对象的值, 再通过${}直接取得这个值
    //${}也是可以进行运算的,还可以添加方法

    var x = 3, y = 5;
    function getName(){
    return 'xiaoming';
    }
    var str = `my name is ${getName()}`;
    console.log(str);



    var arr = [1,2,3,4,5];
    var resStr =`${arr.map(function(item,index){
    return `${item}: ${index}`
    })}`//通过增强字符串与函数把值赋给另外一个变量(对象)

标签模板

  1. 它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串
    标签模板的实质,函数调用的特殊形式
    重要应用,过滤HTML字符串–防止用户恶意注意内容
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    safeHtml `<p>${name} Welcome</p>`

    function safeHtml(data){
    var str = data[0]
    for(let i = 1; i<arguments.length;i++){
    var arg = String(arguments[i])

    str += arg.replace(/&/g,'&').replace('/</')
    }
    }

字符串的新增方法

1
2
3
4
5
6
7
8
String.fromCodePoint() --用于从Unicode编码返回对应的字符串
String.raw() --用于转义字符串,往往用于模板字符串的处理方法
a = String.raw`hi\n\n${5}!`
console.log(a); //hi\n\n5!

//String.raw 作为正常的函数使用
a = String.raw({raw:'hzfnb'},0,1,2)
console.log(a); //h0z1f2nb
  1. 实例方法:codePointAt() –测试一个字符由两字节还是四个字节组成的最简单方法
  2. 实例方法:normailza()
  3. includes(): 返回布尔值,表示是否找到了参数字符串
  4. startsWith() : 返回布尔值,表示参数字符串是否在原字符串的头部
  5. endWith(): 返回布尔值,表示参数字符串是否在原字符串尾部
    1
    2
    3
    4
    5
    6
    var a = "hzfnb zf"
    var r1 = a.includes('hzfnb')
    var r2 = a.startsWith('h')
    var r3 = a.endsWith('f')

    console.log(r1,r2,r3)//true true true
  6. 实例方法: repeat()返回一个新的字符串,并将原字符串重复N次
  7. 实例方法:padStart() padEnd():接受两个参数,第一个参数是字符串补全的位数,第二个填的是要补全的字符串
    1
    2
    3
    padStart() 用于补全头部
    padEnd() 用于补全尾部
    console.log('hzf'.padStart(5,'nb')) //hzfnb
  8. 实例方法:trimStart() , trimEnd();
    分别用于消除字符串最前面的空格以及最后面的空格
  9. 实例方法:matchAll()
    方法返回一个正则表达式在当前字符串的所有匹配

正则表达式的扩展

字符串的正则方法

  1. match()
  2. replace()
  3. search()
  4. split()
  5. u修饰符:含义为unicode模式,用来处理四个字节的UTF-16编码
  6. 点字符
  7. i修饰符
  8. y修饰符

函数的扩展

函数的默认值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
function Persion(name ,age = 100){
console.log(name,age)
}
Persion('hs'); // hs 100
Persion('hs',12); // hs 12

默认值与解构赋值的使用
function f1( {x = 0, y = 0} ={}){
console.log(x,y)
}

function f2({x,y} = {x:0,y:0}){
console.log(x,y)
}

f1()
f2()
f1({x:1,y:2})
f2({x:1,y:2})
f1({x:1})
f2({x:1})

//0 0
//0 0
//1 2
//1 2
//1 0
//1 undefined 最后一个解构赋值之后表示为 {x:1} 所以y = underfined

参数作用域已经注意事项
在函数体内用let定义的变量,不能提前当做参数(放在括号内)
es6在参数默认值方面是使用let来定义的
REST
var arr = [1,2,3,4,5];
fn.call(null,...arr) //...相当于把括号去掉
fn.apply(null,arr) //apply 要用数组的形式引入

// (5) [1, 2, 3, 4, 5]
// (5) [1, 2, 3, 4, 5]

function fn(...args){
console.log(args)
}

箭头函数

注意事项:箭头函数里面没有this这个对象,它只会依次找到父级,也没有arguments

1
2
3
4
5
6
7
8
9
10
11
var f =            ()   =>   num
var f = function 参数 return 参数

//箭头函数的嵌套
function fn(str){
return function(){
return str.splite(``)
}
}

var fn = str => () =>str.splite(``)

数组的扩展

数组的合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var arr = ['dy1']
var arr1 = ['1,2,3,4,5']
var arr2 = ['false',NaN]
var newArr = [...arr,...arr1,...arr2]
console.log(newArr)//["dy1", "1,2,3,4,5", "false", NaN]

var arr3 = [...'hzf']
console.log(arr3);//["h", "z", "f"]

Array.from()
把类数组和可遍历的对象转换成数组
Array.of()
数组实例的方法copyWithin()
var arr = [1,2,3,4,5]
// Array.prototype.copyWithin(target ,start = 0,end = this.length))
console.log (arr.copyWithin(0,3))
// 0 3 还有一位end没写出来,0代表从第0位开始,3代表start=3, 第三位是4 end 没写表示到一直最后,
//表示从4,5替换掉从0开始的两位 因此结果 = 4,5,3,4,5

数组实例方法

fill() , entries(),keys() values()

  1. entries() 是对键值对的遍历
  2. values() 是对键值的遍历
  3. key() 是对键名的遍历
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    var arr = [1,2,3,4,5]
    var a = arr.keys()
    console.log(a) //Array Iterator {}

    var arr1 = new Array(5);
    arr1.fill(7,3,4)
    console.log(arr1) //(5) [empty x 3 ,7 empty x 3]
    //fill的用法是添加某个数,用法跟copywithin()差不多,
    //添加7这个数字,在第3跟第4个数之间插入数字7

    var arr2 = ['2',2,3,4,5]
    var a = arr2.keys()

    for([item, index] of arr.entries())
    {
    console.log(item ,index)
    }
    //entries 可以用于遍历数组,列出是第几位的并且把值打印出来
    // 0 "2"
    // 1 2
    // 2 3

数组的实例方法

includes() find() findIndex()

  1. includes() ——返回一个布尔值,表示某个数组是否包含给定的值。如果包含则返回true,否则返回false
  2. find() ——找到第一个符合条件的数组成员
  3. findIndex() 返回第一个负荷而条件的数组成员的位置
    1
    2
    3
    var arr = [20 , 4, -5, 10]
    var str = [arr.find((n) => n <19)]
    console.log(str) //[4]

对象的扩展

1
2
3
属性的简洁表示法
var foo = '123'
var bar = {foo}
属性的可枚举性以及属性的遍历
  1. 对象的每个属性都有一个遍历对象(Descriptor)用来控制该属性的行为
    1
    2
    3
    4
    var obj = {age :123,name:'dv'}

    console.log(Object.getOwnPropertyDescriptor(Object.prototype,'toString'))
    //enumerable: false 说明不可枚举

    但是有4种操作会忽略enumerable 为flase的属性

    1. for… in 循环:遍历对象自身的和继承的可枚举属性
    2. object.keys() 返回对象自身的所有可枚举的属性的键名
    3. JSON.stringify() 只串行话独享自身的可枚举属性
    4. object.assign() (ES6新增)

对象的新增方法

  1. Object.is()

ES5判断两个值知否相等只有 == 和 ===。它们的缺点在于, == 回自动转换数据类型, === 会使得Nan不等于自身,-0 不等于 +0

1
2
3
object.is()
console.log (Object.is(-0,+0)) //false
console.log (Object.is(NaN,NaN)) //true

Class类

class 一定要先定义再使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        class Person{
constructor( name='zf',age = 18){
this.name = name
this.age = age
} //这里不能写 ',' 写了就报错
show(){
console.log(this.age,this.name)
}
}

var per = new Person()
// per.name 表示实例属性

立即执行class
var p = new class{ //这个类只能使用一次
}

this指向

=> 指向父级作用域,跟ES5里面的this指向有些不同

静态方法

静态属性

继承

与es5的不同之处

  1. 子类 proto表示构造函数的继承
  2. 子类 proto.prototype 表示方法的继承
  3. 注意:proto并不属实语言本身的特征,目前很多浏览器的JS引擎都提供了这个私有属性,但依旧不建议在生产中使用该属性,避免对环境产生依赖。生产环境中,推荐使用Object.getPrototypeof()来获取实例对象的原型,再为原型添加属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class A{
constructor(){
this.name = 'zf'
}
print(){
console.log(this.name)//console.log('father A')
}
}
class B extends A{
constructor(){
super() //为啥要调用super?
//子类要调用super方法,才能使用this,给父级绑定才有this
this.name = 'aasda'
}
print(){
super.print() //b.print() -> father A
}
}

var b = new B()
// b.name = 'aasda'
// b.print() aasda

Promise对象

Promise的含义:简单来说就是一个容器,里面保存着某个未来才会结束的事件(通常来说是一个异步操作。)

  1. 基本用法
  2. 三种状态
    1. pending 就绪状态
    2. resolved 成功状态
    3. rejected 失败状态
      1
      2
      实例方法
      Promise.all Promise.race

评论