Hướng dẫn spread object javascript - lan truyền đối tượng javascript

Chào các bạn, để tiếp tục chuỗi bài về Javascript của mình, hôm nay mình sẽ viết về một operator rất hữu ích, đó là spread operator (được viết là

Math.max(...[1,3,5]) // output: 5
0). Spread operator là một cách rất hữu dụng và ngắn gọn để dùng trong các thao tác với mảng như thêm phần tử vào mảng, kết hợp mảng (hoặc object), truyền tham số mảng vào function, ... Chúng ta sẽ cùng tìm hiểu chi tiết nhé.

Spread operator là gì ?

Trong Javascript, spread operator là nói đến cách sử dụng ký hiệu dấu ba chấm

Math.max(...[1,3,5]) // output: 5
0. Theo Javascrip.info thì spread operator được định nghĩa như sau :

“When ...arr is used in the function call, it ‘expands’ an iterable object arr into the list of arguments.”

Spread operator được thêm vào từ phiên bản ES6 (ES2015), cũng như rest parameter, 2 loại operator này giống nhau về mặt cú pháp, đó là cùng sử dụng dấu

Math.max(...[1,3,5]) // output: 5
0.

Vậy thì Math.max(...[1,3,5]) // output: 5 0 dùng để làm gì ?

“Spread operator to the rescue! It looks similar to rest parameters, also using ..., but does quite the opposite.” — JavaScript.info

Mình sẽ lấy ví dụ cơ bản nhất, đó là hàm tìm số lớn nhất trong mảng như sau :

Math.max(1,3,5) // output: 5
Math.max([1,3,5]) // output: NaN

Khi chúng ta truyền một mảng 3 phần tử vào làm tham số của một hàm (ở đây là hàm Math.max()) như dòng thứ 2, chúng ta mong muốn rằng hàm này sẽ hiểu rằng chúng ta truyền vào 3 tham số riêng biệt, và tìm số lớn nhất trong 3 số này (như cách viết trong dòng thứ 2). Tất nhiên là nếu chúng ta viết như vậy thì hàm sẽ không hiểu được rồi, và sẽ cho ra output là NaN. Đây chính là lúc chúng ta cần đến

Math.max(...[1,3,5]) // output: 5
0, chỉ cần thêm dấu
Math.max(...[1,3,5]) // output: 5
0 vào phần argument, chúng ta sẽ có kết quả mong muốn

Math.max(...[1,3,5]) // output: 5

Trong trường hợp này, spread operator đã mở rộng (spread) mảng 3 phần tử thành 3 tham số riêng biệt.

Ngoài chức năng như mình đã kể ở trên, spread operator còn có rất nhiều các chức năng hữu dụng khác giúp code của chúng ta ngắn gọn và dễ nhìn hơn rất nhiều, có thể kể đến như :

  • Sao chép một mảng
  • Tách hoặc kết hợp một hay nhiều mảng
  • Sử dụng mảng như danh sách các argument
  • Thêm một item vào một list
  • Thao tác với state trong React
  • Kết hợp các objects
  • Chuyển NodeList thành một array

Những ví dụ khác về spread operator Math.max(...[1,3,5]) // output: 5 0

Sau đây mình sẽ giới thiệu tới các bạn một vài ví dụ mà spread operator có thể làm được như sao chép mảng, tách string thành các characters, hoặc là kết hợp các thuộc tính của một object

[...["😋😛😜🤪😝"]] // Array [ "😋😛😜🤪😝" ]
[..."🙂🙃😉😊😇🥰😍🤩!"] // Array(9) [ "🙂", "🙃", "😉", "😊", "😇", "🥰", "😍", "🤩", "!" ]

const hello = {hello: "😋😛😜🤪😝"}
const world = {world: "🙂🙃😉😊😇🥰😍🤩!"}

const helloWorld = {...hello,...world}
console.log(helloWorld) // Object { hello: "😋😛😜🤪😝", world: "🙂🙃😉😊😇🥰😍🤩!" }

Sao chép mảng

Với spread operator

Math.max(...[1,3,5]) // output: 5
0, chúng ta có thể sao chép mảng một cách rất ngắn gọn, bên cạnh đó việc thêm một hay nhiều phần tử vào mảng cũng rất dễ dàng :

const fruits = ['🍏','🍊','🍌','🍉','🍍']
//sao chép mảng fruits sang mảng moreFruits
const moreFruits = [...fruits]; 
console.log(moreFruits) // Array(5) [ "🍏", "🍊", "🍌", "🍉", "🍍" ]

Sử dụng mảng như danh sách các tham số

“The Math object's set of functions are a perfect example of the spread operator as the only argument to a function.” — @davidwalshblog on his blog

Một trong những cách dễ hiểu nhất để hiểu cách sử dụng của spread operator đó là các phương thức của lớp

Math.max(...[1,3,5]) // output: 5
8, ở đây mình sẽ lấy hàm
Math.max(...[1,3,5]) // output: 5
9 và
[...["😋😛😜🤪😝"]] // Array [ "😋😛😜🤪😝" ]
[..."🙂🙃😉😊😇🥰😍🤩!"] // Array(9) [ "🙂", "🙃", "😉", "😊", "😇", "🥰", "😍", "🤩", "!" ]

const hello = {hello: "😋😛😜🤪😝"}
const world = {world: "🙂🙃😉😊😇🥰😍🤩!"}

