Những câu hỏi hay trong Javascript Phần 4

MVT
Đang cập nhật

Tiếp nối với 3 phần trước trong series Những câu hỏi hay trong Javascript, rất vui khi trở lại đây cùng các bạn trong phần 4, dưới đây sẽ là danh sách các câu hỏi và đáp án theo thứ tự tiếp nối với phần 1, 2 và 3.

76. generator function hoạt động như thế nào?

function* startGame() {
  const answer = yield 'Do you love JavaScript?';
  if (answer !== 'Yes') {
    return "Oh wow... Guess we're gone here";
  }
  return 'JavaScript loves you back ❤️';
}

const game = startGame();
console.log(/* 1 */); // Do you love JavaScript?
console.log(/* 2 */); // JavaScript loves you back ❤️

A: game.next("Yes").value and game.next().value

B: game.next.value("Yes") and game.next.value()

C: game.next().value and game.next("Yes").value

D: game.next.value() and game.next.value("Yes")

Generator function "tạm dừng" thực thi khi thấy từ khóa yield. Đầu tiên, chúng ta phải để hàm tạo ra chuỗi "Do you love JavaScript?", điều này có thể được thực hiện bằng cách gọi game.next().value

Mọi dòng được thực thi, cho đến khi nó tìm thấy từ khóa yield đầu tiên. Điều này có nghĩa là biến answer vẫn chưa được xác định!

Đến khi chúng ta gọi game.next("Yes").value, thì yield lần trước sẽ được thay thế bằng giá trị của những tham số được truyền qua hàm next(). là "Yes" trong trường hợp này. Giá trị của biến answer bây giờ là "Yes". Điều kiện của câu lệnh if trả về false, và 'JavaScript loves you back ❤️' được log ra.

77. Kết quả dưới đây là gì?

async function getData() {
  return await Promise.resolve('I made it!');
}

const data = getData();
console.log(data);

A: "I made it!"

B: Promise {<resolved>: "I made it!"}

C: Promise {<pending>}

D: undefined

async function luôn trả về một lời hứa. await vẫn phải đợi lời hứa sẽ giải quyết xong : một lời hứa đang chờ xử lý được trả lại khi chúng ta gọi getData() để thiết lập data bằng với nó

Nếu bạn muốn có quyền truy cập vào giá trị đã được resolved "I made it!", bạn có thể sử dụng phương thức then phía sau data: data.then(res => console.log(res)) nó sẽ log ra giá trị "I made it!"

78. Kết quả dưới đây là gì?

function addToList(item, list) {
  return list.push(item);
}

const result = addToList('apple', ['banana']);
console.log(result);

A: ['apple', 'banana']

B: 2

C: true

D: undefined

Phương thức push() trả về độ dài của mảng mới. Trước đó, mảng chứa một phần tử (chuỗi "banana") và có độ dài là 1. Sau khi thêm chuỗi "apple" vào mảng, mảng chứa hai phần tử và có độ dài là 2. Điều này được trả về từ hàm addToList.

Phương thức push() sửa đổi mảng ban đầu. Nếu bạn muốn trả về mảng từ hàm thay vì độ dài của mảng, bạn nên trả về danh sách sau khi đẩy item vào nó.

79. Object.freeze có tác dụng gì?

const box = { x: 10, y: 20 };

Object.freeze(box);

const shape = box;
shape.x = 100;

console.log(shape);

Object.freeze làm cho đối tượng đó không thể thêm, bớt hoặc sửa đổi các thuộc tính của nó (trừ khi giá trị của thuộc tính là một đối tượng khác).

Khi chúng tạo biến shape và đặt nó vào trong object box được dưới dạng freeze, shape cũng tham chiếu đến đối tượng được đóng băng. Bạn có thể kiểm tra xem một đối tượng có bị đóng băng hay không bằng cách sử dụng Object.isFrozen. Trong trường hợp này, Object.isFrozen(shape) trả về true, vì biến shape có một tham chiếu đến một đối tượng được đóng băng.

