js之深度理解扩展运算符(Spread Operator)

字符串扩展中的使用

展开字符串 字符串转数组

console.log(...'helloworld') // h e l l o w o r l d

console.log([...'helloworld']) // [ 'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd' ]

数组扩展中的使用

展开数组 解构赋值 复制数组 合并数组

   注:如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错

//展开数组
let num = [1, 2, 3]
console.log(...num) //123

console.log(...[4, [1, 2, 3], 5]) //每次只能展开一层

//解构赋值
let [a, ...rest] = num
console.log(a, rest) //1 [2,3]

// 复制数组
let a = [1, 2]
let b = [...a]
console.log(b)

// 合并数组
console.log([0, ...[1, 2]])



对象字面量中的扩展

展开对象

数组可以直接扩展 对象扩展需要{}包裹

let obj = { a: 1, b: 2 } 
console.log(...obj) // 报错对象需要{}包裹
console.log({ ...obj }) // {a:1,b:2}

合并对象

let foo = { c: 3, ...obj }
console.log(foo) // {c:3,a:1,b:2}
// 等同于let foo = Object.assign(obj, { c: 3 })

扩展在函数中的使用

arguments和...args的区别

结论arguments 是一个对象,包含所有传入的参数可以通过...arguments获取,而 args 是一个数组,包含所有传入的参数可以通过...args获取

但直接这样写会报错

let [a] = ...arguments //报错

let [b] = ...args  //报错

故需要使用在外面包裹一层【】以防止报错

let [a] = [..arguments]

let [b] = [...args]

arguments传入参数为字符串 字面量对象 可使用[...arguments]获取

arguments传入参数为数组  可使用[...arguments][0]获取

...args传入参数为字符串 可使用[...args]获取

...args传入参数为数组  字面量对象 可使用[...args][0]获取

// 结论:arguments 是一个对象,包含所有传入的参数可以通过...arguments获取,而 ...args 是一个数组,包含所有传入的参数
function logArgs1() {
  console.log(arguments); //[Arguments] { '0': 1, '1': 2 }   arguments 是一个对象,包含所有传入的参数
  console.log([...arguments]) // [ 1, 2 ]
  console.log(...arguments) // 1 2
}
logArgs1(1, 2)

function logArgs2() {
  console.log(arguments); //[Arguments]{ '0': { a: 1, b: 2 } }  arguments 是一个对象,包含所有传入的参数
  console.log([...arguments]) // [ { a: 1, b: 2 } ]
  console.log(...arguments) // { a: 1, b: 2 }
  let [obj] = [...arguments]
  console.log(obj, obj.a, obj.b) // { a: 1, b: 2 } 1 2
}
logArgs2({ a: 1, b: 2 })
function logArgs3() {
  console.log(arguments); //[Arguments]{ '0': [ 3, 4 ] }  arguments 是一个对象,包含所有传入的参数
  console.log([...arguments]) //[ [ 3, 4 ] ]
  console.log(...arguments) // [ 3, 4 ]
}
logArgs3([3, 4])


function args1(...args) {
  console.log(args); //[ 1, 2 ]
  console.log(...args) // 1 2
  console.log([...args]) // [ 1, 2 ]

}
args1(1, 2)
function args2(...args) {
  console.log(args); //[ { a: 1, b: 2 } ]
  console.log(...args) //{ a: 1, b: 2 }
  console.log([...args]) //[ { a: 1, b: 2 } ]
  let { a, b } = [...args][0]
  console.log(a, b) // 1 2

}
args2({ a: 1, b: 2 })
function args3(...args) {
  console.log(args); //[ [ 3, 4 ] ] // args 是一个数组,包含所有传入的参数
  console.log(...args) //[ 3, 4 ]
  console.log([...args]) //[ [ 3, 4 ] ]
  let [a, b] = [...args][0]
  console.log(a, b) // 3 4
}
args3([3, 4])

使用...args改造普通函数

function sum(a, b, c) {
  return a + b + c;
}
console.log(sum(1, 2, 3)); // 输出 6


function sum1(...args) {
  let [a, b, c] = args;
  return a + b + c;
}
console.log(sum1(1, 2, 3));

使用剩余参数与普通参数结合

  • 剩余参数只能出现在参数列表的最后
  • 如果没有传入额外的参数,剩余参数将是一个空数组。
  • 剩余参数只收集位置参数;关键字参数(比如默认参数、解构参数等)不会被收集。
