ES6学习(9)-- 各数据类型扩展的汇总(2)

本篇文章我们续接ES6学习(8)-- 各类数据类型扩展的汇总(1)学习剩下的部分:函数的扩展,数组扩展,对象的扩展,运算符的扩展;同样的,在这里我们还是摘取出来大家常见,常用,或者有机会用到的知识点。

4,函数的扩展

函数参数的默认值

        ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。

注意:

参数变量是默认声明的,所以不能用letconst再次声明。

使用参数默认值时,函数不能有同名参数。 

参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的。

// 例1
function log(x, y = 'World') {
  console.log(x, y);
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello

//例2
function foo(x = 5) {
  let x = 1; // error
  const x = 2; // error
}

//例3
// 不报错
function foo(x, x, y) {
  // ...
}
// 报错
function foo(x, x, y = 1) {
  // ...
}
// SyntaxError: Duplicate parameter name not allowed in this context

 与解构赋值默认值结合使用

function foo({x, y = 5} = {}) {
  console.log(x, y);
}

foo() // undefined 5

rest参数 

 定义:ES6 引入 rest 参数,用于获取函数的多余参数,这样就不需要使用arguments对象了。

形式:...变量名,变量是一个数组,该变量将多余的参数放入数组中。

function add(...values) {
  let sum = 0;

  for (var val of values) {
    sum += val;
  }

  return sum;
}

add(2, 5, 3) // 10

// 注意,rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。
// 报错
function f(a, ...b, c) {
  // ...
}

rest参数与arguments对象相比差异:

rest参数时数组,可以直接使用所有的数组方法。arguments对象是‘类数组’,本质上是对象。想要使用数组的方法需要Array.from()进行转换。

name属性

函数的name属性,返回该函数的函数名。

// 一般函数
function baz(){
    ...
}
baz.name  // baz

// 匿名函数
var baz = function(){
    ...
}
baz.name // baz

// 表达式函数
var baz = function foo(){
    ...
}
baz.name // foo

// 构造函数
(new Function).name //anonymous

箭头函数

 具体请转至  ES6学习(6)-- 箭头函数  。

5,数组的扩展

扩展运算符

扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。 

特点:

1,扩展运算符主要与函数一起使用

2,扩展运算符后可以放置表达式

3,只有函数调用时,扩展运算符才可以放在圆括号中,否则会报错。

4,扩展运算符后面是一个空数组,则不产生任何效果。

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5

// 函数调用
function push(array, ...items) {
  array.push(...items);
}

function add(x, y) {
  return x + y;
}

const numbers = [4, 38];
add(...numbers) // 42

// 表达式
const arr = [
  ...(x > 0 ? ['a'] : []),
  'b',
];

// 空数组
[...[], 1]
// [1]

Array.from()

Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。

Array.from()方法可以有两个参数,第一个参数是需转换的类数组,第二个参数是用来对每个元素进行处理,将处理后的值放入返回的数组。

// 一般用法,一个参数
let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};

// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']


// 两个参数
Array.from([1, 2, 3], (x) => x * x)
// [1, 4, 9]

Array.of()

Array.of()基本上可以用来替代Array()new Array(),并且不存在由于参数不同而导致的重载。它的行为非常统一:总是返回参数值组成的数组。如果没有参数,就返回一个空数组。

Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1

find() 和 findIndex()

find() :  用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。第二个参数用来绑定回调函数的this对象。

findIndex() :用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1

// find()
[1, 5, 10, 15].find(function(value, index, arr) {
  return value > 9;
}) // 10

// findIndex()
[1, 5, 10, 15].findIndex(function(value, index, arr) {
  return value > 9;
}) // 2

fill()

fill方法使用给定值,填充一个数组。它可以接受三个参数:第一个参数,指定填充数组的值或内容。(可以为空);第二个参数:填充的起始位置;第三个参数:填充的结束位置;(不包含结束参数本身);

//情况一:三个参数
['a', 'b', 'c'].fill(7, 1, 2)   // ['a', 7, 'c']

// 情况二,一个参数
['a', 'b', 'c'].fill(7)        // [7, 7, 7]

new Array(3).fill(7)           // [7, 7, 7]

// 注意,如果填充的类型为对象,那么被赋值的是同一个内存地址的对象,而不是深拷贝对象。
let arr = new Array(3).fill({name: "Mike"});
arr[0].name = "Ben";
arr             // [{name: "Ben"}, {name: "Ben"}, {name: "Ben"}]

let arr = new Array(3).fill([]);
arr[0].push(5);
arr             // [[5], [5], [5]]

entires()、keys()、values()