Vì biến shape bị đóng băng và vì giá trị của x không phải là một đối tượng, chúng ta không thể sửa đổi thuộc tính x. x vẫn bằng 10{x: 10, y: 20} được log ra.

80. Tạo một biến là object và gán biến đó có giá trị là một object thì chuyện gì sẽ xảy ra?

const { name: myName } = { name: 'Lydia' };

console.log(name);

A: "Lydia"

B: "myName"

C: undefined

D: ReferenceError

Khi chúng ta giải nén thuộc tính name khỏi đối tượng ở phía bên phải, chúng tôi đã gán giá trị của nó "Lydia" cho một biến có tên myName.

Với {name : myName}, chúng ta đã nói với JS rằng chúng ta muốn tạo một biến mới có tên là myName với giá trị của thuộc tính name

Vì vậy biến name lúc này là biến undefined, do đó, ReferenceError sẽ được ném ra.

81. Pure function là gì?

Pure function là một hàm luôn trả về cùng một kết quả, nếu các có cùng tham số được truyền vào. Không bị ảnh hưởng từ các yếu tố, các tham số không tồn trong hàm

82. Chức năng của hàm ghi nhớ là gì ?


const add = () => {
  const cache = {};
  return num => {
    if (num in cache) {
      return `From cache! ${cache[num]}`;
    } else {
      const result = num + 10;
      cache[num] = result;
      return `Calculated! ${result}`;
    }
  };
};

const addFunction = add();
console.log(addFunction(10));
console.log(addFunction(10));
console.log(addFunction(5 * 2));

A: Calculated! 20 Calculated! 20 Calculated! 20

B: Calculated! 20 From cache! 20 Calculated! 20

C: Calculated! 20 From cache! 20 From cache! 20

D: Calculated! 20 From cache! 20 Error

Trong VD trên, hàm add được gọi là hàm ghi nhớ memoized function. Tân dụng việc ghi nhớ, chúng ta có thể lưu vào bộ nhớ cache các kết quả của một hàm để tăng tốc độ thực thi của nó. Trong trường hợp này, chúng ta tạo một object cho biến cache để lưu trữ các giá trị đã trả về trước đó

Nếu chúng ta gọi lại hàm addFunction với cùng một đối số, trước tiên nó sẽ kiểm tra xem nó đã nhận giá trị đó trong cache chưa. Nếu đúng như vậy, giá trị cache sẽ được trả về, giúp tiết kiệm thời gian thực thi. Ngược lại, nếu nó không được lưu trong cache, nó sẽ tính toán giá trị và lưu trữ sau đó.

Chúng ta gọi hàm addFunction ba lần với cùng một giá trị: trong lần gọi đầu tiên, giá trị của hàm khi num bằng 10 chưa được lưu vào cache. Điều kiện của câu lệnh if num in cache trả về false và khối else được thực thi: "Calculated! 20" được ghi lại và giá trị của kết quả được thêm vào cache. bộ nhớ cache bây giờ trông giống đang chứa như {10: 20}.

Lần thứ hai, cache chứa giá trị được trả về cho 10. Điều kiện của câu lệnh if num in cache trả về true'From cache! 20' được ghi lại. Lần thứ ba, chúng ta truyền 5 * 2 cho hàm được tính toán là 10. cache chứa giá trị được trả về là 10. Điều kiện của lệnh if num in cache trả về true và 'From cache! 20' được log ra.

83. for infor of có gì khác nhau?

const myLifeSummedUp = ['☕', '💻', '🍷', '🍫'];

for (let item in myLifeSummedUp) {
  console.log(item);
}

for (let item of myLifeSummedUp) {
  console.log(item);
}

A: 0 1 2 3 and "☕" "💻" "🍷" "🍫"

B: "☕" "💻" "🍷" "🍫" and "☕" "💻" "🍷" "🍫"

C: "☕" "💻" "🍷" "🍫" and 0 1 2 3

D: 0 1 2 3 and {0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}

