HomeLập trìnhJavaScriptJavaScript Rest vs...

JavaScript Rest vs Spread Operator – Đâu là sự khác biệt?


JavaScript sử dụng dấu ba chấm (...) cho cả toán tử còn lại và trải rộng. Nhưng hai toán tử này không giống nhau.

Sự khác biệt chính giữa phần còn lại và trải rộng là toán tử phần còn lại đặt phần còn lại của một số giá trị cụ thể do người dùng cung cấp vào một mảng JavaScript. Nhưng cú pháp trải rộng mở rộng các lần lặp thành các phần tử riêng lẻ.

Chẳng hạn, hãy xem đoạn mã này sử dụng phần còn lại để đặt một số giá trị vào một mảng:

// Use rest to enclose the rest of specific user-supplied values into an array:
function myBio(firstName, lastName, ...otherInfo) { 
  return otherInfo;
}

// Invoke myBio function while passing five arguments to its parameters:
myBio("Oluwatobi", "Sofela", "CodeSweetly", "Web Developer", "Male");

// The invocation above will return:
["CodeSweetly", "Web Developer", "Male"]

Hãy dùng thử trên StackBlitz

Trong đoạn mã trên, chúng tôi đã sử dụng ...otherInfo tham số còn lại để đặt "CodeSweetly", "Web Developer""Male" thành một mảng.

Bây giờ, hãy xem xét ví dụ về toán tử trải phổ này:

// Define a function with three parameters:
function myBio(firstName, lastName, company) { 
  return `${firstName} ${lastName} runs ${company}`;
}

// Use spread to expand an array’s items into individual arguments:
myBio(...["Oluwatobi", "Sofela", "CodeSweetly"]);

// The invocation above will return:
“Oluwatobi Sofela runs CodeSweetly”

Hãy dùng thử trên StackBlitz

Trong đoạn mã trên, chúng tôi đã sử dụng toán tử trải rộng (...) lây lan ["Oluwatobi", "Sofela", "CodeSweetly"]nội dung của trên myBio()thông số của.

Đừng lo lắng nếu bạn chưa hiểu phần còn lại hoặc các toán tử trải rộng. Bài viết này đã có bạn bảo hiểm!

Trong các phần tiếp theo, chúng ta sẽ thảo luận về cách hoạt động của phần còn lại và trải rộng trong JavaScript.

Vì vậy, không cần phải bận tâm thêm nữa, hãy bắt đầu với toán tử còn lại.

Chính xác thì toán tử còn lại là gì?

Các nhà điều hành phần còn lại được sử dụng để đặt phần còn lại của một số giá trị cụ thể do người dùng cung cấp vào một mảng JavaScript.

Vì vậy, ví dụ, đây là cú pháp còn lại:

...yourValues

Dấu ba chấm (...) trong đoạn mã trên tượng trưng cho toán tử còn lại.

Văn bản sau toán tử còn lại tham chiếu các giá trị bạn muốn đặt bên trong một mảng. Bạn chỉ có thể sử dụng nó trước tham số cuối cùng trong định nghĩa hàm.

Để hiểu rõ hơn về cú pháp, hãy xem phần còn lại hoạt động như thế nào với các hàm JavaScript.

Toán tử còn lại hoạt động như thế nào trong một chức năng?

Trong các hàm JavaScript, phần còn lại được sử dụng làm tiền tố cho tham số cuối cùng của hàm.

Đây là một ví dụ:

// Define a function with two regular parameters and one rest parameter:
function myBio(firstName, lastName, ...otherInfo) { 
  return otherInfo;
}

Toán tử còn lại (...) hướng dẫn máy tính thêm bất cứ thứ gì otherInfo (đối số) do người dùng cung cấp thành một mảng. Sau đó, gán mảng đó cho otherInfo tham số.

Như vậy, chúng tôi gọi ...otherInfo một tham số nghỉ ngơi.

Ghi chú: Đối số là các giá trị tùy chọn mà bạn có thể chuyển đến tham số của hàm thông qua bộ gọi.

Đây là một ví dụ khác:

// Define a function with two regular parameters and one rest parameter:
function myBio(firstName, lastName, ...otherInfo) { 
  return otherInfo;
}

// Invoke myBio function while passing five arguments to its parameters:
myBio("Oluwatobi", "Sofela", "CodeSweetly", "Web Developer", "Male");