entries()keys()values()——用于遍历数组。它们都返回一个遍历器对象,可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。使用方法可以参考:ES6学习(7)-- Set和Map数据结构 。

includes()

 Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。该方法可以接受两个参数:第一个参数是判定值;第二个参数是表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。

相比于原来的数组方法indexOf()的方法,includes()方法有两大优点:

语义化更好,返回结果就是true和false,不用去比较indexOf的返回值是不是-1;

与indexOf相比,它是有这新的判定算法,改掉了indexOf的(===)算法,可以判定NaN。

[1, 2, 3].includes(2)     // true
[1, 2, 3].includes(4)     // false
[1, 2, NaN].includes(NaN) // true

6,对象的扩展

 属性的遍历

ES6 一共有 5 种方法可以遍历对象的属性:

1,for...in:循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

2,Object.keys(obj):返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

3,Object.getOwnPropertyNames(obj):返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。

4,Object.getOwnPropertySymbols(obj):返回一个数组,包含对象自身的所有 Symbol 属性的键名。

5,Reflect.ownKeys(obj):返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

super关键字

详见我的其他文章:ES6学习(2)--class的基本语法和继承

扩展运算符

上边的数组的扩展中我们已经认识了扩展运算符了。同样的,对象中也有扩展运算符,让我们汇总一下对象的扩展运算符的相关特性:

定义:对象的扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。(这里拷贝是深拷贝)在我其他的文章里也提到了此方法实现深拷贝的使用方法,有兴趣的伙伴可以去瞅瞅:JavaScript 引用数据类型的浅拷贝和深拷贝

7,运算符的扩展

指数运算符( ** )

特点:

1,运算符的一个特点是右结合,而不是常见的左结合。多个指数运算符连用时,是从最右边开始计算的。

2,指数运算符可以与等号结合,形成一个新的赋值运算符(**=)。

2 ** 3         // 8

2 ** 3 ** 2    // 512 (相当于 2 ** (3 ** 2))

let a = 1.5;
a **= 2;
// 等同于 a = a * a;

let b = 4;
b **= 3;
// 等同于 b = b * b * b;

链判断运算符( ?. )

我们经常会遇到对象含有多层结构的现象,当我们需要判断内层的某个数据时,需要层层的判断,这非常的麻烦。因此 ES2020 引入了“链判断运算符”(optional chaining operator)?.,简化多层判断多次的写法。

// 错误的写法
const  firstName = message.body.user.firstName || 'default';

// 正确的写法
const firstName = (message
  && message.body
  && message.body.user
  && message.body.user.firstName) || 'default';

// 链判断运算符的写法
const firstName = message?.body?.user?.firstName || 'default';

注意点:

1,短路机制:本质上,?.运算符相当于一种短路机制,只要不满足条件,就不再往下执行。

2,括号的影响:如果属性链有圆括号,链判断运算符对圆括号外部没有影响,只对圆括号内部有影响。一般来说,使用?.运算符的场合,不应该使用圆括号。

3,报错场合:以下写法是禁止的,会报错。

// 构造函数
new a?.()
new a?.b()

// 链判断运算符的右侧有模板字符串
a?.`{b}`
a?.b`{c}`

// 链判断运算符的左侧是 super
super?.()
super?.foo

// 链运算符用于赋值运算符左侧
a?.b = c

4,右侧不得为十进制数值:为了保证兼容以前的代码,允许foo?.3:0被解析成foo ? .3 : 0,因此规定如果?.后面紧跟一个十进制数字,那么?.不再被看成是一个完整的运算符,而会按照三元运算符进行处理,也就是说,那个小数点会归属于后面的十进制数字,形成一个小数。

Null判断运算符( ?? ) 

 Null 判断运算符??。它的行为类似||,但是只有运算符左侧的值为nullundefined时,才会返回右侧的值。 

const headerText = response.settings.headerText ?? 'Hello, world!';
const animationDuration = response.settings.animationDuration ?? 300;
const showSplashScreen = response.settings.showSplashScreen ?? true;

 逻辑赋值运算符( ||=&&=??= 

// 或赋值运算符
x ||= y
// 等同于
x || (x = y)

// 与赋值运算符
x &&= y
// 等同于
x && (x = y)

// Null 赋值运算符
x ??= y
// 等同于
x ?? (x = y)

到此结束!

以上就是函数,数组,对象,运算符的扩展内容(不是全部!!!不是全部!!!),这里只是摘取了一部分,它们在我们实际的工作中是比较常用的,希望对大家有帮助,有需要的伙伴可以在这里极快的筛选查找一下,应该可以提高一点效率。

拜了个拜!迪迦。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值