簡體   English   中英

為什么使用 `console.log` 調用 object 會記錄 `[object Object]`?

[英]Why does an object log `[object Object]` when called with `console.log`?

老實說,我不太確定如何格式化,因為我在這里放了一段很長的代碼,所以我會經常檢查這個以消除任何混淆。

有問題的代碼如下:

 const menu = { _courses: { appetizers: [], mains: [], desserts: [] }, get appetizers() { this._courses.appetizers; }, set appetizers(appetizerIn) { this._courses.appetizers = appetizerIn; }, get mains() { this._courses.mains; }, set mains(mainIn) { this._courses.mains = mainIn; }, get desserts() { this._courses.desserts; }, set desserts(dessertIn) { this._courses.desserts = dessertIn; }, get courses() { return { appetizers: this.appetizers, mains: this.mains, desserts: this.desserts } }, addDishToCourse(courseName, dishName, dishPrice) { const dish = { name: dishName, price: dishPrice } this._courses[courseName].push(dish); }, getRandomDishFromCourse(courseName) { const dishes = this._courses[courseName]; const dishNum = Math.floor(Math.random() * dishes.length); return dishes[dishNum]; }, generateRandomMeal() { const appetizer = this.getRandomDishFromCourse('appetizers'); const main = this.getRandomDishFromCourse('mains'); const dessert = this.getRandomDishFromCourse('desserts'); const totalPrice = appetizer.price + main.price + dessert.price; console.log(appetizer) return `Appetizer: ${appetizer} Main: ${main} Dessert: ${dessert} Total Price: ${totalPrice}`; }, } menu.addDishToCourse('appetizers', 1, 1) menu.addDishToCourse('appetizers', 2, 2) menu.addDishToCourse('appetizers', 3, 3) menu.addDishToCourse('mains', 1, 1) menu.addDishToCourse('mains', 2, 2) menu.addDishToCourse('mains', 3, 3) menu.addDishToCourse('desserts', 1, 1) menu.addDishToCourse('desserts', 2, 2) menu.addDishToCourse('desserts', 3, 3) const meal = menu.generateRandomMeal(); console.log(meal);

我返回要記錄到控制台的字符串的代碼的特定部分是

generateRandomMeal() {
    const appetizer = this.getRandomDishFromCourse('appetizers');
    const main = this.getRandomDishFromCourse('mains');
    const dessert = this.getRandomDishFromCourse('desserts');
    const totalPrice = appetizer.price + main.price + dessert.price;
    console.log(appetizer)
    return Appetizer: ${appetizer}
Main: ${main}
Dessert: ${dessert}
Total Price: ${totalPrice}`;
  },

我希望它打印到控制台的是[ *key*: *value*, *key2*: *value2* ]但它打印的是[ object Object ] 我知道定義 object 的原因是,當我用console.log(appetizer) appetizer.name) 替換 console.log(appetizer console.log(appetizer.name)時,它會打印正確的名稱。

好吧,如果開胃菜是 JSON object,您可以簡單地使用 JSON.stringify(object)。

console.log(JSON.stringify(appetizer))

雖然console.log()將適用於對象,但有一種方法專門用於將對象顯示到控制台,稱為console.dir()

console.dir(appetizer)

您需要使用JSON.stringify() ,它將 object 轉換為console.log將打印出來的字符串。

當遇到 object 時, console.log不會深入到 object 並為您打印所有內容。

它只是將其識別為 object 並記錄[Object object]

因此,對於您的示例,您需要執行以下操作:

return `Appetizer: ${JSON.stringify(appetizer)};
        Main: ${JSON.stringify(main)}
        Dessert: ${JSON.stringify(dessert)}
        Total Price: ${JSON.stringify(totalPrice)}`;

在瀏覽器和 nodejs 環境中,運行console.log(appetizer)會產生:

{
  "name": 3,
  "price": 3
}

[object Object]僅通過運行console.log(meal)產生

Appetizer: [object Object]
Main: [object Object]
Dessert: [object Object]
Total Price: 6

這很正常,因為對象被隱式轉換為字符串。 這些是等價的:

 const obj = { a: 1 } console.log('Hello: ' + obj) console.log('Hello: ' + obj.toString()) console.log(`Hello: ${obj}`)

如果您希望您的字符串包含對象的 JSON 代表,請使用JSON.stringify

 const obj = { a: 1 } const s = 'Hello: ' + JSON.stringify(obj); /// or JSON.stringify(obj, null, 2); with 2 spacing console.log(s)

TLDR

[object Object]是自定義對象的默認字符串表示。 您可以通過實現自己的toString方法或通過添加帶有眾所周知的符號@@toStringTag的 getter 屬性來覆蓋此行為。 console.log不是 ECMAScript 規范的一部分,並且在大多數情況下會嘗試打印比[object Object]更有意義的內容。

細節

JavaScript 提供[object <Tag>]形式的對象的默認字符串表示。

一些內置對象,例如FunctionDate會覆蓋Object#toString方法,但我們仍然可以通過在這些對象上調用Object#toString來獲得默認的字符串表示。 如果我們查看 output,就會出現一個模式!

 const toString = Function.prototype.call.bind({}.toString) // Instances console.log(toString({})) // [object Object] console.log(toString(undefined)) // [object Undefined] ¹ console.log(toString(null)) // [object Null] ¹ console.log(toString(/foo/)) // [object RegExp] console.log(toString(true)) // [object Boolean] console.log(toString('')) // [object String] console.log(toString(new ArrayBuffer)) // [object ArrayBuffer] console.log(toString(1)) // [object Number] console.log(toString(Symbol())) // [object Symbol] // Constructor functions console.log(toString(Number)) // [object Function] console.log(toString(Date)) // [object Function] console.log(toString(RegExp)) // [object Function] // Namespace objects: console.log(toString(Math)) // [object Math] console.log(toString(JSON)) // [object JSON] console.log(toString(Atomics)) // [object Atomics] console.log(toString(Intl)) // [object Object] ² console.log(toString(Reflect)) // [object Object] ²

自定義對象繼承了Object.prototypetoString方法,但是你可以重寫它:

 const o = { dish: 'Fish & Chips', toString() { return JSON.stringify(this) } } console.log('' + o) // { "dish": "Fish & Chips" }

...但是如果您直接針對您的自定義 object 調用Object#toString ,您仍然會得到[object Object] 您可以通過使用眾所周知的符號 @@toStringTag 的鍵定義屬性來更改此設置:

 const o = { get [Symbol.toStringTag]() { return 'Bubblegum.' } } console.log(Object.prototype.toString.call(o)) // '[object Bubblegum!]'

¹這些值可能看起來很奇怪,但我認為它們來自規范,即Object#toString的 output 應該只是[object <string tag>] 對於nullundefined ,字符串標簽分別是NullUndefined ,給出值[object Null][object Undefined]

² 請注意,對IntlReflect內置對象的toString操作發出的值的不一致是我上次查看時(2020 年初)在 TC-39 中的一個開放討論點,並且可能來自不同團隊實現這些 API。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM