Những câu hỏi hay trong Javascript Phần 4
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
và {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
và '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 in
và for 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 default
và named 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"
và y
bằng "Lydia"
, được log ra. Mảng con thứ hai là ["age", 21]
, với x
bằng "age"
và 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/await
và Promise
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ả .then
và await
, 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"
và "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.