Với vòng lặp for-in, chúng ta có thể lặp qua các thuộc tính của một thuộc tính. Trong một mảng, các thuộc tính liệt kê là khóa (key) của các phần tử mảng, chúng thực sự là index của mảng đó. Bạn có thể thấy một mảng như sau:

{0: "☕", 1: "💻", 2: "🍷", 3: "🍫"}

Trong đó các khóa(key) là các thuộc tính có thể liệt kê. 0 1 2 3 được log ra.

Với vòng lặp for-of, chúng ta có thể lặp qua các vòng lặp, một mảng là một vòng lặp. Khi chúng ta lặp qua mảng, biến "item" bằng với phần tử mà nó hiện đang lặp qua, do đó, "☕" "💻" "🍷" "🍫" được log ra.

84. Sử dụng this trong đối tượng lồng nhau

var status = '😎';

setTimeout(() => {
  const status = '😍';

  const data = {
    status: '🥑',
    getStatus() {
      return this.status;
    },
  };

  console.log(data.getStatus());
  console.log(data.getStatus.call(this));
}, 0);

A: "🥑" and "😍"

B: "🥑" and "😎"

C: "😍" and "😎"

D: "😎" and "😎"

Giá trị của this phụ thuộc vào nơi bạn sử dụng nó. Trong một phương thức, như là likeStatus, từ khóa this tham chiếu object mà phương thức đó thuộc về, phương thức getStatus thuộc về object data, vì vậy this ở đây đề cập đến object data. Khi chúng ta log this.status, thuộc tính status trong object data sẽ được log ra, đó là "🥑".

Với phương thức call, chúng ta có thể thay đổi đối tượng mà từ khóa this tham chiếu đến. Trong các hàm, từ khóa this tham chiếu đến object mà hàm đó thuộc về. Bởi vì chúng ta khai báo hàm setTimeout() là một global object (toàn cục), vì vậy bên trong hàm setTimeout(), từ khóa this sẽ tham chiếu đến global object. Trong global object, có biến được gọi là status với giá trị là "😎". Khi đó, this.status sẽ log ra "😎".

85. Gán một biến bằng với thuộc tính chưa được định nghĩa trong một object, chuyện gì sẽ xảy ra?

const person = {
  name: 'Lydia',
  age: 21,
};

let city = person.city;
city = 'Amsterdam';

console.log(person);

A: { name: "Lydia", age: 21 }

B: { name: "Lydia", age: 21, city: "Amsterdam" }

C: { name: "Lydia", age: 21, city: undefined }

D: "Amsterdam"

Chúng ta đặt biến city bằng giá trị của thuộc tính được gọi là city trong object person. Không có thuộc tính nào trong person có tên là city cả, do đó, biến city bây giờ có giá trị là undefined

Lưu ý rằng chúng ta không tham chiếu đến chính object person! Chúng ta chỉ cần đặt biến city bằng giá trị hiện tại của thuộc tính city trong object person.

Sau đó, chúng ta đặt city bằng chuỗi "Amsterdam". Điều này không thay đổi object person: vì không có tham chiếu đến object đó.

Khi log objectg person nó không có thay đổi gì nên trả về giá trị như ban đầu.

86. Sử dụng then nhiều lần sau khi fetch dữ liệu

fetch('https://www.website.com/api/user/1')
  .then(res => res.json())
  .then(res => console.log(res));

A: The result of the fetch method.

B: The result of the second invocation of the fetch method.

C: The result of the callback in the previous .then().

D: It would always be undefined.

Giá trị của red ở lần .then() thứ 2 sẽ trả về từ lần .then() trước đó. Bạn có thể sử dụng chuỗi .then() nhiều lần liên tiếp nhau với điều kiện giá trị được truyền vào ở lần trước để chờ lần xử lý tiếp theo.

87. Dấu * as khi import một module có ý nghĩa gì?

// module.js
export default () => 'Hello world';
export const name = 'Lydia';

// index.js
import * as data from './module';

console.log(data);

A: { default: function default(), name: "Lydia" }

B: { default: function default() }

