從 Compat 2021 到 Interop 2022
Compat 2021 致力於消除瀏覽器相容性問題的五個主要焦點領域,使開發者可以在這些領域上自信地建立可靠的基礎。而 Interop 2022 的重點是在15個開發者認為在不同瀏覽器之間缺失或存在相容性問題時尤其困擾的領域上制定基準。約 2216 字 (12分鐘閱讀)

上一篇文章有說到 JavaScript 要如何檢驗物件是否包含屬性的方法,介紹到了 in
運算符 (in operator)、hasOwn()
與 hasOwnProperty()
。
在比對三者的差異性為何前,先來複習一下大略介紹的官方資訊:
hasOwn()
是 ECMAScript 2022(ES13)的新靜態方法,若指定的對象自身有指定的屬性,則 Object.hasOwn()
返回 true
;若屬性是繼承的或者不存在,該方法返回 false
。
而 in
運算符、hasOwnProperty()
是在 ECMAScript 2022 (ES13) 以前出來的,較多人使用用來檢查 JS 對象是否具有任何自定義屬性的傳統方法。
in
運算符檢查屬性是否存在於物件及其原型鏈上。hasOwnProperty()
檢查屬性是否存在於物件自身,不考慮原型鏈。in
運算符甚至對於繼承的屬性也會返回 true
,例如: toString
、constructor
和 hasOwnProperty
是所有 JavaScript 對象的繼承方法。
以下示例區分直接屬性(Direct properties)和通過原型鏈繼承的屬性(Inherited properties):
let examples = {
name: "Kama",
website: "reikama414.github.io",
}
// `hasOwn` will only return true for direct properties:
Object.hasOwn(examples, 'name'); // true
Object.hasOwn(examples, 'toString'); // false
Object.hasOwn(examples, 'constructor'); // false
Object.hasOwn(examples, 'hasOwnProperty'); // false
// `in` operator will return true for direct or inherited properties:
'name' in examples; // true
'toString' in examples; // true
'constructor' in examples; // true
'hasOwnProperty' in examples; // true
// `hasOwnProperty` will only return true for direct properties:
examples.hasOwnProperty('name'); // true
examples.hasOwnProperty('toString'); // false
examples.hasOwnProperty('constructor'); // false
examples.hasOwnProperty('hasOwnProperty'); // false
主要原因大致可分為兩種:
hasOwnProperty
可能會被覆蓋,但 hasOwn()
避免了這個問題,可以返回正確結果。hasOwnProperty()
方法不適用於 null 對象,但 hasOwn()
方法適用。JavaScript 不保護屬性名 hasOwnProperty
,具有此名稱屬性的對象可能會返回不正確的結果:
const person = {
hasOwnProperty() {
return false;
},
name: 'Kama',
};
// Use Object.hasOwn() method - recommended
Object.hasOwn(person, 'name'); // true
// Use the hasOwnProperty property from the Object prototype
Object.prototype.hasOwnProperty.call(person, 'name'); // true
// Use another Object's hasOwnProperty and call it with 'this' set to person
({}).hasOwnProperty.call(person, 'name'); // true
// re-implementation always returns false
person.hasOwnProperty('name'); // false
當還在使用 hasOwnProperty()
時,為了避免這種錯誤,最好始終從 Object.prototype
調用這些方法(e.g. 使用 Object.prototype.hasOwnProperty.call()
)。
不過有了 ES13 出來的 hasOwn()
以後,即便 hasOwnProperty()
被覆蓋,我們仍然可以確定屬性檢查將返回正確的結果。
It also may cause security issues. A specific example of this is when a web server reads in JSON data from a client and uses the hasOwnProperty property on that object. A problem could happen if client sends malicious JSON value like {"hasOwnProperty": 1} that would cause the server to fail.
一一 This excerpt is taken from "Reference" [5], written by Igor Gonchar.
(指 hasOwnProperty
可能會被覆蓋這件事) 這也可能導致安全問題。
一個具體示例是當 Web 服務器從客戶端讀取 JSON 資料並使用在該對象上使用 hasOwnProperty
屬性時。
如果客戶端發送諸如 {"hasOwnProperty": 1}
之類的惡意 JSON 值,則可能會出現問題,從而導致服務器失敗。
使用 Object.create(null)
創建的對象不會繼承自 Object.prototype
,從而導致 hasOwnProperty()
無法訪問。
hasOwnProperty()
方法不適用於 null 對象,但 hasOwn()
方法適用。
const example = Object.create(null);
example.type = "WEB";
Object.hasOwn(example, "type"); // true
// Uncaught TypeError: example.hasOwnProperty is not a function
example.hasOwnProperty("type");
簡單來講,in
運算符 (in operator)、hasOwn()
與 hasOwnProperty()
可以分為:
in
運算符*(in operator)*hasOwn()
與 hasOwnProperty()
而 hasOwn()
與 hasOwnProperty()
,之所以建議使用 Object.hasOwn()
而不是 Object.hasOwnProperty()
的原因是:
因為 Object.hasOwn()
也適用於使用 Object.create(null)
創建的對象,以及覆蓋了繼承的 hasOwnProperty()
方法的對象。
儘管可以通過在外部對象上調用 Object.prototype.hasOwnProperty.call(<object reference>, <property name>)
解決這些問題,但 Object.hasOwn()
可以直接克服這些問題,因此更受推薦。
[1] JavaScript Object hasOwn() Method - GeeksforGeeks
https://www.geeksforgeeks.org/javascript-object-hasown-method/
[2] in operator - JavaScript | MDN
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in
[3] Object.hasOwn() - JavaScript | MDN
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn
[4] Object.prototype.hasOwnProperty() - JavaScript | MDN
[5] JavaScript: hasOwn() — new way to check if Object has property | by Igor Gonchar | Medium
[6] javascript - Object.hasOwn() vs Object.prototype.hasOwnProperty() - Stack Overflow
https://stackoverflow.com/questions/69561596/object-hasown-vs-object-prototype-hasownproperty
JavaScript: in vs. hasOwn vs. hasOwnProperty
作者
約 2216 字 (12分鐘閱讀)
約 2161 字 (11分鐘閱讀)
約 1851 字 (10分鐘閱讀)