ES6新语法特性(第二篇)

ES6新语法特性(第二篇)

在上一篇讲了let声明变量,const声明常量,解构赋值,模板字符串,对象简化写法,箭头函数,这篇继续概述ES6其他的新特性。

主要包括以下内容:

1)函数参数默认值设定及与解构赋值的结合使用;

2)rest参数替代arguments处理可变参数;

3)扩展运算符在函数调用、数组合并和伪数组转换中的应用;

4)Symbol数据类型创建唯一标识符及其特性;

5)Set集合实现数组去重、交并差集运算;

6)Map数据结构扩展键值类型;

7)数值扩展和对象方法扩展;

8)模块化及导出方式

9)私有属性

一、函数参数默认值

Es6允许给函数的形参设置初始值(默认值),如果传参,会覆盖默认值。写的时候,具有默认值的参数,一般位置放后边。

javascript 复制代码
function add(a,b,c=10){ 
    return a +b + c
}
let result1 = add(1,2)   // c未传参,默认为10
let result2 = add(1,2,3) // c传参,值为3
console.log(result1)     // 13
console.log(result2)     // 6

默认值可以与解构赋值结合使用:

javascript 复制代码
//传统写法
//每次都要people.去获取对象的值,不简洁
function fn(people){
   console.log(people.name) //张三
   console.log(people.age)	 //18
   console.log(people.like) //study
}
fn({
    name : '张三',
    age:20,
    like:'study'
})

//解构赋值 + 默认值
function fn({name,age,like,sex = '男'}){
   console.log(name) //张三
   console.log(age)  //18
   console.log(like) //study
   console.log(sex)  //男(默认值)
}

二、rest参数(...args)

arguments是JavaScript函数内部的一个特殊对象,它包含了调用函数时传递的所有参数。这个类数组对象在ES5及之前版本中广泛用于处理可变数量参数。

但在现代JavaScript开发中,ES6的剩余参数(...args)已成为更推荐的替代方案。

javascript 复制代码
function data(){
    console.log(args)
}
data('香蕉','苹果','梨')  //{'香蕉','苹果','梨'}--->对象

//rest参数
function data(...args){
    console.log(args)
}
data('香蕉','苹果','梨')  //['香蕉','苹果','梨']--->数组

返回了一个数组,这样可以使用数组的filter,some,every,map等api方法,提高了对参数处理的一个灵活程度。

注意:语法上,rest参数必须放在最后!

三、扩展运算符

javascript 复制代码
const fruit = ['香蕉','苹果','梨']
function fn(){
    console.log(arguments)
}
const fruit = ['香蕉','苹果','梨']
fn(...fruit) // 等同于-->fn('香蕉','苹果','梨'),将数组'展开'了

//用法一:数组合并
const vegetable = ['黄瓜','西红柿','胡萝卜']
//传统写法
//const food = fruit.concat(vegetable)
const food = [...fruit,...vegetable]
console.log(food)  // ['香蕉','苹果','梨','黄瓜','西红柿','胡萝卜']

//用法二:数组克隆(若拷贝数组里有引用类型对象,这里是浅拷贝,新旧对象指向同一地址)
const shuiguo = [...fruit] // ['香蕉','苹果','梨']

//用法三:将伪数组转为真数组
const divs = document.querySelectorAll('div') //伪数组
const divArr = [...divs] 
console.log(divArr) //是一个真数组

区分rest参数和扩展运算符:

rest的位置是函数声明的形参位置,而扩展运算符是在函数调用的是实参中。

rest:function data(...args){ }

扩展运算符:fn(...fruit)

四、Symbol基本使用

Symbol是JavaScript中一种特殊的原始数据类型,自ES6引入,是js语言的第七种数据类型,类似于字符串,主要用于创建唯一且不可变的标识符。

1. 特点:

  • Symbol值是唯一的,用来解决命名冲突的问题。

  • Symbol值不能与其他数据进行运算。

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

  • Symbol不能与其他类型隐式转换,但可以显式转换为字符串或布尔值:

    javascript 复制代码
    const sym = Symbol('foo');
    
    // 隐式转换会报错
    // 'sym value is: ' + sym;  // TypeError
    
    // 显式转换
    String(sym); // "Symbol(foo)"
    Boolean(sym); // true
    Number(sym); // TypeError
  1. Symbol.prptotype.description 获取Symbol的描述字符串

    javascript 复制代码
    let s = Symbol('John')
    console.log(s.description)  //John

五、set集合

ES6提供了新的数据结构Set(集合),它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用扩展运算符和 for...of... 进行遍历集合的属性和方法。

for i in list 遍历的时候,i 代表数组索引值,

foe i of list 遍历的时候,i 代表该索引下标对应的值。

set的属性和方法:

(1)size 元素个数 set.size

(2)add ()添加新元素 set.add(str)

(3)delete() 删除某个元素 set.delete(str)

(4)has ()查找某元素 set.has(str)

(5)clear ()清空集合 set.clear()

(6)for(let i of set) { } 遍历集合中的值

set的应用

(1)数组去重

把数组new为set集合实例,然后用展开运算符展开集合,并用数组[ ]包住。