C: { default: "Hello world", name: "Lydia" }

D: Global object of module.js

Với cú pháp import * as name, chúng ta sẽ import tất cả các export từ module.js thành một object mới có tên là data. Trong file module.js, có 2 kiểu export: export defaultnamed export. export default là một hàm trả về kiểu chuỗi "Hello World", còn named export là một biến có tên là name với giá trị Lydia.

object data có thuộc tính mặc định sẽ cho export default, các thuộc tính khác có tên named export sẽ được đặt tên và giá trị tương ứng của chúng.

88. console.log(array.push(item)) sẽ như thế nào?

let newList = [1, 2, 3].push(4);

console.log(newList.push(5));

A: [1, 2, 3, 4, 5]

B: [1, 2, 3, 5]

C: [1, 2, 3, 4]

D: Error

Phương thức .push() trả về độ dài mới của mảng, không phải của chính mảng! Bằng cách đặt newList bằng [1, 2, 3].push(4), chúng ta đã đặt newList có độ dài mới của mảng: 4

Sau đó, chúng ta cố gắng sử dụng phương thức .push() trên newList. Vì newList là giá trị số 4, chúng ta không thể sử dụng phương thức .push: một TypeError được ném ra.

89. prototype của regular function và arrow function có gì khác?

function giveLydiaPizza() {
  return 'Here is pizza!';
}

const giveLydiaChocolate = () =>
  "Here's chocolate... now go hit the gym already.";

console.log(giveLydiaPizza.prototype);
console.log(giveLydiaChocolate.prototype);

A: { constructor: ...} { constructor: ...}

B: {} { constructor: ...}

C: { constructor: ...} {}

D: { constructor: ...} undefined

Regular function như hàm giveLydiaPizza thì có thuộc tính prototype vì như đã biết function của một object (prototype object) nên có thuộc tính constructor. Tuy nhiên, arrow function như hàm giveLydiaChocolate lại không có thuộc tính prototype, do đó, undefined được trả về như một thuộc tính chưa được định nghĩa của giveLydiaChocolate.prototype.

90. lặp for-of với Object.entries(object)

const person = {
  name: 'Lydia',
  age: 21,
};

for (const [x, y] of Object.entries(person)) {
  console.log(x, y);
}

A: name Lydia and age 21

B: ["name", "Lydia"] and ["age", 21]

C: ["name", "age"] and undefined

D: Error

Object.entries(person) trả về một mảng các mảng lồng nhau, chứa các khóa và đối tượng [ [ 'name', 'Lydia' ], [ 'age', 21 ] ]

Sử dụng vòng lặp for-of, chúng ta có thể lặp qua từng phần tử trong mảng, các mảng con trong trường hợp này. Chúng ta có thể hủy cấu trúc các mảng con ngay lập tức trong vòng lặp for-of, sử dụng const [x, y]. x là phần tử đầu tiên trong mảng con, y là phần tử thứ hai trong mảng con.

Mảng con đầu tiên là ["name", "Lydia"], với x bằng "name"y bằng "Lydia", được log ra. Mảng con thứ hai là ["age", 21], với x bằng "age"y bằng 21, được log ra tiếp theo.

91. Sử dụng ...args trong function như thế nào ?

function getItems(fruitList, ...args, favoriteFruit) {
  return [...fruitList, ...args, favoriteFruit]
}

getItems(["banana", "apple"], "pear", "orange")

A: ["banana", "apple", "pear", "orange"]

B: [["banana", "apple"], "pear", "orange"]

C: ["banana", "apple", ["pear"], "orange"]

D: SyntaxError

...args là tham số còn lại nghĩa là sau khi hàm sử truyền vào các tham số trước đó, những tham số nào còn sót lại sẽ được đưa vào trong ...args nó phải được đặt ở vị trí cuối cùng trong danh sách tham số được truyền vào trong hàm. Trong ví dụ này, tham số ...args là tham số thứ hai. Điều này là không thể và sẽ gây ra lỗi cú pháp

92. Sử dụng Symbol là thuộc tính trong object