// The invocation above will return:
["CodeSweetly", "Web Developer", "Male"]

Hãy dùng thử trên StackBlitz

Trong đoạn mã trên, lưu ý rằng myBiolời gọi của nó đã truyền năm đối số cho hàm.

Nói cách khác, "Oluwatobi""Sofela" được giao cho firstNamelastName thông số.

Đồng thời, toán tử còn lại đã thêm các đối số còn lại ( "CodeSweetly", "Web Developer""Male") thành một mảng và gán mảng đó cho otherInfo tham số.

Đọc thêm  Cách tạo biểu đồ thanh phân kỳ bằng thư viện biểu đồ JavaScript

Vì vậy, myBio() chức năng trả lại chính xác ["CodeSweetly", "Web Developer", "Male"] như nội dung của otherInfo thông số nghỉ ngơi.

Hãy coi chừng! Bạn không thể dùng nó “use strict” Bên trong một hàm chứa tham số nghỉ

Hãy nhớ rằng bạn không thể sử dụng “use strict” chỉ thị bên trong bất kỳ hàm nào chứa tham số nghỉ, tham số mặc định hoặc tham số phá hủy. Nếu không, máy tính sẽ báo lỗi cú pháp.

Chẳng hạn, hãy xem xét ví dụ dưới đây:

// Define a function with one rest parameter:
function printMyName(...value) {
  "use strict";
  return value;
}

// The definition above will return:
"Uncaught SyntaxError: Illegal 'use strict' directive in function with non-simple parameter list"

Dùng thử trên CodeSandbox

printMyName() đã trả về lỗi cú pháp vì chúng tôi đã sử dụng “use strict” chỉ thị bên trong một chức năng với một tham số còn lại.

Nhưng giả sử bạn cần chức năng của mình ở chế độ nghiêm ngặt đồng thời sử dụng tham số còn lại. Trong trường hợp như vậy, bạn có thể viết “use strict” chỉ thị bên ngoài chức năng.

Đây là một ví dụ:

// Define a “use strict” directive outside your function:
"use strict";

// Define a function with one rest parameter:
function printMyName(...value) {
  return value;
}

// Invoke the printMyName function while passing two arguments to its parameters:
printMyName("Oluwatobi", "Sofela");

// The invocation above will return:
["Oluwatobi", "Sofela"]

Dùng thử trên CodeSandbox

Ghi chú: Chỉ đặt các “use strict” chỉ thị bên ngoài chức năng của bạn nếu toàn bộ tập lệnh hoặc phạm vi kèm theo ở chế độ nghiêm ngặt là được.

Vì vậy, bây giờ chúng ta đã biết cách thức hoạt động của phần còn lại trong một hàm, chúng ta có thể nói về cách thức hoạt động của nó trong một phép gán phá hủy.

Cách toán tử còn lại hoạt động trong nhiệm vụ hủy cấu trúc

Toán tử còn lại thường được sử dụng làm tiền tố của biến cuối cùng của phép gán hủy.

Đây là một ví dụ:

// Define a destructuring array with two regular variables and one rest variable:
const [firstName, lastName, ...otherInfo] = [
  "Oluwatobi", "Sofela", "CodeSweetly", "Web Developer", "Male"
];

// Invoke the otherInfo variable:
console.log(otherInfo); 

// The invocation above will return:
["CodeSweetly", "Web Developer", "Male"]

Hãy dùng thử trên StackBlitz

Toán tử còn lại (...) hướng dẫn máy tính thêm phần còn lại của các giá trị do người dùng cung cấp vào một mảng. Sau đó, nó gán mảng đó cho otherInfo Biến đổi.

Như vậy, bạn có thể gọi ...otherInfo một biến nghỉ ngơi.

Đây là một ví dụ khác:

// Define a destructuring object with two regular variables and one rest variable:
const { firstName, lastName, ...otherInfo } = {
  firstName: "Oluwatobi",
  lastName: "Sofela", 
  companyName: "CodeSweetly",
  profession: "Web Developer",
  gender: "Male"
}

// Invoke the otherInfo variable:
console.log(otherInfo);

// The invocation above will return:
{companyName: "CodeSweetly", profession: "Web Developer", gender: "Male"}

Hãy dùng thử trên StackBlitz

Trong đoạn mã trên, lưu ý rằng toán tử còn lại đã gán một đối tượng thuộc tính — không phải một mảng — cho otherInfo Biến đổi.