javascript 复制代码
let arr = [1,2,3,4,1,2,3]
let result = [...new Set(arr)]  // [1,2,3,4]

(2)求两个数组的交集

两个数组去重后,遍历数组1的元素,判断集合2中是否有数组1的元素

javascript 复制代码
let arr1 = [1,2,3,4,1,2,3]
let arr2 = [3,4,5,3,4]

let res1 = [...new Set(arr1)]  //[1,2,3,4]
let res2 = new Set(arr2)  //{3,4,5}

let res = res1.filter(item => {
    if(res2.has(item)){  //has方法是集合的方法
        return true 
    }else{
        return false
    }
})
console.log(res)  //[3,4]  

//可以简化为一行代码
let res = [...new Set(arr1)].filter(item => new Set(arr2).has(item))

(3)求两个数组的并集

将两个数组通过展开运算符合并为一个数组后,去重s

javascript 复制代码
let arr1 = [1,2,3,4,1,2,3]
let arr2 = [3,4,5,3,4]
 
let res = [...new Set([...arr1,...arr2]) ]  //[1,2,3,4,5]

(4)求两个数组的差集

javascript 复制代码
let res = [...new Set(arr1)].filter(item => !(new Set(arr2).has(item))) //取反,交集的逆运算

六、Map集合

ES6提供了Map数据结构,它类似于对象,也是键值对的集合,但是'键'的范围不局限于字符串,各种类型的值都可以(包括对象)当作键。Map也实现了iterator接口,所以可以使用扩展运算符和 for...of... 进行遍历。可以理解map为升级版的对象。

Map的属性和方法:

javascript 复制代码
//声明Map
let m = new Map()
//添加元素
m.set('name','张三')
m.set ('eat',function(){
   ....函数体
})
//Map的元素个数
console.log(m.size)
//删除元素
m.delete('name') //通过键名删除
//获取查找某元素
m.get('eat')   //通过键名获取value值
//清空Map
m.clear()
//遍历Map
for(let v of m){
   console.log(v)
}//遍历获取value值

七、ES6数值扩展

(1)Number.EPSILON( )

Number.EPSILON是JavaScript表示的最小精度,属性值接近于2.22004460...E-16,如果两个值的差小于该精度,可以认为这两个值相等。

javascript 复制代码
//如果两个值的差小于该精度,认为这两个值相等
function equal(a,b){
    if(Math.abs(a-b) < Number.EPSILON){
        return ture
    }else{
        return false
    }
}
console.log(0.1 + 0.2 === 0.3)  //false
console.log( equal(0.1 + 0.2 , 0.3) )  //true

(2)Number.isFinite( )

检测一个数值是否是有限数。

javascript 复制代码
console.log(Number.isFinite(100))     //true
console.log(Number.isFinite( 100/0 )) //false

(3)Number.isNaN( )

检测一个数值是否是NaN。

javascript 复制代码
console.log(Number.isNaN(100))    //false

(4)Number.parseInt / Number.parseFloat( )

字符串转整数。

javascript 复制代码
console.log(Number.parseInt(100156love)) //100156
console.log(Number.isFlost(1.13154abc))  //1.13154

(5)Number.isInteger( )

检测一个数是否是整数。

javascript 复制代码
console.log(Number.isInteger(5))  //true
console.log(Number.isInteger(5.5))  //false

(6)Math.trunc( )

将数字的小数部分抹掉。

(7)Math.aign( )

判断一个数到底为正数,负数,0。

正数返回1,负数返回-1,0返回0。

(8)进制数表示

0b开头表示二进制数,0o开头表示八进制数,0x开头表示十六进制数。

八、对象方法扩展

(1)Object.is 判断两个值是否完全相等。