const helloWorld = {...hello,...world}
console.log(helloWorld) // Object { hello: "😋😛😜🤪😝", world: "🙂🙃😉😊😇🥰😍🤩!" }
0 làm ví dụ. Hàm này sẽ tìm số nhỏ nhất (hoặc lớn nhất) trong danh sách tham số mà chúng ta truyền vào. Số lượng tham số là tùy ý, hàm này chỉ nhận danh sách các tham số chứ không nhận tham số là mảng. Lúc này thì chúng ta có thể sử dụng spread operator:

const numbers = [37, -17, 7, 0]
console.log(Math.min(numbers)) // output là NaN do hàm này không nhận array là tham số

//Sử dụng spread operator
console.log(Math.min(...numbers)) // output: -17 
console.log(Math.max(...numbers)) // 37

Không chỉ các hàm của lớp

Math.max(...[1,3,5]) // output: 5
8, mà tất cả những hàm nào mà nhận một số lượng tùy ý các tham số thì chúng ta đều có thể sử dụng được spread operator. Mình lấy thêm một vài ví dụ nhé :

const fruitStand = ['🍏','🍊','🍌']
const sellFruit = (f1, f2, f3) => { console.log(`Fruits for sale: ${f1}, ${f2}, ${f3}`) }
sellFruit(...fruitStand) // Fruits for sale: 🍏, 🍊, 🍌
fruitStand.pop()
fruitStand.pop()
fruitStand.push('🍉')
fruitStand.push('🍍')
sellFruit(...fruitStand) // Fruits for sale: 🍏, 🍉, 🍍
fruitStand.pop()
fruitStand.pop()
sellFruit(...fruitStand,'🍋') // Fruits for sale: 🍏, 🍋, undefined

Thêm phần tử vào mảng

Như đã đề cập ở trên đây, spread operator còn có thể thêm một hay nhiều phần tử vào mảng, giúp cho đoạn code của chúng ta đơn giản và tự nhiên hơn rất nhiều so với cách viết code truyền thống như trước đây :

const fewFruit = ['🍏','🍊','🍌']
const fewMoreFruit = ['🍉', '🍍', ...fewFruit] //thêm các phần tử của mảng fewFruit vào mảng fewMoreFruit
console.log(fewMoreFruit) //  Array(5) [ "🍉", "🍍", "🍏", "🍊", "🍌" ]

Thao tác với state trong React

Kết hợp các objects

import React, { useState } from "react"
import ReactDOM from "react-dom"

import "./styles.css"

function App() {
  // Khai báo React Hook
  const [searches, setSearches] = useState([])
  const [query, setQuery] = useState("")

  const handleClick = () => {
     
    // Thêm một phần tử vào trong state searches của React Hook
    setSearches(searches => [...searches, query])
  }

Chuyển NodeList thành một array

Những ví dụ khác về spread operator

Math.max(...[1,3,5]) // output: 5
0

const objectOne = {hello: "🤪"}
const objectTwo = {world: "🐻"}

// Kết hợp objectOne, objectTwo lại trong objectThree và thêm thuộc tính laugh
const objectThree = {...objectOne, ...objectTwo, laugh: "😂"}
console.log(objectThree) // Object { hello: "🤪", world: "🐻", laugh: "😂" }

// Tương tự chúng ta có objectFour, với laugh là một hàm
const objectFour = {...objectOne, ...objectTwo, laugh: () => {console.log("😂".repeat(5))}}
objectFour.laugh() // 😂😂😂😂😂

Sau đây mình sẽ giới thiệu tới các bạn một vài ví dụ mà spread operator có thể làm được như sao chép mảng, tách string thành các characters, hoặc là kết hợp các thuộc tính của một object

Sao chép mảng

const array = ['😉','😊','😇']
const copyWithEquals = array // Thay đổi mảng array đồng nghĩa cũng sẽ thay đổi mảng copyWithEquals
const copyWithSpread = [...array] // Thay đổi mảng array sẽ không ảnh hưởng đến mảng copyWithSpread

array[0] = '😡' //thay đổi phần tử đầu tiên của mảng array

console.log(...array) // 😡 😊 😇
console.log(...copyWithEquals) // 😡 😊 😇
console.log(...copyWithSpread) // 😉 😊 😇

Với spread operator

Math.max(...[1,3,5]) // output: 5
0, chúng ta có thể sao chép mảng một cách rất ngắn gọn, bên cạnh đó việc thêm một hay nhiều phần tử vào mảng cũng rất dễ dàng :

Kết luận

Kể từ khi ra đời từ phiên bản ES6 (ES2015), spread operator

Math.max(...[1,3,5]) // output: 5
0 đã được cộng đồng lập trình viên Javascript rất yêu thích vì tính hữu dụng và ngắn gọn của nó khi thao tác với mảng và object. Bản thân mình cũng thường xuyên sử dụng nó khi làm việc với React Hooks, nhất là khi thêm một phần tử vào mảng React state.

Việc biết thêm những cú pháp mới sẽ giúp chúng ta tiết kiệm thời gian khi code, đồng thời giúp code của chúng ta trở nên dễ đọc hơn rất nhiều. Và mình hi vọng bài chia sẻ này của mình sẽ giúp ích cho các bạn trong "sự nghiệp" code đầy gian nan và vất vả của bản thân nhé

Hướng dẫn spread object javascript - lan truyền đối tượng javascript
Hướng dẫn spread object javascript - lan truyền đối tượng javascript

Tài liệu tham khảo: https://www.geeksforgeeks.org/javascript-rest-operator/ https://medium.com/coding-at-dawn/how-to-use-the-spread-operator-in-javascript-b9e4a8b06fab