梳理ES6中增加的新特性(一)

本文深入探讨了ES6(ECMAScript 2015)的新增特性,包括块级作用域、let与const变量声明、解构赋值、模板字符串、默认参数、剩余参数、箭头函数、对象字面量增强及扩展方法等,解析了这些特性的使用场景与优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ECMAScript通常被认为是JavaScript的标准化规范,实际JavaScript是ECMScript的扩展语言,ECMAScript只定义提供最基本的语法。

我们通常所说的ES6指的是ES2015、ES2016、ES2017……等,所以ES6泛指所有的新版本。

ES6是在ES5.1的基础上进行的升级:

  ① 解决了原有语法的上的一些问题或不足

  ②对原有语法进行了增强

  ③全新的对象,全新的语法,全新的功能

  ④全新的数据类型和数据结构


一、作用域——某个成员(变量)能起作用的范围

  在ES6中的作用域分为:全局作用域、函数作用域、块级作用域

  用 var 定义的变量存在变量提升,属于全局范围。 

  当用var定义变量是为全局变量,在双层循环中。下面代码返回值为 0  1  2  内层结束  i=3,得到的结果与预期不符

for (var i = 0; i < 3; i++) {
    for (var i = 0; i < 3; i++) {
        console.log(i)
    }
    console.log('内层结束 i=' + i)
}

  let 只能在所声明的代码块中使用,外部无法访问,只能先声明变量,才能使用。

  下面代码中,使用 let 定义变量,只能在所处的代码块中使用,互不影响,得到的结果符合预期,结果如下:

  第一次循环:0  1  2  内层结束 i=0,第二次循环0  1  2  内层结束 i=1,第三次循环0  1  2  内层结束 i=2

for (let i = 0; i < 3; i++) {
    for (let i = 0; i < 3; i++) {
        console.log(i)
    }
    console.log('内层结束 i=' + i)
}

看下面代码,用let定义变量是处于一个块作用域中的,在每次循环的过程中,let i= i+1 都是处于一个新的块级作用域中的,与之前的 i 互不干扰,所以调用 elements[0].onclick() 会得到预期的值。 若将 let i =0 改为 var i=0,则所有调用结果都为 3。

var elements = [{}, {}, {}]
for (let i = 0; i < elements.length; i++) {
    elements[i].onclick = function() {
        console.log(i)
    }
}
elements[0].onclick() // 0
elements[1].onclick() // 1
elements[2].onclick() // 2

  上面代码的不同结果,是因为变量所处的作用域不同,var 属于全局作用域,都可以修改,而 let 处于块级作用域,只能在所处的代码块中进行修改,使用。


二、下面讲一些新特性

1. const  常量  (在 let 的基础上多了个只读的特性)

  const 常量在声明的同时必须赋初值,否则会报语法错误:SyntaxError: Missing initializer in const declaration    

  不允许在声明过后重新指向内存地址(并不是不能去修改常量中的属性成员)

//新定义,再赋值,报错
const aa
aa = 'dd'


//声明后,重新指向新的内存地址,报错
const name = 'ddd'
name = 'ccc'


//声明常量,为常量中的属性成员赋值
const obj = {}
obj.name = 'zzz'
console.log(obj.name)

2. 解构 (数组的解构 和 对象的解构)

  (1) 数组的解构

   在ES6中, 以 ...  接收当前元素到最后的所有剩余元素。三个点的方式只能用于最后的解构位置。若解构的元素位置大于数组长度,则对应的值为undefined

const arr = [100, 200, 300]

const [foo, bar, dd] = arr
console.log(foo, bar, dd)

const [foo, ...ree] = arr
console.log(ree)

(2) 对象的解构

   与数组方式基本一致,根据属性名去提取对应的属性值,当属性名发生冲突时,可以起别名的方式

const obj = {
    name: 'zs',
    age: 22
}

//根据属性名提取对应的属性值
const { age } = obj
console.log(age)

//当发生冲突时,可以起别名
const name = 'tom'
const { name: Oname } = obj
console.log(Oname)

3. 模板字符串

(1) 字面量

用反引号定义 => `  `,支持转义字符,支持换行,可以使用插值表达式 ${name}

const str = `hello es2015 \`hi\``
const str = `hello es2015,
hi haow ` //支持换行
console.log(str)

const name = 'tom'
const msg = `heym,${name}`
console.log(msg)

(2) 标签函数

在定义模板字符串之前,添加一个标签,这个标签就是一个特殊的函数,添加标签即调用函数。标签函数的作用对模板字符串进行加工。 如下面代码 gender 的加工