Nói cách khác, bất cứ khi nào bạn sử dụng phần còn lại trong một đối tượng phá hủy, toán tử phần còn lại sẽ tạo ra một đối tượng thuộc tính.

Tuy nhiên, nếu bạn sử dụng phần còn lại trong một mảng hoặc hàm phá hủy, thì toán tử sẽ mang lại một mảng bằng chữ.

Trước khi chúng tôi kết thúc cuộc thảo luận của mình về phần còn lại, bạn nên biết một số khác biệt giữa các đối số JavaScript và tham số phần còn lại. Vì vậy, hãy nói về điều đó dưới đây.

Đối số so với Tham số còn lại: Sự khác biệt là gì?

Dưới đây là một số khác biệt giữa đối số JavaScript và tham số còn lại:

Sự khác biệt 1: Các arguments đối tượng là một đối tượng giống như mảng — không phải là một mảng thực!

Hãy nhớ rằng đối tượng đối số JavaScript không phải là một mảng thực. Thay vào đó, nó là một đối tượng dạng mảng không có các tính năng toàn diện của một mảng JavaScript thông thường.

Tuy nhiên, tham số còn lại là một đối tượng mảng thực. Như vậy, bạn có thể sử dụng tất cả các phương thức mảng trên đó.

Vì vậy, ví dụ, bạn có thể gọi sort(), map(), forEach()hoặc pop() phương pháp trên một tham số nghỉ ngơi. Nhưng bạn không thể làm điều tương tự trên đối tượng đối số.

Sự khác biệt 2: Bạn không thể sử dụng arguments đối tượng trong một chức năng mũi tên

Các arguments đối tượng không khả dụng trong chức năng mũi tên, vì vậy bạn không thể sử dụng nó ở đó. Nhưng bạn có thể sử dụng tham số còn lại trong tất cả các chức năng — bao gồm cả chức năng mũi tên.

Sự khác biệt 3: Hãy nghỉ ngơi theo sở thích của bạn

Tốt nhất là sử dụng các tham số còn lại thay vì arguments đối tượng — đặc biệt là khi viết mã tương thích với ES6.

Bây giờ chúng ta đã biết nghỉ ngơi hoạt động như thế nào, hãy thảo luận về spread toán tử để chúng ta có thể thấy sự khác biệt.

Toán tử lây lan là gì và hoạt động như thế nào spread làm việc trong JavaScript?

Các toán tử lây lan (...) giúp bạn mở rộng các lần lặp thành các phần tử riêng lẻ.

Cú pháp trải rộng hoạt động trong các ký tự mảng, các lệnh gọi hàm và các đối tượng thuộc tính được khởi tạo để trải các giá trị của các đối tượng có thể lặp lại thành các mục riêng biệt. Vì vậy, nó làm điều ngược lại với toán tử còn lại.

Đọc thêm  Giải thích về Tuyên bố nhãn, Tuyên bố tiếp tục và Tuyên bố ngắt

Ghi chú: Toán tử trải rộng chỉ có hiệu quả khi được sử dụng trong các ký tự mảng, lệnh gọi hàm hoặc đối tượng thuộc tính được khởi tạo.

Vì vậy, chính xác điều này có nghĩa là gì? Hãy xem với một số ví dụ.

Ví dụ về trải rộng 1: Cách thức hoạt động của trải rộng trong một mảng chữ

const myName = ["Sofela", "is", "my"];
const aboutMe = ["Oluwatobi", ...myName, "name."];

console.log(aboutMe);

// The invocation above will return:
[ "Oluwatobi", "Sofela", "is", "my", "name." ]

Hãy dùng thử trên StackBlitz

Đoạn mã trên đã sử dụng trải rộng (...) để sao chép myName mảng vào aboutMe.

Ghi chú:

  • thay đổi để myName sẽ không phản ánh trong aboutMe bởi vì tất cả các giá trị bên trong myName là nguyên thủy. Do đó, toán tử trải rộng chỉ cần sao chép và dán myNamenội dung của vào aboutMe mà không tạo bất kỳ tham chiếu nào trở lại mảng ban đầu.
  • Như @nombrekeff đã đề cập trong một nhận xét ở đây, toán tử trải rộng chỉ thực hiện bản sao nông. Vì vậy, hãy nhớ rằng giả sử myName chứa bất kỳ giá trị không nguyên thủy nào, máy tính sẽ tạo một tham chiếu giữa myNameaboutMe. Xem thông tin 3 để biết thêm về cách hoạt động của toán tử trải rộng với các giá trị nguyên thủy và không nguyên thủy.
  • Giả sử chúng ta không sử dụng cú pháp lây lan để nhân đôi myNamenội dung của. Ví dụ, nếu chúng ta đã viết const aboutMe = ["Oluwatobi", myName, "name."]. Trong trường hợp như vậy, máy tính sẽ gán một tham chiếu trở lại myName. Như vậy, bất kỳ thay đổi nào được thực hiện trong mảng ban đầu sẽ phản ánh trong mảng trùng lặp.

