ES6学习笔记(一)| let和const;模板字符串;函数之默认值、剩余参数、扩展运算符、箭头函数

自学笔记,参考阮一峰教程和B站小马哥ES6

一、ES6简介

ES6是什么?

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

ES6和javascript的关系

    要讲清楚这个问题,需要回顾历史。1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。

    该标准从一开始就是针对 JavaScript 语言制定的,但是之所以不叫 JavaScript,有两个原因。一是商标,Java 是 Sun 公司的商标,根据授权协议,只有 Netscape 公司可以合法地使用 JavaScript 这个名字,且 JavaScript 本身也已经被 Netscape 公司注册为商标。二是想体现这门语言的制定者是 ECMA,不是 Netscape,这样有利于保证这门语言的开放性和中立性。

    因此,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 JScript 和 ActionScript)。日常场合,这两个词是可以互换的。

二、let和const

    与过去在ES5中常用的var关键字相同,这两个关键字在ES6中的作用就是声明变量。

  1. let声明变量,不存在变量提升
    但不同的是,var声明变量存在变量提升的问题。
console.log(a); // undefined
var a = 10; //这就相当于在打印之前已经声明了a这个变量,只是在这一行进行赋值,执行代码并不会报错

这部分代码相当于:

var a;
console.log(a); // undefined
a = 10;

但是用letconst来声明变量就不存在变量提升的问题,例如:

console.log(a) //报错:Uncaught ReferenceError: can't access lexical declaration 'a' before initialization
let a = 10;
  1. 是一个块级作用域
    在这里,用var声明的变量a存在变量提升,其作用域就扩大到了if语句外,而let声明的变量b的作用域只在if语句内
console.log(a) //undefined
if(1 === 1){
    var a = 10;
}

console.log(b) // 报错:Uncaught ReferenceError: b is not defined
if(1 === 1){
    let b = 10;
}
  1. 不能重复声明
var a = 10;
var a = 20;
console.log(a) //20

let b = 10;
let b = 20;
console.log(b) // 报错:Uncaught SyntaxError: redeclaration of let b
  1. 以上let具有的特点const都有,此外const声明的变量不能被改变
const a = 10;
a = 20; // 报错:Uncaught TypeError: invalid assignment to const 'a'
console.log(a) 

但是要注意,当用const来声明对象时,对象的属性是可以修改的,但是注意不能修改整个对象。

const person = {
    name:'Mike',
    year: 20,
    Nation: 'China'
}

person.name = 'Jack'
console.log(person.name) //Jack

person.sex = 'male'
console.log(person.sex) //male

person = {
    intrest:'sing'
} // 报错:Uncaught TypeError: invalid assignment to const 'person'
console.log(person.intrest)

三、模板字符串

ES6中引入的模板字符串能够很好地简化代码。过去需要输出一段可变的文本时需要通过拼接字符串的方式:

<body>
    <div id="Box">
    </div>
</body>
<script>
    let sentence = '你好,这里是模板字符串'
    const box = document.getElementById('Box')
    box.innerHTML = '拼接字符串写法:<ul><li><p>'+sentence+'</p></ul>'
</script>

在这里插入图片描述
模板字符串即可以用``(反引号,即Tab上面那个符号)的方式将字符串写在里面,如果有需要写入的变量,则用${}将变量包裹起来,这样就无需用+号来拼接字符串了:

box.innerHTML = `模板字符串写法:<ul><li><p>${sentence}</p></ul>`

在这里插入图片描述

四、函数之默认值、剩余参数、扩展运算符、箭头函数

1. 函数默认值

ES6之前,当需要为函数的参数定义一个默认值时,需要在函数内部通过判断的方式为形参赋值:

    function add(a, b){
        a = a || 10;
        b = b || 20;
        return a + b;
    }
    console.log(add()); // 30
    console.log(add(15)); // 35
    console.log(add(15, 30)); // 45

ES6中函数的默认值可以直接写在括号中:

      function add(a = 10, b = 20){
        return a + b;
    }
    console.log(add()); // 30
    console.log(add(15)); // 35
    console.log(add(15, 30)); // 45

默认值也可以是一个表达式:

    function add(a, b = getVal()){
       return a + b;
   }
   function getVal(val = 35){
       return val + 10;
   }
   console.log(add(15)); // 60

2. 剩余参数

