ES6新特性(1)

目录

1.let ,var ,const

 let 特点

cosnt 特点

2.解构赋值

3.模板字符串

4.对象的简化写法

5.箭头函数

6.函数默认参数值

7. rest 参数

8.扩展运算符

9.迭代器 

 10.生成器

(1)生成器的声明与调用

 (2)生成器的函数参数


1.let ,var ,const

 let 特点

1.变量不能重复声明   

这种是不被允许的

let a = 5
let a = 6

2.块级作用域

存在3种作用域,全局作用域,函数作用域,eval作用域(在ES5的模式下)

什么是块级作用域呢?  是指只在代码块级内产生作用,出了作用域则不起作用

//比如 let 使用这种写法,则会报错
{
    let a = 666
}
console.log(a)
//而对于 var 的使用, 则不会报错
{
    var a = 2
}
console.log(a)

例如 for 循环

//使用 let 声明则会输出 0~9
for (let i = 0; i < 10; i++) {
    console.log(i)
}
//而使用 var 声明则会输出10个10
for (var i = 0; i < 10; i++) {
    console.log(i)
}

3.不存在变量提升

变量提升:在代码编译之前就已经声明了变量, 而var 可以存在变量提升

例如这样:

console.log(a);
var a = 999

控制台输出结果是undefined 

则相当于在执行前就已经声明了变量 a

var a;
console.log(a);
var a = 999

而 let 不存在变量提升

console.log(a);
let a = 999

 控制台则直接发生报错

4.不影响作用域链

函数fun 作用域不存在变量 a ,则向上一级查找变量a = 6

{
    let a = 6;
    function fun () {
        console.log(a)
    }
}

cosnt 特点

1. 声明常量一定要赋初值

const A = 6

2. 声明一般使用大写

当然小写也是可以的,但大写规范性更好

3.常量的值不允许改变

即前面已经声明了A = 6, 后面不允许再改变它的值

A = 666

4.块级作用域(见上面解释)

5.对于数组和对象的元素的修改,不算对常量的修改,不会发生报错

//这种修改没有问题
const arr = [1, 2, 3, 4, 5]
arr.push(6)
console.log(arr);
//这种则会报错
const arr = [1, 2, 3, 4, 5]
arr = [1, 2, 3]

为什么呢?

这是因为数组和对象事属于引用类型,它们存储的时候保存的是指针地址,所以说当我们修改里面的元素时并没有改变其指针的地址,所以修改是合法的

2.解构赋值

什么是解构赋值?

它是允许按照一定的模式从数组或者对象中提取值,对变量进行赋值,并且在 js 中使用  [ ], { }  提取其中的值

//数组的解构赋值
const arr = [1, 2, 3, 4, 5]
let [a, b, c, d, e] = arr
console.log(a);
console.log(b);
console.log(c);

//对象的解构赋值
const my = {
    name: 'yy',
    age: 18,
    hobby: function() {
        console.log("睡懒觉");
    }
}
let {name, age, hobby} = my
console.log(name);
console.log(age);
hobby();

3.模板字符串

模板字符串是增强版的字符串,使用反引号( ` `  )包裹字符串,并且在字符串中可以使用( ${  } )嵌套变量或者表达式

//1.声明
let hobby = `我喜欢睡懒觉`
//2.允许出现换行符
let str =  `
    <ul>
        <li>臭豆腐</li>
        <li>臭豆腐2</li>
        <li>臭豆腐3</li>
    </ul>`;
//3.变量嵌入
let name = `yy`
let my = `我的名字是${name}`
console.log(my);

4.对象的简化写法

在es6中,可以使用更简洁的方式,在大括号中直接去写变量和函数,最为对象的属性和方法,写方法时也可以去掉  :function

let name = 'laoliu'
let age = function () {
    console.log('我的年龄是'+18);
}

const my = {
    name,
    age,
    hobby() {
        console.log('我喜欢睡大觉');
    }

    //hobby:function() {
    //    console.log('我喜欢睡大觉');
    //}
} 

5.箭头函数

在 es6 中引入了  =>  来定义函数,省去了关键字 function 用法如下

//函数的声明
let fn = function() {
    console.log('aaa');
}

let fun = (a, b) => {
    console.log('bbb');
}
//调用函数
fn()
fun()

1.this 的指向问题

箭头函数中的 this 是静态的, 它始终指向函数声明时所在作用域下的 this 的值

举个栗子~

function fun() {
    console.log(this.hobby);
}
const fun2 = ()=> {
    console.log(this.hobby);
}
//设置window 对象的 hobby 属性
window.hobby = '睡大觉'
const my = {
    hobby: '吃螺蛳粉'
}

//直接调用
fun()
fun2()

//call 函数主要改变 this 的指向对象
fun.call(my)
fun2.call(my)

我们首先声明好函数和属性,然后直接调用函数,打印发现他们的 this 指向都是 window ,然后再利用call 函数改变两个函数的 this  的指向,打印发现 fun1 的 this 指向了 my , 而 fun2 的 this 依然指向的是 window