const info = {
  [Symbol('a')]: 'b',
};

console.log(info);
console.log(Object.keys(info));

A: {Symbol('a'): 'b'} and ["{Symbol('a')"]

B: {} and []

C: { a: "b" } and ["a"]

D: {Symbol('a'): 'b'} and []

Symbol không thể liệt kê được. Phương thức Object.keys trả về tất cả các thuộc tính khóa có thể liệt kê trên một đối tượng. Sylbol sẽ không hiển thị và một mảng trống được trả về. Khi logký toàn bộ đối tượng, tất cả các thuộc tính sẽ hiển thị, ngay cả những thuộc tính không thể liệt kê được.

Đây là một trong nhiều đặc tính của một biến Symbol: bên cạnh việc đại diện cho một giá trị hoàn toàn duy nhất (ngăn chặn sự trùng tên ngẫu nhiên trên các đối tượng, ví dụ: khi làm việc với 2 thư viện muốn thêm thuộc tính vào cùng một đối tượng), bạn cũng có thể "ẩn" thuộc tính trên các đối tượng theo cách này (mặc dù không hoàn toàn. Bạn vẫn có thể truy cập các biểu tượng bằng phương thức Object.getOwnPropertySymbols ()).

93. Kết quả dưới đây là gì?

const getList = ([x, ...y]) => [x, y]
const getUser = user => { name: user.name, age: user.age }

const list = [1, 2, 3, 4]
const user = { name: "Lydia", age: 21 }

console.log(getList(list))
console.log(getUser(user))

A: [1, [2, 3, 4]] and undefined

B: [1, [2, 3, 4]] and { name: "Lydia", age: 21 }

C: [1, 2, 3, 4] and { name: "Lydia", age: 21 }

D: Error and { name: "Lydia", age: 21 }

Hàm getList nhận một mảng làm đối số của nó. Giữa các dấu ngoặc đơn của hàm getList, chúng ta hủy cấu trúc mảng này ngay lập tức. Bạn có thể thấy điều này là:

[x, ...y] = [1, 2, 3, 4]

Với tham số còn lại ...y, chúng ta đặt tất cả các đối số "còn lại" trong một mảng. Các đối số còn lại là 2, 3 và 4 trong trường hợp này. Giá trị của y là một mảng, chứa tất cả các tham số còn lại. Giá trị của x bằng 1 trong trường hợp này, vì vậy khi chúng ta log [x, y], [1, [2, 3, 4]].

Hàm getUser nhận một đối tượng. Với các arrow function, chúng ta không phải viết dấu ngoặc nhọn nếu chúng ta chỉ trả về một giá trị. Tuy nhiên, nếu bạn muốn trả về một đối tượng từ một arrow function, bạn phải viết nó giữa các dấu ngoặc đơn, nếu không sẽ không có giá trị nào được trả về! Hàm sau sẽ trả về một đối tượng:

const getUser = user => ({ name: user.name, age: user.age })

Vì không có giá trị nào được trả về trong trường hợp này, nên hàm trả về không xác định.

94. Khai báo và thực hiện sai kiểu sẽ như thế nào?

const name = 'Lydia';

console.log(name());

A: SyntaxError

B: ReferenceError

C: TypeError

D: undefined

Biến name giữ giá trị của một chuỗi, không phải là một hàm, do đó không thể gọi hàm.

Lỗi Kiểu TypeErrors được ném ra khi một giá trị không thuộc loại mong đợi. Tên dự kiến của JavaScript sẽ là một hàm vì chúng ta đang cố gọi nó. Tuy nhiên, đó là một chuỗi, do đó nó sẽ ném lỗi TypeError gets thrown: name is not a function!

Lỗi Cú pháp SyntaxErrors được ném khi bạn viết một cú pháp nào đó không hợp lệ trong JS. VD khi bãn viết từ return dưới dạng retrun.

Lỗi tham chiếu ReferrenceErrors được ném ra khi JavaScript không thể tìm thấy tham chiếu đến giá trị mà bạn đang cố truy cập.