function greet(first, last, ...messages) {
  console.log(`Hello ${first} ${last}`); //Hello Alice Doe
  let [a, b] = [...messages] 
  console.log(a, b) //How are you? Nice to meet you.

}
function greet1(first, last, ...messages) {
  console.log(`Hello ${first} ${last}`); //Hello Alice Doe
  console.log(messages) //[]
  console.log([...messages])//[]

}

greet('Alice', 'Doe', 'How are you?', 'Nice to meet you.');
greet1('Alice', 'Doe');
let cameraInfo1 = {
  id: 0,
  channelNo: "34020000001320000067",
}

let cameraInfo2 = [3, 4]
function getCameraInfo(...args) {
  let { id, channelNo } = [...args][0]
  console.log(id, channelNo) // 0 34020000001320000067
}
function getCameraInfo2(...args) {
  console.log('2==>', args) // 2==> [ [ 3, 4 ], [ 3, 4 ] ]
  console.log('2==>', args[0], args[1]) //2==> [ 3, 4 ] [ 3, 4 ]
}
getCameraInfo(cameraInfo1)
getCameraInfo2(cameraInfo2, cameraInfo2)

扩展在class类中的使用

类的构造函数(constructor)中使用剩余参数

let cameraInfo1 = {
  id: 0,
  channelNo: "34020000001320000067",
}

class Test {
  constructor(...args) {
    let { id, channelNo } = args[0]
    this.id = id
    this.channelNo = channelNo
  }
  run() {
    console.log('test1', this.id, this.channelNo)

  }
}



const test = new Test(cameraInfo1)
test.run()
// 输出:
// test1 0 34020000001320000067

类的构造函数(constructor)中使用默认参数和剩余参数

  • 剩余参数必须是构造函数参数列表中的最后一个参数。
  • 如果没有提供额外的参数,hobbies 将会是一个空数组。
  • 你可以结合使用默认参数和剩余参数,使得构造函数更加灵活。
class Person {
  constructor(name, age, ...hobbies) {
    this.name = name;
    this.age = age;
    console.log(hobbies[0])

    if (Array.isArray([...hobbies][0])) {
      let [x, y] = hobbies[0]
      this.x = x
      this.y = y
    } else if (this.isObject(hobbies[0])) {
      let { x, y } = hobbies[0]
      this.x = x
      this.y = y
    }
  }
  // Object.prototype.toString.call() 方法可以更准确地检测对象类型,因为它会返回一个表示对象类型的字符串,包括内置类型
  isObject(obj) {
    return Object.prototype.toString.call(obj) === '[object Object]';
  }
  // 如果你只想检测是否是一个数组,可以使用 Array.isArray 方法  Array.isArray(obj)。
   // 检测对象和数组 obj !== null && typeof obj === 'object' && obj instanceof Object

  introduce() {
    console.log(`name ${this.name}, age ${this.age},xy ${this.x},${this.y}`);
    if (this.x) {
      console.log('xy存在', this.x, this.y)

    }
  }
}


// 创建一个Person实例
const bob = new Person('Bob', 25);
bob.introduce();
// 输出:
// undefined
// name Bob, age 25,xy undefined,undefined

const alice = new Person('Alice', 30, { x: 100, y: 200 });
alice.introduce();
// 输出:
// { x: 100, y: 200 }
// name Alice, age 30,xy 100,200
// xy存在 100 200

检测对象

1. 使用 Array.isArray检测是否是数组

如果你只想检测是否是一个数组,可以使用 Array.isArray 方法。

function isArray(obj) {
    return Array.isArray(obj);
}

console.log(isArray({})); // false
console.log(isArray([])); // true
console.log(isArray(null)); // false
console.log(isArray(42)); // false
console.log(isArray('')); // false

2. 使用 toString 方法检测是否为对象

Object.prototype.toString.call() 方法可以更准确地检测对象类型,因为它会返回一个表示对象类型的字符串,包括内置类型。

function isObject(obj) {
    return Object.prototype.toString.call(obj) === '[object Object]';
}

console.log(isObject({})); // true
console.log(isObject([])); // false
console.log(isObject(null)); // false
console.log(isObject(42)); // false
console.log(isObject('')); // false

3. 结合使用 typeof 和 instanceof检测对象和数组

为了确保准确性,你也可以结合使用 typeofinstanceof

function isObject(obj) {
    return obj !== null && typeof obj === 'object' && obj instanceof Object;
}

console.log(isObject({})); // true
console.log(isObject([])); // true
console.log(isObject(null)); // false
console.log(isObject(42)); // false
console.log(isObject('')); // false

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值