2.不能作为构造函数实例化对象

这种写法是错误的,控制台报  “Per is not a constructor”  错误

let Per = (name, age) => {
    this.name = name;
    this.age = age;
}
let my = new Per('yy', '18')
console.log(my);

3.不能使用 arguments 变量

//错误使用,控制台报错 arguments 未定义
let fn = () => {
    console.log(arguments);
}
fn();

4.箭头函数的简写

(1) 省略小括号

当形参只有一个时

let fn = n => {
    return n++;
}

(2) 省略花括号

当代码体只有一条语句时,可以省略花括号,并且需要省略 return ,其中语句的执行结果就是函数的返回值

let fn = (n) => {
    return n++;
}
//简写形式
let fn = (n) => n++:

总结一下~

箭头函数适合与 this 无关的回调,比如定时器,数组方法的回调,不适合与 this 有关的回调,比如事件和对象的方法 

6.函数默认参数值

在es6中允许给默认函数参数初始值

栗子~

1.形参默认初始值,具有默认的参数,一般要靠后写

//如果我们给a, b, c 都赋予值, 则参数c为输入的值
function fun(a, b, c = 6) {
    return a + b + c;
}
console.log(fun(1, 2, 3));

//如果我们没有给 c赋予值,则c 默认值是6
function fun(a, b, c = 6) {
    return a + b + c;
}
console.log(fun(1, 2, 3));

//这种输入是不合理的,1和2并不会直接给参数a, b 赋上值,
//而是会直接把 c 的值覆盖掉,控制台的输出结果为NaN
function fun(a, c = 6, b) {
    return a + b + c;
}
console.log(fun(1, 2));

2.还可以与解构赋值结合

//如果不使用这种方法,就会写多个param,比较麻烦
function connect(param) {
    console.log(param.host);
    console.log(param.username);
    console.log(param.password);
    console.log(param.port);
}


//而这种与解构赋值结合的方法方便很多
function connect({host, username, password, port}) {
    console.log(host);
    console.log(username);
    console.log(password);
    console.log(port);
}

//当然也可以采用默认值的方式,如果host 不输入则采用参数的默认值
function connect({host="127.0.0.1", username, password, port}) {
    console.log(host);
    console.log(username);
    console.log(password);
    console.log(port);
}

//输入值
connect({
    host: 'localhost',
    username: 'root',
    password: 'root',
    port: 3306
})

7. rest 参数

在es6 中引入了 rest 参数,用于获取函数的实参,用来代替 arguments

那我们先来简单了解一下arguments 参数~

arguments 是一种类数组对象,代表传给参数的 function 列表,它包含 length 属性来获取传入参数的个数,而其他数组有的方法arguments 都没有,所以为了使用数组的方法,必须使用 Array.prototype.slice.call 先将其转为数组

function fun() {
    console.log(arguments);
}
fun('熊大', '熊二')

arguments 控制台输出的是一个对象

对于 rest 参数就有很大的优势了

先来解释下rest 参数,它是用于获取多余的参数,rest  参数对应的是数组,该变量将多余的参数放在数组中。

求几个数的和:

function fun(...args) {
    let sum = 0;
    for( var e of args) {
        sum+=e
    }
    return sum;
}
console.log(fun(1, 2, 3));

对于resr 参数特别需要注意:...argu 必须放到最后面

function fun(a, b, ...argu) {
    console.log(a);
    console.log(b);
    console.log(...argu);
}
fun(1, 2, 3, 4, 5, 6)

控制台输出的结果是1, 2, 3456,也就是1给了a, 2给了b, 3456给了...argu ,如果改变参数的顺序就会混乱 

8.扩展运算符

什么是扩展运算符呢?

扩展运算符(...),是es6的新语法,可以将数组转化为丢逗号分隔的参数序列

举个栗子~

//这种方式打印出来的是一个值,也就是输入的数组
const arr = ['a', 'b', 'c']
function fun() {
    console.log(arguments);
}
fun(arr)


//而使用拓展运算符的形式打印出来的是三个值a, b, c
const arr = ['a', 'b', 'c']
function fun() {
    console.log(arguments);
}
fun(...arr)

那我们可以怎样使用呢?

1.数组的合并 

const arr1 = ['a', 'b', 'c']
const arr2 = [1, 2, 3]
const arr3 = [...arr1, ...arr2]    //arr3就是合并后的数组
console.log(arr3);

2.数组的克隆

const arr1 = ['a', 'b', 'c']
const arr4 = [...arr1]    //克隆后的数组
console.log(arr4);

3.将伪数组转化为真正的数组

伪数组:可以理解为类似数组的集合,他们和数组一样有索引和length 但是没有一些数组特有的方法,比如arguments,DOM的children 元素

举个栗子~