95. Sự kết hợp các kiểu dữ liệu thông qua toán tự ||

const one = false || {} || null;
const two = null || false || '';
const three = [] || 0 || true;

console.log(one, two, three);

A: false null []

B: null "" true

C: {} "" []

D: null null true

Với toán tử ||, chúng ta có thể trả về toán hạng chân trị đầu tiên. Nếu tất cả các giá trị là false, toán hạng cuối cùng sẽ được trả về. (false || {} || null): đối tượng rỗng {} là một giá trị truthy. Đây là giá trị truthy đầu tiên (và duy nhất), được trả về. Vậy one bằng {}.

(null || false || ""): tất cả các toán hạng đều là giá trị sai. Điều này có nghĩa là toán hạng cuối cùng, "" được trả về. Vậy two bằng "".

([] || 0 || ""): mảng rỗng [] là một giá trị truthy. Đây là giá trị truthy đầu tiên được trả về. Vậy three bằng [].

96. Sử dụng Async/awaitPromise

const myPromise = () => Promise.resolve('I have resolved!');

function firstFunction() {
  myPromise().then(res => console.log(res));
  console.log('second');
}

async function secondFunction() {
  console.log(await myPromise());
  console.log('second');
}

firstFunction();
secondFunction();

A: I have resolved!, second and I have resolved!, second

B: second, I have resolved! and second, I have resolved!

C: I have resolved!, second and second, I have resolved!

D: second, I have resolved! and I have resolved!, second

Với một Promise, về cơ bản chúng ta nói rằng chúng ta muốn thực thi chức năng này, nhưng chúng ta sẽ tạm gác nó sang một bên khi nó đang chạy vì điều này có thể mất một lúc. Chỉ khi một giá trị nhất định được giải quyết (hoặc bị từ chối) và khi ngăn xếp cuộc gọi trống, chúng ta mới muốn sử dụng giá trị này.

Chúng ta có thể lấy giá trị này bằng cả .then và từ khóa await trong một hàm async. Mặc dù chúng ta có thể nhận được giá trị của promise với cả .thenawait, nhưng chúng hoạt động hơi khác một chút.

Trong FirstFunction, chúng ta đặt hàm myPromise sang một bên khi nó đang chạy, nhưng tiếp tục chạy code khác, đó là console.log('second') trong trường hợp này. Sau đó, hàm được giải quyết với chuỗi mà "I have resolved", sau đó được ghi lại sau khi thấy rằng callstack trống.

Với từ khóa await trong secondFunction, chúng ta thực sự tạm dừng việc thực thi một hàm không đồng bộ cho đến khi giá trị đã được giải quyết trước khi chuyển sang dòng tiếp theo.

Điều này có nghĩa là nó đã đợimyPromise giải quyết với giá trụ "I have resolved" đã giải quyết và chỉ khi điều đó xảy ra, chúng ta đã chuyển sang dòng tiếp theo: second được log ra.

97. Lặp với Set

const set = new Set();

set.add(1);
set.add('Lydia');
set.add({ name: 'Lydia' });

for (let item of set) {
  console.log(item + 2);
}

A: 3, NaN, NaN

B: 3, 7, NaN

C: 3, Lydia2, [object Object]2

D: "12", Lydia2, [object Object]2

Toán tử + không chỉ được sử dụng để thêm các giá trị số mà chúng ta cũng có thể sử dụng nó để nối các chuỗi. Bất cứ khi nào JavaScript Engine thấy rằng một hoặc nhiều giá trị không phải là số, nó sẽ ép buộc số đó thành một chuỗi.

Giá trị đầu tiên là 1, là một giá trị số. 1 + 2 trả về số 3.

Tuy nhiên, cái thứ hai là một chuỗi "Lydia". "Lydia" là một chuỗi và 2 là một số: 2 được ép buộc thành một chuỗi. "Lydia""2" được nối với nhau, dẫn đến chuỗi "Lydia2".