Ví dụ 2 về trải rộng: Cách sử dụng trải rộng để chuyển đổi một chuỗi thành các mục mảng riêng lẻ

const myName = "Oluwatobi Sofela";

console.log([...myName]);

// The invocation above will return:
[ "O", "l", "u", "w", "a", "t", "o", "b", "i", " ", "S", "o", "f", "e", "l", "a" ]

Hãy dùng thử trên StackBlitz

Trong đoạn mã trên, chúng tôi đã sử dụng cú pháp lây lan (...) trong một đối tượng chữ mảng ([...]) mở rộng myNamegiá trị chuỗi của thành các mục riêng lẻ.

Như vậy, "Oluwatobi Sofela" được mở rộng thành [ "O", "l", "u", "w", "a", "t", "o", "b", "i", " ", "S", "o", "f", "e", "l", "a" ].

Ví dụ 3 về trải rộng: Toán tử trải rộng hoạt động như thế nào trong một lệnh gọi hàm

const numbers = [1, 3, 5, 7];

function addNumbers(a, b, c, d) {
  return a + b + c + d;
}

console.log(addNumbers(...numbers));

// The invocation above will return:
16

Hãy dùng thử trên StackBlitz

Trong đoạn mã trên, chúng tôi đã sử dụng cú pháp trải rộng để trải rộng numbers nội dung của mảng trên addNumbers()thông số của.

Giả sử numbers mảng có nhiều hơn bốn mục. Trong trường hợp này, máy tính sẽ chỉ sử dụng bốn mục đầu tiên làm addNumbers() lập luận và bỏ qua phần còn lại.

Đây là một ví dụ:

const numbers = [1, 3, 5, 7, 10, 200, 90, 59];

function addNumbers(a, b, c, d) {
  return a + b + c + d;
}

console.log(addNumbers(...numbers));

// The invocation above will return:
16

Hãy dùng thử trên StackBlitz

Đây là một ví dụ khác:

const myName = "Oluwatobi Sofela";

function spellName(a, b, c) {
  return a + b + c;
}

console.log(spellName(...myName));      // returns: "Olu"

console.log(spellName(...myName[3]));   // returns: "wundefinedundefined"

console.log(spellName([...myName]));    // returns: "O,l,u,w,a,t,o,b,i, ,S,o,f,e,l,aundefinedundefined"

console.log(spellName({...myName}));    // returns: "[object Object]undefinedundefined"

Hãy dùng thử trên StackBlitz

Ví dụ về trải rộng 4: Cách thức hoạt động của trải rộng trong một đối tượng theo nghĩa đen

const myNames = ["Oluwatobi", "Sofela"];
const bio = { ...myNames, runs: "codesweetly.com" };

console.log(bio);

// The invocation above will return:
{ 0: "Oluwatobi", 1: "Sofela", runs: "codesweetly.com" }

Hãy dùng thử trên StackBlitz

Trong đoạn mã trên, chúng tôi đã sử dụng trải rộng bên trong bio đối tượng mở rộng myNames các giá trị thành các thuộc tính riêng lẻ.

Những điều cần biết về toán tử lây lan

Hãy ghi nhớ ba thông tin cần thiết này bất cứ khi nào bạn chọn sử dụng toán tử chênh lệch.

Thông tin 1: Toán tử trải rộng không thể mở rộng giá trị của đối tượng bằng chữ

Vì đối tượng thuộc tính không phải là đối tượng có thể lặp lại nên bạn không thể sử dụng toán tử trải rộng để mở rộng giá trị của nó.

Tuy nhiên, bạn có thể sử dụng toán tử trải rộng để sao chép các thuộc tính từ đối tượng này sang đối tượng khác.

Đây là một ví dụ:

const myName = { firstName: "Oluwatobi", lastName: "Sofela" };
const bio = { ...myName, website: "codesweetly.com" };

console.log(bio);

// The invocation above will return:
{ firstName: "Oluwatobi", lastName: "Sofela", website: "codesweetly.com" };

Hãy dùng thử trên StackBlitz

Đoạn mã trên đã sử dụng toán tử trải rộng để sao chép myNamenội dung của vào bio vật.

Ghi chú:

  • Toán tử trải rộng chỉ có thể mở rộng giá trị của các đối tượng có thể lặp lại.
  • Một đối tượng chỉ có thể lặp lại nếu nó (hoặc bất kỳ đối tượng nào trong chuỗi nguyên mẫu của nó) có một thuộc tính với khóa @@ iterator.
  • Array, TypedArray, String, Map và Set đều là các kiểu có thể lặp lại tích hợp sẵn vì chúng có @@iterator tài sản theo mặc định.
  • Đối tượng thuộc tính không phải là kiểu dữ liệu có thể lặp lại vì nó không có @@iterator tài sản theo mặc định.
  • Bạn có thể làm cho một đối tượng thuộc tính có thể lặp lại bằng cách thêm @@iterator lên nó.

Thông tin 2: Toán tử trải rộng không sao chép các thuộc tính giống hệt nhau

Giả sử bạn đã sử dụng toán tử trải rộng để sao chép các thuộc tính từ đối tượng A sang đối tượng B. Và giả sử đối tượng B chứa các thuộc tính giống hệt với các thuộc tính trong đối tượng A. Trong trường hợp này, các phiên bản của B sẽ ghi đè lên các phiên bản bên trong A.

Đọc thêm  Cách chuyển đổi chuỗi thành số trong JavaScript (kèm ví dụ)

Đây là một ví dụ:

const myName = { firstName: "Tobi", lastName: "Sofela" };
const bio = { ...myName, firstName: "Oluwatobi", website: "codesweetly.com" };

console.log(bio);

// The invocation above will return:
{ firstName: "Oluwatobi", lastName: "Sofela", website: "codesweetly.com" };

Hãy dùng thử trên StackBlitz

Quan sát rằng toán tử trải rộng không sao chép myName‘S firstName tài sản vào bio đối tượng vì bio đã chứa một firstName tài sản.

Thông tin 3: Cẩn thận với cách hoạt động của trải rộng khi được sử dụng trên các đối tượng chứa các phần tử không nguyên thủy!

Giả sử bạn đã sử dụng toán tử trải rộng trên một đối tượng (hoặc mảng) chỉ chứa các giá trị nguyên thủy. Máy tính sẽ không phải tạo bất kỳ tham chiếu nào giữa đối tượng gốc và đối tượng trùng lặp.

Chẳng hạn, hãy xem xét mã này bên dưới:

const myName = ["Sofela", "is", "my"];
const aboutMe = ["Oluwatobi", ...myName, "name."];

console.log(aboutMe);

// The invocation above will return:
["Oluwatobi", "Sofela", "is", "my", "name."]

Hãy dùng thử trên StackBlitz

Quan sát rằng mọi mục trong myName là một giá trị nguyên thủy. Do đó, khi chúng tôi sử dụng toán tử trải rộng để sao chép myName vào trong aboutMemáy tính không tạo bất kỳ tham chiếu nào giữa hai mảng.

Như vậy, bất kỳ thay đổi nào bạn thực hiện đối với myName sẽ không phản ánh trong aboutMevà ngược lại.

Ví dụ, hãy thêm nhiều nội dung hơn vào myName:

myName.push("real");

Bây giờ, hãy kiểm tra trạng thái hiện tại của myNameaboutMe:

console.log(myName); // ["Sofela", "is", "my", "real"]

console.log(aboutMe); // ["Oluwatobi", "Sofela", "is", "my", "name."]

Hãy dùng thử trên StackBlitz

Thông báo rằng myNamenội dung cập nhật của không phản ánh trong aboutMe – bởi vì sự lây lan không tạo ra tham chiếu nào giữa mảng ban đầu và mảng trùng lặp.

Chuyện gì xảy ra nếu myName chứa các mục không nguyên thủy?

Giả sử myName chứa không nguyên thủy. Trong trường hợp đó, trải rộng sẽ tạo ra một tham chiếu giữa bản gốc không nguyên thủy và bản sao.

Đây là một ví dụ:

