Почему в свойстве document.location.host нет «доступных для записи» и «значений» - PullRequest
0 голосов
/ 24 мая 2019

Я использую Object.freeze(document.location), чтобы заморозить document.location, но обнаружил, что все еще могу изменить document.location.host. И я обнаружил, что в свойстве document.location.host нет writable, поэтому я могу это сделать?

Object.getOwnPropertyDescriptors(document.location)
// result
{replace: {…}, href: {…}, ancestorOrigins: {…}, origin: {…}, protocol: {…}, …}
ancestorOrigins: {get: ƒ, set: undefined, enumerable: true, configurable: false}
assign: {value: ƒ, writable: false, enumerable: true, configurable: false}
hash: {get: ƒ, set: ƒ, enumerable: true, configurable: false}
host:
configurable: false
enumerable: true
get: ƒ host()
set: ƒ host()
__proto__: Object
hostname: {get: ƒ, set: ƒ, enumerable: true, configurable: false}
href:
configurable: false
enumerable: true
value: "https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"
writable: false
__proto__: Object
origin: {get: ƒ, set: undefined, enumerable: true, configurable: false}
pathname: {get: ƒ, set: ƒ, enumerable: true, configurable: false}
port: {get: ƒ, set: ƒ, enumerable: true, configurable: false}
protocol: {get: ƒ, set: ƒ, enumerable: true, configurable: false}
reload: {value: ƒ, writable: false, enumerable: true, configurable: false}
replace: {value: ƒ, writable: false, enumerable: true, configurable: false}
search: {get: ƒ, set: ƒ, enumerable: true, configurable: false}
toString: {value: ƒ, writable: false, enumerable: true, configurable: false}
valueOf: {value: ƒ, writable: false, enumerable: false, configurable: false}
Symbol(Symbol.toPrimitive): {value: undefined, writable: false, enumerable: false, configurable: false}
__proto__: Object

1 Ответ

0 голосов
/ 24 мая 2019

Это потому, что host является установщиком / получателем, а не простым свойством.Если бы это было обычное свойство, и вы использовали Object.freeze, оно не могло быть изменено:

const obj = { foo: 'foo' };
Object.freeze(obj);
obj.foo = 'newval';
console.log(obj.foo);

Но когда вы присваиваете сеттеру, вы фактически не меняете там свойства , поэтому Object.freeze не мешает вам вызывать сеттер:

const obj = {
  set foo(newVal) {
    console.log('set foo called');
  },
  get foo() {
    console.log('get foo called');
    return 'getVal';
  }
};
Object.freeze(obj);
obj.foo = 'newval';
console.log(obj.foo);

Атрибуты writable и value существуют только для дескрипторов данных , которые исключают сеттеры / геттеры.См. MDN :

значение

Значение, связанное со свойством (только дескрипторы данных) .

доступный для записи

true тогда и только тогда, когда значение, связанное со свойством, может быть изменено (только дескрипторы данных).

...