const divs = document.querySelectorAll('div');    //获取div 数组
const divArr = [...divs];   //转化为真正的数组
console.log(divArr);

9.Symbol 数据类型

 在es6中引入了一种新的原始数据类型Symbol ,表示独一无二的值,是JavaScript 语言的第七种数据类型,类似于字符串的数据类型。

Symbol 的几个特点:

(1) Symbol 的值是唯一的,用来解决命名冲突的问题

(2)不能与其他数据进行运算

(3)Symbol 定义的对象属性不能使用 for...in 循环遍历,但是可以使用  Reflect.ownkeys  来获取对象的所有键名

let sym = Symbol()    //创建Symbol
let res = sym + 100
console.log(res);

9.迭代器 

迭代器(Iterator)是一种接口, 为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator接口,就可以完成遍历操作。

在es6中创造了一种新的遍历命令 for...of  循环,Iterator 接口主要提供for...of

原生具有 Iterator  接口的数据(可以使用for ... of 遍历):Array, Arguments, Set, Map,  String, TypedArray, NodeList

那么迭代器是如何工作的呢?

首先创建一个指针对象,指向当前数据结构的其实位置,第一次调用对象的next 方法,指针自动指向数据结构的第一个成员,接下来不断地调用 next 方法,指针一直往后移动,直到指向最后一个成员,每调用 next 方法就会返回一个包含 value 和 done 属性的对象。

  • value 表示可迭代对象的下一个值
  • done 表示的是是否已经全部取出所有的数据,false表示的是还有数据未取出,true 表示的是已经全部取出shun
let arr = ['阿呆1号', '阿呆2号', '阿呆3号', '阿呆4号']
let iterator = arr[Symbol.iterator]()   //生成迭代器
console.log(iterator.next());   //输出 done:false value:'阿呆1号'
console.log(iterator.next());   //输出 done:false value:'阿呆2号'
console.log(iterator.next());   //输出 done:false value:'阿呆3号'
console.log(iterator.next());   //输出 done:false value:'阿呆4号'
console.log(iterator.next());   //输出 done:true  value:undefined

 再来说一说for...in 和 for ... of 的区别:

  • 区别一:都可以遍历数组,但是for...in 输出的是数组的下标,for...of 输出的是数组的值
const arr = ['a', 'b', 'c', 'd', 'e']
for (const key in arr) {
    console.log(key);   //输出的是0,1,2,3,4
    console.log(arr[key]);    //输出的是a, b, c, d, e
}
for (const iterator of arr) {
    console.log(iterator);    //输出的是a, b, c, d, e
}
  •  区别二:for ... in 可以遍历对象,而 for ... of 不可以遍历对象,他只能够遍历带有迭代器的,比如Array, Set, Map...
const my = {
    name: 'yy',
    age: 18,
    hobby: '睡懒觉'
}
for (const key in my) {
    console.log(my[key]);   //输出:yy, 18,睡懒觉
}
for (const iterator of my) {
    console.log(my);    //输出报错信息: my is not iterable
}

 遍历数组对象:

可通过for ... in 和 for ...  of 结合的形式遍历数组对象

const arr =[
    {
        name: '小花',
        age: 19,
        hobby: '打游戏'
    },
    {
        name: '小绿',
        age: 20,
        hobby: '睡觉'
    },
    {
        name: '阿紫',
        age: 18,
        hobby: '摆烂'
    }
]
for (const iterator of arr) {
    for (const key in iterator) {
        console.log(iterator[key]);    //输出全部人的信息
    }
}

 10.生成器

生成器函数是es6 提供的一种异步编程解决方案,语法与传统的函数完全不同。

(1)生成器的声明与调用

//声明
function * fun () {
    console.log('熬大夜学编程');
}
//执行
let iterator = fun();
//返回的结果
//console.log(iterator);   //输出的其实是一个迭代器对象,里面有next方法
iterator.next();    //不写这一步不会再控制台打印出结果

 生成器函数还可以引入yield 语句,通过next 方法来控制代码的一个向下的执行

function * fun() {
    console.log(111);
    yield '分隔1';
    console.log(222);
    yield '分隔2';
    console.log(333);
    yield '分隔3';
    console.log(444);
}
let iterator = fun();
iterator.next();    //输出111
iterator.next();    //输出111 222
iterator.next();    //输出111 222 333
iterator.next();    //输出111 222 333 444

 (2)生成器的函数参数

next 语句也可以传递参数,传递的参数作为上一个yield 语句的返回结果,效果如下:

function * fun(arg) {
    console.log(arg);
    let first = yield '分隔1';
    console.log(first);
    let second = yield '分隔2';
    console.log(second);
    let third = yield '分隔3';
    console.log(third);
}
let iterator = fun('a');
console.log(iterator.next());
console.log(iterator.next('b'));    //传入参数b,则first为b
console.log(iterator.next('c'));    //传入参数c,则second为c
console.log(iterator.next('d'));    //传入参数d,则third为d

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值