当无法确定需要输入函数的实参的数量时,过去可以用arguments的方式获取实参:

    function search(obj){
        let person = new Object();
        for(let i = 1; i < arguments.length; i++){
            person[arguments[i]] = obj[arguments[i]]
        }
        return person;
    }
    let Person = {
        name:'Jack',
        age:23,
        job:'fireman',
        country:'China'
    }
    console.log(search(Person,'name','country')) // Object { name: "Jack", country: "China" }

剩余参数即可以将定义函数时未知数量的实参都存入一个数组中,需要用到实参时可以遍历数组取参,写法为...具名参数,例如...keys

    function search(obj, ...keys){
        let person = new Object();
        for(let i = 0; i < keys.length; i++){
            person[keys[i]] = obj[keys[i]]
        }
        return person;
    }
    // Object { name: "Jack", country: "China" }

3. 扩展运算符

与剩余参数相同,扩展运算符也是通过...arr这种在变量名前面加三个点实现的,不同的是,扩展运算符是将数组里面的元素提取出来作为参数输入函数的,也就是输入函数的不再是一个数组,而是一个个参数。

let min = Math.min(10,20,54,42)
console.log(min) // 10

let arr = [10,23,45,29,100,23,56]
let max = Math.max(arr)
console.log(max) // NaN
	
let arr = [10,23,45,29,100,23,56]
let max = Math.max(...arr)
console.log(max) // 100

4. 箭头函数

在ES6中,可以采用=>的方式定义函数,让代码更加简洁。
过去定义函数需要用function来定义,例如:

let add = function(a, b){
	return a + b;
}
console.log(add(5,7)) // 12

换成箭头函数的方式定义函数就可以写成:

let add = (a, b)=>{
	return a + b;
}
console.log(add(5,7)) // 12

当声明函数时只传入一个参数的时候,可以省略括号,让写法更简洁:

let add = a => a + 10;
console.log(add(5)) // 15

箭头函数支持剩余参数、默认参数和解构赋值,但是不能省略括号,会报错。
在用箭头函数返回一个对象时,不能省略括号,省略()的话会直接报错:

let person =(id,name)=>({
        id:id,
        name:name
    })
let person1 = person(123,'Jack')
console.log(person1) // Object { id: 123, name: "Jack" }

利用箭头函数也可以实现闭包

let hello =(function(){
    return function(){
        console.log('hello world')
    }
})()
hello() // hello world

// 可以改写成:
let hello =(()=>{
    return ()=>console.log('hello world')
})()
hello() // hello world

5. 箭头函数this指向和注意事项

(1)箭头函数没有独立的 this,箭头函数内部的this只能通过查找作用域链来实现,一旦使用箭头函数,当前不存在作用域。
在ES6之前的写法中,函数内部的this会指向调用函数的对象:

let handle = {
    id: 123,
    init: function(){
        document.addEventListener('click', function(event){
            this.doSomeThing(event) //此时这里的this是指向document的,报错:Uncaught TypeError: this.doSomeThing is not a function
        }, false)
    },
    doSomeThing: function(event){
        console.log(event.type)
        console.log(this.id)
    }
}
handle.init()

改写成箭头函数后,this就指向了init的对象handle,:

let handle = {
    id: 123,
    init: function(){
        document.addEventListener('click', function(event){
            this.doSomeThing(event)
        }, false)
    },
    doSomeThing: function(event){
        console.log(event.type) // click
        console.log(this.id) // 123
    }
}
handle.init()

如果将init也改写成箭头函数,this就会顺着作用域链去找init的对象,也就是window

let handle = {
    id: 123,
    init: ()=>{
        document.addEventListener('click', (event)=>{
            this.doSomeThing(event) //此时this指向的是window,报错:Uncaught TypeError: this.doSomeThing is not a function
        }, false)
    },
    doSomeThing: function(event){
        console.log(event.type)
        console.log(this.id)
    }
}
handle.init()

(2)箭头函数没有arguments

let add = function(a, b){
    return arguments[0] + arguments[1]
}
console.log(add(10,20)) //30

let add = (a, b) =>{
    return arguments[0] + arguments[1] //报错:Uncaught ReferenceError: arguments is not defined
}
console.log(add(10,20))

(3)箭头函数不能用作构造函数,使用 new 调用它们会引发 TypeError。

let person = function(){
    this.id = 123,
    this.name = 'Jack'
}
let p = new person()
console.log(p) //Object { id: 123, name: "Jack" }

// 改写为箭头函数后:
let person = ()=>{
    this.id = 123,
    this.name = 'Jack'
}
let p = new person() //报错:Uncaught TypeError: person is not a constructor
console.log(p)
  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值