iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0

物件啊物件

昨天了解了物件的基本概念,
今天來看一下物件常用的方法!



環遊非洲第14天-非洲101-Q

猜猜全世界說法語人口最多的國家是哪一個?

  1. 當然是法國啦
  2. 我知道!加拿大部分地區也說法語
  3. 不會是...剛果吧
  4. 瑞士或是比利時...嗎?


創造物件

Object.create

建造一個物件
Object.create(proto 作為原型的目標物件, propertiesObject 非必要參數)

案例:

const AfricaCountry = {
  isAfricaCountry: false,
  printIntroduction: function() {
    console.log(`This is ${this.name}. The country is in Africa? ${this.isAfricaCountry}`);
  }
};

const Congo = Object.create(AfricaCountry);

Congo.name = 'Congo'; // "name" 屬性綁在Congo上,而不是AfricaCountry
Congo.isAfricaCountry = true; // 繼承來的屬性可被覆寫

Congo.printIntroduction();
// expected output: This is Congo. The country is in Africa? true

注意,如果使用null生成一個物件,無法繼承所有Object的函式。

const a = Object.create(null);
const b = {};

console.log(`hello ${a}`) //VM173:1 Uncaught TypeError: Cannot convert object to primitive value
console.log(`hello ${b}`) //hello [object Object]
a.valueOf(); //VM203:1 Uncaught TypeError: a.valueOf is not a function
b.valueOf(); //{} =>可使用原型繼承來的的涵式

新增與修改物件屬性

Object.defineProperty & Object.defineProperties

可以新增或修改一個物件的屬性。
Object.defineProperties(targetObject, prop, descriptor)

const africaCountry = {};

Object.defineProperty(africaCountry, 'info',  {
    value: "Congo",
    writable: true,//可否覆寫
    enumerable: false, 
    configurable: false,
  });

console.log(africaCountry.info); //Congo

descriptor屬性描述器主要有兩種:

  1. 資料描述器(data descriptor)-能否覆寫的屬性,上面例子有帶到value & writable的就是資料描述,他們就沒有訪問描述器的getter & setter

  2. 訪問描述器(accessor descriptor)- 由getter & setter 定義的

兩者共享的key:

  • enumerable (可否被列舉)

  • configurable(default: false, 屬性不能被刪除,不能在資料或訪問描述器兩者之間切換)

defineProperties則可以一次新增多個屬性:
Object.defineProperties(targetObject, props);

用法:

const africaCountry = {};

Object.defineProperties(africaCountry, {
  info: {
    value: "Congo",
    writable: true
  },
  property2: {}
});

console.log(africaCountry.info); //Congo

物件拷貝

Object.assign

  • 靜態方法,不會被繼承
  • 注意這只是淺拷貝
const Congo = { region: "central", population: " 5,820,080 " };
const Ethiopia = { region: "east", population: "121,295,237" };

const returnedCountries = Object.assign(Congo, Ethiopia);

console.log(target);
// { a: 1, b: 4, c: 5 }

console.log(returnedTarget);
// { a: 1, b: 4, c: 5 }

刪除物件屬性

Delete Property

const Ghana = {
    name: "Ghana",
    population: "31,000,000",
    features: "Top cocoa export country"
}

delete Ghana.feature
console.log(Ghana) //{name: 'Ghana', population: '31,000,000'}


檢查物件屬性:

in & Object.hasOwn & Object.hasOwnProperty

我們可以用以下方法來檢查物件是否擁有某個屬性:

const Ghana = {
    name: "Ghana",
    population: "31,000,000",
    features: "Top cocoa export country"
}

"name" in Ghana //ture
Ghana.hasOwnProperty("name") //true
Object.hasOwn(Ghana, "name") //true

那究竟Object.hasOwn & Object.hasOwnProperty到底哪一個好?

官方推薦hasOwn 方法,他也是近幾年才出現的,為了解決hasOwnProperty的問題:

問題1.可以被覆寫

let object = {
  hasOwnProperty() {
    throw new Error("Hahaha!")
  }
}

object.hasOwnProperty("randomKey")
// Uncaught Error: Hahaha!

問題2. 不能解決Object.create(null)的error

Object.create(null).hasOwnProperty("foo")

// Uncaught TypeError: Object.create(...).hasOwnProperty is not a function

Object.create(null)
const a = Object.create(null)
Object.hasOwn(a, "foo")
//會回傳給我們false,告訴我們沒有這個屬性

引用改編自:Object.hasOwn 替换掉 Object.prototype.hasOwnProperty

回溯物件原型

getPrototypeOf

const my_proto = {};
const my_obj = Object.create(my_proto);

console.log(Object.getPrototypeOf(my_obj) === my_proto);
// true

以上!

話說JS內建的物件還有好多沒看過沒用過
MDN的文件也太棒了吧,
希望未來有機會回來看看
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects



環遊非洲第14天-非洲101-A

就是!3.不會是...剛果吧

剛果人口9000多萬,法國人口6000多萬,剛果毫無懸念站上第一名!
過去曾經被法國殖民的剛果,獨立之後還是選擇法語當作官方語言。
很多法國殖民地聚集在中西非的國家,至今也都還說法語,還和法國維持友好關係。
甚至還使用非洲法郎當作流通貨幣。
非洲法郎與歐元掛勾,貨幣穩定。
但是50%的儲備金要上繳法國國庫,非洲國家也無權制定法郎的貨幣政策。
(我個人覺得很荒謬。)

這些非洲國家就算已經脫離了殖民了,流通的貨幣還是沒有掌控權。



參考資料

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object


上一篇
JS的物件導向與Object-D13
下一篇
可以不要安裝一些有的沒的嗎?懶人救星:Docker -D15
系列文
分手前端菜雞之旅@非洲30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言