const myName = [["Sofela", "is", "my"]];
const aboutMe = ["Oluwatobi", ...myName, "name."];

console.log(aboutMe);

// The invocation above will return:
[ "Oluwatobi", ["Sofela", "is", "my"], "name." ]

Hãy dùng thử trên StackBlitz

quan sát rằng myName chứa một giá trị không nguyên thủy.

Do đó, sử dụng toán tử trải rộng để sao chép myNamenội dung của vào aboutMe khiến máy tính tạo tham chiếu giữa hai mảng.

Như vậy, bất kỳ thay đổi nào bạn thực hiện đối với myNamebản sao của sẽ phản ánh trong aboutMephiên bản của nó và ngược lại.

Ví dụ, hãy thêm nhiều nội dung hơn vào myName:

myName[0].push("real");

Bây giờ, hãy kiểm tra trạng thái hiện tại của myNameaboutMe:

console.log(myName); // [["Sofela", "is", "my", "real"]]

console.log(aboutMe); // ["Oluwatobi", ["Sofela", "is", "my", "real"], "name."]

Hãy dùng thử trên StackBlitz

Thông báo rằng myNamenội dung cập nhật của được phản ánh trong aboutMe — bởi vì spread đã tạo tham chiếu giữa mảng ban đầu và mảng trùng lặp.

Đây là một ví dụ khác:

const myName = { firstName: "Oluwatobi", lastName: "Sofela" };
const bio = { ...myName };

myName.firstName = "Tobi";

console.log(myName); // { firstName: "Tobi", lastName: "Sofela" }

console.log(bio); // { firstName: "Oluwatobi", lastName: "Sofela" }

Hãy dùng thử trên StackBlitz

Trong đoạn trích trên, myNamecập nhật của không phản ánh trong bio bởi vì chúng tôi đã sử dụng toán tử trải rộng trên một đối tượng chỉ chứa các giá trị nguyên thủy.

Ghi chú: Một nhà phát triển sẽ gọi myName một đối tượng nông bởi vì nó chỉ chứa các mục nguyên thủy.

Đây là một ví dụ nữa:

const myName = { 
  fullName: { firstName: "Oluwatobi", lastName: "Sofela" }
};

const bio = { ...myName };

myName.fullName.firstName = "Tobi";

console.log(myName); // { fullName: { firstName: "Tobi", lastName: "Sofela" } }

console.log(bio); // { fullName: { firstName: "Tobi", lastName: "Sofela" } }

Hãy dùng thử trên StackBlitz

Trong đoạn trích trên, myNamecập nhật của được phản ánh trong bio bởi vì chúng tôi đã sử dụng toán tử trải rộng trên một đối tượng chứa giá trị không nguyên thủy.

Ghi chú:

  • Chúng tôi gọi myName một đối tượng sâu bởi vì nó chứa một mục không nguyên thủy.
  • Bạn làm bản sao nông khi bạn tạo các tham chiếu trong khi sao chép một đối tượng vào một đối tượng khác. Ví dụ, ...myName tạo ra một bản sao nông của myName đối tượng vì bất kỳ thay đổi nào bạn thực hiện trong cái này sẽ phản ánh trong cái kia.
  • Bạn làm sao chép sâu khi bạn sao chép các đối tượng mà không tạo tham chiếu. Chẳng hạn, tôi có thể sao chép sâu myName vào trong bio bằng cách làm const bio = JSON.parse(JSON.stringify(myName)). Làm như vậy, máy tính sẽ nhân bản myName vào trong bio không có tạo bất kỳ tài liệu tham khảo.
  • Bạn có thể ngắt tham chiếu giữa hai đối tượng bằng cách thay thế fullName đối tượng bên trong myName hoặc bio với một đối tượng mới. Ví dụ, làm myName.fullName = { firstName: "Tobi", lastName: "Sofela" } sẽ ngắt kết nối con trỏ giữa myNamebio.

gói nó lên

Bài viết này đã thảo luận về sự khác biệt giữa các toán tử còn lại và trải rộng. Chúng tôi cũng đã sử dụng các ví dụ để xem cách hoạt động của từng toán tử.

Cảm ơn vì đã đọc!



Zik.vn – Biên dịch & Biên soạn Lại

spot_img

Create a website from scratch

Just drag and drop elements in a page to get started with Newspaper Theme.

Buy Now ⟶

Bài viết liên quang

DMCA.com Protection Status