JavaScript ES6 核心特性详解:变量声明、字符串与函数

作者:木棉时间:2026-10-22 20:54:00浏览:420

本文系统梳理 ES6 核心语法,涵盖 let 与 const 的块级作用域及常量特性、模板字符串的多行与插值优势、箭头函数的 this 绑定规则,以及数组和对象的新增方法如 Array.from、Object.is 和扩展运算符。

ES6 let与const及其相关

块级作用域

ES6 引入了块级作用域的概念,其核心规则是:由大括号 {} 包裹的代码区域通常被视为一个独立的块级作用域。

常见的应用场景包括:

直接使用大括号 {} 包裹代码块:


 {
 var a = 4
 }

包括函数体、if-else 语句、for 循环、switch 语句以及 try-catch 语句的大括号。特别需要注意的是,在 for 循环中,每一次迭代所对应的大括号 {} 都是一个独立的块级作用域。


 for(let i=0; a < 5; i++){
  let j = i
 }

上述代码执行了五次循环,实际上创建了五个相互独立的变量 j。

在日常开发中,我们可以利用这一特性手动创建块级作用域,以隔离变量作用范围。

块级作用域变量 let 与 const

使用 let 或 const 声明的变量仅在当前块级作用域内有效,一旦超出该代码块,变量将无法被访问。


 {
  let a = 5
 }
console.log(a) 
// Uncaught ReferenceError: a is not defined

在日常开发中,建议在所有块级作用域内使用 let 或 const 来声明变量,以确保作用域的清晰与安全。

使用时需要注意以下问题:

let 和 const 声明的变量必须先声明后使用,以避免错误,不应依赖变量提升特性。const 声明时必须进行初始化,否则将报错;建议 let 也在声明时进行初始化。const 声明的变量一旦初始化,后续不可重新赋值,但可以修改其引用对象的内容。


 const noChangeMe; 
 // Uncaught SyntaxError: Missing initializer in const declaration
 const noChangeMe = [1,2,4]
 noChangeMe = [2, 3] 
 // Uncaught TypeError: Assignment to constant variable
 noChangeMe[100] = 100 // everything is OK

let 和 const 声明的变量不允许重复声明。虽然 var 允许无限次重复声明,但这种做法不适用于这两个新的声明方式。


 let a = 1
 let a = 2 
 // Identifier 'a' has already been declared

不应通过 window.xxx 调用 let 与 const 声明的变量。根据 ES6 规定,使用 let、const 和 class 声明的全局变量不属于顶层对象(如 window)的属性。

String

使用反引号 `` 包裹字符串。利用 `` 可以解决以下问题:

传统字符串无法直接换行,若需换行必须使用 + 号拼接;字符串内的引号若与外层引号相同,则需要进行转义;在字符串中插入变量时,需使用 + 号连接。以往的写法如下:


 var name = 'world'
 var str = "小明说:\"hello, " + name + "\""  // 小明说:"hello, world"

现在可以更方便地写作:


 var name = 'world'
 str str = `小明说:"hello, ${name}"`

总体而言,这种方式有三个主要优势:

无需担心字符串内部出现的引号问题;支持直接换行,反引号包裹的字符串可以自由换行;使用 ${} 将变量或表达式嵌入字符串中,无需编写大量的 + 号拼接。

ES6 遍历字符串

使用 for...of 替代传统的 for 循环:


 var string = 'string'
 for(var i of string) {
 console.log(i)
 }

includes()、startsWith()、endsWith()。不再需要使用 indexOf() 来判断字符串中是否包含特定值,可以使用 includes():


 var string = 'string'
 string.includes('i', 0)  // true

includes 方法的第二个参数表示查找的起始索引。此外,还可以使用 startsWith() 和 endsWith() 来判断字符串是否以特定字符开头或结尾。

ES6 函数

参数的默认值

方便地设置函数参数的默认值。


 function print( a = 2 ){
 console.log(a)
 }
 print() //2

ES6 扩展运算符…获取其余参数

可以使用 ... 加上变量名来保存剩余参数的全部数量。当仅知道函数的前几个具体参数,而不确定后续传入参数个数时,可以使用 ... 将剩余参数保存到一个数组中。


 function print(value1, value2, ...values){
 console.log(values.join('--'))
 }
 print(1, 2, '参数3') // 参数3
 print(1, 2, '参数3', '参数4', '参数5') // print(1, 2, '参数3', '参数4', '参数5')

ES6 使用箭头函数

使用箭头函数有两个主要好处:

代码更加简洁;静态绑定 this。在箭头函数中,this 指向定义箭头函数时所在对象的 this。


 var name = 'outer'
 var obj = {
  name: 'inner',
  func: () => {
  console.log(this.name)
  }
 }
 var obj2 = {
   name: 'inner',
   func: function() {
     console.log(this.name)
   }
 }
 obj.func() // "outer"
 obj2.func() // "inner"