{name: "Lydia"} là một object. Cả một số hay một đối tượng đều không phải là một chuỗi, vì vậy nó chỉ định cả hai. Bất cứ khi nào chúng ta xâu chuỗi một đối tượng thông thường, nó sẽ trở thành "[object Object]". "[object Object]" được nối với "2" trở thành "[object Object] 2".

98. Promise.resolve()

Promise.resolve(5);

A: 5

B: Promise {<pending>: 5}

C: Promise {<fulfilled>: 5}

D: Error

Chúng ta có thể chuyển bất kỳ loại giá trị nào mà chúng ta muốn Promise.resolve, có thể là lời hứa hoặc không lời hứa. Phương thức tự trả về một lời hứa với giá trị được giải quyết (<fulfilled>). Nếu bạn truyền vào một regular function, nó sẽ là một lời hứa được giải quyết với một giá trị thông thường. Nếu bạn truyền vào một lời hứa, đó sẽ là một lời hứa được giải quyết với giá trị được giải quyết của lời hứa đó đã được thông qua đó.

rong trường hợp này, chúng ta chỉ chuyển giá trị số 5. Nó trả về một lời hứa đã giải quyết với giá trị 5.

99. Kết quả dưới đây là gì?

function compareMembers(person1, person2 = person) {
  if (person1 !== person2) {
    console.log('Not the same!');
  } else {
    console.log('They are the same!');
  }
}

const person = { name: 'Lydia' };

compareMembers(person);

A: Not the same!

B: They are the same!

C: ReferenceError

D: SyntaxError

Các Object được truyền bằng tham chiếu. Khi chúng ta kiểm tra các object bằng nhau một cách nghiêm ngặt (===), chúng sẽ so sánh tham chiếu của chúng. Vì chúng ta đặt giá trị mặc định cho person2 bằng đối tượng person và chuyển đối tượng person làm giá trị cho person1.

Điều này có nghĩa là cả hai giá trị đều có tham chiếu đến cùng một vị trí trong bộ nhớ, do đó chúng bằng nhau.

100. Tìm thuộc tính trong object thông qua một phần tử của mảng có sẵn

const colorConfig = {
  red: true,
  blue: false,
  green: true,
  black: true,
  yellow: false,
};

const colors = ['pink', 'red', 'blue'];

console.log(colorConfig.colors[1]);

A: true

B: false

C: undefined

D: TypeError

Trong JavaScript, chúng ta có hai cách để truy cập các thuộc tính trên một đối tượng: ký hiệu dấu ngoặc vuông [] hoặc ký hiệu dấu chấm .. Trong ví dụ này, chúng ta sử dụng ký hiệu dấu chấm (colorConfig.colors) thay vì ký hiệu dấu ngoặc (colorConfig ["Colors"]).

Với ký hiệu dấu chấm, JavaScript cố gắng tìm thuộc tính trên đối tượng có tên chính xác đó. Trong ví dụ này, JavaScript cố gắng tìm một thuộc tính được gọi là colors trên đối tượng colorConfig. Không có thuộc tính nào được gọi là colors, vì vậy giá trị này trả về không xác định. Sau đó, chúng ta cố gắng truy cập giá trị của phần tử đầu tiên bằng cách sử dụng [1]. Chúng ta không thể thực hiện việc này trên một giá trị undefined, vì vậy nó sẽ ném ra Lỗi TypeError: Cannot read property '1' of undefined.

JavaScript thông dịch (hoặc unboxes) các câu lệnh. Khi chúng ta sử dụng ký hiệu ngoặc, nó sẽ thấy dấu ngoặc mở đầu tiên [ và tiếp tục cho đến khi tìm thấy dấu ngoặc đóng ]. Sau đó, nó tiến hành đánh giá các câu lệnh. Nếu chúng ta sử dụng colorConfig[Colors[1]], thì nó sẽ trả về giá trị của thuộc tính red trên đối tượng colorConfig

Phần 4 đến đây là hết, cám ơn các bạn đã đón đọc. Hẹn gặp lại các bạn ở phần 5.


Bài viết có liên quan