【JavaScript】甚麼時候該用for…in,甚麼時候該用for…of

for…in是個常在Object中使用的方法,但前一陣子發現原來還有for…of,怕搞混這兩個所以來整理一下差別。

1. for…in

根據MDN的解釋,for…in用來跌代Object中enumerable的屬性,然而不只會跌代所宣告Object中enumerable的屬性,還會遞迴該Object的prototype中enumerable的屬性。

Object.prototype.objCustom = function() {}
Array.prototype.arrCustom = function() {}

const iterable = [3, 5, 7]
iterable.foo = 'hello'

for (const i in iterable) {
  console.log(i)
}
// 0, 1, 2, "foo", "arrCustom", "objCustom"

那麼甚麼是enumerable呢?enumerable屬於6個Property Descriptor其中一個,用來定義是否將該屬性被for…in跌代。如果一個屬性的enumerable為false,下面三個操作不會取到該屬性:for…in、Object.keys、JSON.stringify。

在Object中,property的enumerable預設為true,可以透過defineProperty方法將其改為false。

const obj = {
    name: "Jimmy"
}
Object.defineProperty(obj, 'name', { enumerable: false })
const descriptor = Object.getOwnPropertyDescriptor(obj, 'name');
console.log(descriptor)
/* {
    value: 'Jimmy',
    writable: true,
    enumerable: false,
    configurable: true
  } */

2. for…of

根據MDN的解釋,for…of用來跌代iterable object中的value。

const iterable = [3, 5, 7]
for (const i of iterable) {
  console.log(i) 
}
// 3, 5, 7

3. 使用時機

3.1 for…in 用在Object中

for…in用在Object中可以同時取出Object中的key和value。

const obj = {
    name: "Jimmy",
    age: 25,
    weight: "75 kg"
}
for (const key in obj ) {
    console.log(key)
    console.log(obj[key])
}
// name, Jimmy, age, 25, weight, 75 kg

3.2 for…of 用在Object中

for…of用在Object中也可以同時取出key和value,和for…in不一樣的地方是,必須搭配Object.keys方法使用,否則會出錯。

const obj = {
    name: "Jimmy",
    age: 25,
    weight: "75 kg"
}
for (const key of Object.keys(obj)) {
    console.log(key)
    console.log(obj[key])
}
// name, Jimmy, age, 25, weight, 75 kg
for (const key of obj) {
    console.log(key)
}
// error!

3.3 for…in 用在Array中

for…in用在Array中可以同時取出Array中的key和value。(Array的key是index。)

const arr = ["Jimmy", 25, "75 kg"]
for (const key in arr ) {
    console.log(key)
    console.log(arr[key])
}
// 0, Jimmy, 1, 25, 2, 75 kg

3.4 for…of 用在Array中

for…of用在Array中只能取出Array的value。

const arr = ["Jimmy", 25, "75 kg"]
for (const key of arr) {
    console.log(key)
}
// Jimmy, 25, 75 kg

Leave a Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Scroll to Top