第一个示例使用了箭头函数,由于箭头函数的 this 与其所在环境中的 this 相同,即与 obj 的 this 相同,而 obj 处于全局环境的活动对象中,this 指向全局对象(此处为 window),因此输出 outer。注意:obj 对象的 this 与其属性中的 this 不同。第二个示例使用了普通函数,作为 obj2 的一个属性,func 方法中的 this 指向了所在的对象,输出 inner。

ES6 数组

使用 Array.from() 把类数组对象转为数组

一般来说,含有 length 属性的对象可以被视为类数组对象。平时获取多个 DOM 对象后,无法直接使用数组中的许多方法。我们可以使用 Array.from 方便地将其转换为数组。


 var divs = Array.from(document.querySelectorAll('div'))
 divs.forEach((value, index) => {})

使用 fill() 初始化数组

想要以某个值初始化数组,通常需要遍历。而使用 fill() 方法,则方便了许多。


 var arr = new Array(100) // 建立一个100元素的数组
 arr.fill('初始值', 0, arr.length)

第一个参数是要填充的值,后两个参数与一般数组方法相同,分别为起始索引和结束索引(不包括结束索引位置)。

使用 includes 方法

与字符串的 includes 方法类似,用于判断数组中是否包含给定值。

对象 使用简单的属性表示和方法表示


 var name = 'John'
 var a = {
 name: name,
 sayName: function(){ console.log(this.name) }
 }

改写为:


 var name = 'John'
 var a = {
 name,
 sayName () { console.log(this.name) }
 }

记得 Object.is() 这个方法。 其与 === 的差别:


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

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

可以这样理解,遵循的原则是:是同一个东西就要相等。NaN 与 NaN 被视为同一个东西,而 -0 带有负号,与 0 和 +0 不同。0 和 +0 相同,就像 1 和 +1 相同一样。

使用 Object.assign() 合并多个对象

Object.assign() 用于合并对象。assign 意为分配、指派。该方法的本意是将某些对象自身的属性拷贝到目标对象上,它不会复制继承来的属性。例如,可以在定义某个配置时,先定义一个基础配置,再定义两种不同情况下的配置,使用时进行合并。


 var pathConfig = {
 path: 'style/images'
 }
 var devConfig = {
 baseUrl: 'http://localhost:8080/'
 }
 var buildConfig = {
 baseUrl: 'https://192.128.0.2'
 }
 // 使用时,合并
 var mode = 'dev'
 var config = Object.assign({}, pathConfig, mode === 'dev' ? devConfig : buildConfig)

此处仅为例示。

Object.keys(),Object.values(),Object.entries。 这三个方法返回对象自身的、可枚举的、属性名为字符串的属性相关信息,分别为:


Object.keys(): 属性名组成的数组
Object.values(): 属性值组成的数组
Object.entries: ["key", "value"]组成的数组。
 var john = {
 name: 'John',
 age: 12
 }
 Object.keys(john) // ["name", "age"]
 Object.values(john) // ["John", 12]
 Object.entries(john) // [["name", "John"], ["age", 12]]

ES6 ...运算符

前面在函数的剩余参数处理中提到了...扩展运算符。总结一下,感觉有两个用法:

用来读取数组或者对象的时候,是把数组或对象给扩展开; 用来给对象或者数组赋值的时候,自动给对象或数组添加属性或元素。 用来读取 读取的时候就是把数组或者对象给扩展开来。


 var a = [...[1,2,3], 4] // 把数组的每一项都展出来
 a // [1, 2, 3, 4]
 var obj = {
 name: 'John',
 age: 12
 }
 var newObj = {...obj, job: 'teacher' } // 把某个属性展出来
 newObj // {name: "John", age: 12, job: "teacher"}

所以可以很方便地用来扩展、合并数组或对象。

用作赋值

用作赋值的时候,是用作解构赋值,含义就是把等号右边表达式的剩余属性或数组项都放到...后面的变量里。


var a, restB
 [a, ...restB] = [1, 3, 5]
 a // 1
 restB // [3, 5]

 var c, restD
 { name, ...restD } = {name: 'John', age: 12, job: 'teacher'}
 name // "John" 是一个属性的值
 restD // { c, ...restD } = {name: 'John', age: 12, job: 'teacher'} 是一个对象

对于对象的解构赋值,会把对应不到的属性全部放进...后面的变量对象中。

注意:因为是把剩下没人要的属性或者数组项都收下,所以...应该放在数组或者对象中的最后,且只能有一个。

以上即是 ES6 常用基础知识总结,希望对大家有所帮助

作者最新文章