javascript 复制代码
console.log(Object.is(1,1))     //true
console.log(Object.is(NaN,NaN)) //true  通过object.is判断,NaN是相等的
console.log(NaN === NaN         //false

2.Object.assign对象的合并。

javascript 复制代码
Object.assign(obj1,obj2)
//两个对象进行合并,合并为一个对象,若出现重名,obj2会覆盖和obj1同名的属性

3.Object.setPrototypeOf(obj1,obj2)设置原型对象,把obj2设置为obj1的原型对象。但推荐在创建对象时就设置好其原型对象。

4.Object.getPrototypeOf(obj1)获取obj1的原型对象。

5.Object.entries

  • 返回一个由对象自身可枚举属性的键值对组成的二维数组,格式为 [ [key1, value1], [key2, value2] ]
  • 即把对象变为一个数组,数组元素是把对象里的每组键值对写成一个数组。这样可以实现将对象转变为map。
  • 浅拷贝:返回的数组是原对象属性的副本,修改数组中的值会影响原对象。
  • 不包含继承属性:仅处理对象自身的可枚举属性,忽略原型链上的属性
javascript 复制代码
const p = {
    name:'John',
    hobby:['eat','study','sleep']
}
//获取对象所有键
console.log(Object.keys(p))//['name','hobby']
//获取对象所有值
console.log(Object.values(p))//['John',Array(3)]

// entries
console.log(Object.entries(p))
// 输出结果:
   [Array(2),Array(2)]    返回一个新数组
 >  0: ['name':'John']     数组每个元素 :是对象键值对写成数组
 >  1: ['hobby',Array(3)] 

const m = new Map(Object.entries(p))
console.log(m)
// 输出结果:
  Map(3){'name':'John','hobby' => Array(3)}

6.Object.fromEntries

与Object.entries相反(逆运算),它可以把键值对组成的二维数组转为一个对象。

javascript 复制代码
const res = Object.fromEntries([
    ['name':'John'],
    ['hobby',Array(3)]
])
console.log(res) // { name:'John',hobby:['eat','study','sleep']}

7.Object.getOwnPropertyDescriptors( )

该方法返回指定对象所有自身属性的描述对象

九、ES6模块化

ES6模块化是ES6标准中引入的原生JavaScript模块化方案,旨在解决大型项目中代码组织、依赖管理和复用性问题。其核心是通过exportimport关键字实现模块的导出与导入,将代码拆分为独立的、可复用的模块。以下是ES6模块化的关键特性和要点:

核心特点
  • 独立作用域:每个模块拥有独立的作用域,内部变量和函数默认不会污染全局命名空间,避免了命名冲突。提高代码复用,高维护性。
  • 静态化加载:模块的依赖关系在编译时确定(静态分析),而非运行时动态加载,这使得工具能够优化代码(如Tree Shaking)并提升性能。
  • 显式导出与导入 :通过export导出模块的变量、函数或类,其他模块通过import按需引入,形成清晰的依赖关系。

在ES6模块化规范里,共有三种暴露方式,分别是分别暴露、统一暴露和默认暴露,下面展开介绍:

1.分别暴露

  • 语法 :在需要暴露的变量、函数、对象等前面直接使用export关键字。
  • 特点:可以导出多个具名成员,导入时需使用确切名称。
  • 示例
javascript 复制代码
// 分别暴露
export const person = {name: 'zhangsan', age: 12};
export function playGame() {
    console.log('打游戏');
}

2.统一暴露

  • 语法 :先在模块内部定义变量、函数等,最后使用export {变量名1, 变量名2...}的形式统一导出。
  • 特点:与分别暴露类似,但导出列表集中管理,提高代码可读性,适合模块内部定义较多,但只需要暴露部分内容的场景,便于维护和管理导出接口。
  • 示例
javascript 复制代码
// 统一暴露
const cat = {name: 'xiaotao', age: 5};
function playBall() {
    console.log('猫咪喜欢玩球');
}
export {cat, playBall};

3.默认暴露

  • 语法 :使用export default,后面可以跟变量、函数、对象等,每个模块只能有一个默认导出。
  • 特点:导入时可自定义名称。
  • 示例
javascript 复制代码
// 默认暴露
export default function A() {
    console.log('你好');
}

三种暴露方式在导入时也有所不同:

  • 分别暴露和统一暴露导入时使用import {变量名1, 变量名2} from '模块路径'。(解构赋值的方式引入)

  • 默认暴露导入时使用import 自定义名称 from '模块路径'

  • 若引入多个模块,有方法发生重名,可以在引入时通过as定义别名。

    import {apple as pingguo} from './....'

    import {default as pingguo} from './....'

十、私有属性

类私有字段是 ES2020 引入的官方标准方法,通过在属性名前加 #前缀来定义私有属性。

js 复制代码
class Person {
  #name; // 私有属性声明
  constructor(name) {
    this.#name = name;
  };
  
  getName() {
    return this.#name;
  };
  
  setName(newName) {
    this.#name = newName;
  }
}

const person = new Person('John');//实例化
console.log(person.getName());   // "John"
console.log(person.#name);     // SyntaxError: 私有字段无法外部访问
相关推荐
不爱说话郭德纲3 分钟前
👩‍💼产品姐一句小优化,让我给上百个列表加上一个动态实时计算高度的方法😿😿
前端·vue.js·性能优化
现在没有牛仔了6 分钟前
小试牛刀,用electron+vue3做了一个文件归纳程序~
前端·electron
FogLetter7 分钟前
Prisma + Next.js 全栈开发初体验:像操作对象一样玩转数据库
前端·后端·next.js
知识分享小能手7 分钟前
React学习教程,从入门到精通, React教程:构建你的第一个 React 应用(1)
前端·javascript·vue.js·学习·react.js·ajax·前端框架
李剑一8 分钟前
别乱封装,你看出事儿了吧...
前端·vue.js
文心快码BaiduComate12 分钟前
新增Zulu-CLI、企业版对话支持自定义模型、一键设置自动执行、复用相同终端,8月新能力速览!
前端·后端·程序员
walking95715 分钟前
JavaScript 神技巧!从 “堆代码” 到 “写优雅代码”,前端人必看
前端·面试
前端西瓜哥20 分钟前
图形编辑器开发:基于矩阵的画布缩放和移动实现
前端
walking95720 分钟前
前端 er 收藏!高性价比 JS 工具库,轻量又强大
前端·面试
gongzemin29 分钟前
Vue 项目权限管理 路由 按钮权限
前端·vue.js