下面代码中,strings接收的是模板字符串的字符,以数组的形式, name和gender接收的是模板字符串的插值表达式

const name = 'tom'
const gender = true

function MyTgeFun(strings, name, gender) {
    // console.log(strings, name, gender)  // 打印结果[ 'hey,', ' is a ', '.' ] tom true
    const sex = gender ? 'man' : 'woman'
    return strings[0] + name + strings[1] + sex + strings[2]
}

const result = MyTgeFun `hey,${name} is a ${gender}.`
console.log(result) // hey,tom is a man.

4. 字符串的扩展方法

   字符串的查找方法

  • includes('string')   判断字符串中是否存在string
  • startsWith('string')  判断字符串是否以string开头
  • endsWith('string')  判断字符串是否以string结尾
// 字符串的扩展方法

const message = 'Error: foo is not defined'

// 字符串是否已Error开头。用startsWith
console.log(message.startsWith('Error')) //开头  true
console.log(message.endsWith('d'))       //结尾  true
console.log(message.includes('fodo'))    //中间  fasle

5. 默认值

在定义函数时,可以给形参赋值,若调用时,接收的参数少于形参,则形参就采用默认值

function foo(bar, enable = true) {
    console.log('foo invoked - enable: ')
    console.log(enable)
}

foo('fs') //  foo invoked - enable:  true

foo('fs','defult') // foo invoked - enable:  defult

6.剩余参数

我们知道,可以使用arguments伪数组的形式接收,而es6中出现了 ... 操作符

// 剩余参数
foo(1, 2, 3, 4)
//arguments
function foo() {
    console.log(arguments) // [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 }
}
// ...
function foo(...args) {
    console.log(args)  //  [ 1, 2, 3, 4 ]
}

7.展开数组

apply(this,arry),第一个参数为this指向,第二个为数组。也可以使用  ... 操作符

// 展开设置参数

const arr = ['fpp', 'ff', 'sdd']

// 一个一个传,当参数不确定时,无法进行
// console.log(
//     arr[0],
//     arr[1],
//     arr[2]
// )

// apply() 第一个参数this的指向,第二个数组
console.log.apply(console, arr)

console.log(...arr)

8.箭头函数

  (1)箭头函数简单使用

  代码简单易读,下面代码为 filter方法普通函数与箭头函数的对比。

const arr = [1, 2, 3, 4, 5, 6, 7]
arr.filter(function(item) {
    return item % 2
})
const aa = arr.filter(i => i % 2)
console.log(aa)
console.log(11)

 (2) 箭头函数与this

 箭头函数不会改变this的指向,因为箭头函数中无this机制,所以箭头函数内的this指向与箭头函数外相同。即箭头函数指向当前作用域的this

// 箭头函数与this
const person = {
    name: 'tom',
     sayhi: function() {
         console.log(`hi, my namae is ${this.name}`)
             // this指向person对象
         console.log(this)
     },
}
person.sayhi()

//输出为
hi, my namae is tom
{ name: 'tom', sayhi: [Function: sayhi] }

9.对象字面量增强

  计算属性名: [Mth.random]: 属性值;     方法不加function: methods () {  }   

// 对象字面量
// 可以使用表达式的返回值作为对象属性名
const bar = 'e45';
const obj = {
    foo: 123,
    // bar:bar
    bar,
    methods1: function() {
        console.log('methods1')
    },
    methods2() {
        console.log('methods2')
    },
    // Math.random():123
    [Math.random()]: 222 //计算属性名

}

// obj[Math.random()] = 123
console.log(obj)
obj.methods1()
obj.methods2()

10.对象扩展方法

(1) assign:将多个源对象中的属性复制到一个目标中,若属性值相同,则覆盖,若无此属性值,则添加。复制对象到全新的对象中去,修改不会影响外部数据。可以用于对obj对象参数设置默认值。

function func(obj) {
    // obj.name = 'func obj'
    // console.log(obj)
    const funcObj = Object.assign({}, obj)  //复制obj对象到一个空对象
    funcObj.name = 'funcObjk'    //修改新对象的name属性
    console.log(funcObj)
}

const obj = { name: 'global obj' }
func(obj)  //打印 funcObj 对象
console.log(obj)  //打印obj对象

/*--------打印结果-------------*/

{ name: 'funcObjk' }
{ name: 'global obj' }

(2) Object.is 用于判断两个值是否相等

//Object.is 与 === 对比

console.log(NaN === NaN) //false
console.log(Object.is(NaN, NaN)) //true

console.log(+0 === -0) //true
console.log(Object.is(+0, -0)) //false

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值