Object.defineProperty — реквизит, невидимый в chrome devtool

Что ж, я столкнулся с вопросом, когда пытаюсь использовать полифилл Object.watch в Chrome. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch https://gist.github.com/eligrey/384583

Полифил довольно короткий, и вы можете прочитать, как он удаляет исходное свойство и сразу же определяет новое свойство с тем же значением, но с переопределением геттера и сеттера.

Проблема в том, что если вы используете этот полифилл и смотрите на o.p:

var o = { p: 1 };
o.watch("p", function (id, oldval, newval) {
  console.log( "o." + id + " changed from " + oldval + " to " + newval );
  return newval;
});

После этого вы проверяете объект o в chrome devtool. Хлопнуть! Объект o сейчас пуст! На самом деле у него все еще есть свойство p, введите o.p, вы найдете o.p = 1.

Мой вопрос: почему это свойство невидимо в списке свойств объектов инструментов разработчика Chrome?

Примечание: если вы не знаете/не интересуетесь Object.watch, вы все равно можете помочь мне в этом вопросе, если хорошо понимаете Object.defineProperty.


Изменить: оказывается, это совсем не то, что я думал, что оно создает новое свойство, только переопределяя его геттер и сеттер. Цитата из https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty «Дескрипторы свойств, присутствующие в объектах, бывают двух основных разновидностей: дескрипторы данных и дескрипторы доступа. Дескриптор данных — это свойство, которое имеет значение , который может быть доступен или не доступен для записи. Дескриптор доступа — это свойство, описываемое парой функций получения-установки».

Таким образом, похоже, что полифил изменяет целевое свойство со «свойства данных» на «свойство доступа». Я предполагаю, что единственный способ полифилла это?


person kakacii    schedule 18.07.2013    source источник
comment
Он не невидим, он изменяется на getter и setter полифиллом watch. Вот как watch узнает, когда он изменен.   -  person Xotic750    schedule 18.07.2013
comment
Хорошо, если вы прочитаете код, вы увидите, что он делает копию, удаляет старое свойство и повторно добавляет это свойство в качестве геттера и сеттера со старым значением. -> измененный   -  person Xotic750    schedule 18.07.2013
comment
Я вижу это. jsfiddle   -  person Xotic750    schedule 18.07.2013
comment
@ Xotic750 Хм .. Я думал, что он создает новое свойство, переопределяя только его геттер и сеттер. Но нет, все не так, как я думал..   -  person kakacii    schedule 18.07.2013
comment
как разработчик библиотеки, мне интересно, есть ли способ заставить мои объекты выглядеть нормально в веб-инспекторе Chrome   -  person J Chris A    schedule 17.01.2014


Ответы (1)


My question is, why the property is invisible under Chrome developer tools object property list?

Ответ: он виден, но теперь это геттер и сеттер.

Object {}
get p: function () {
set p: function (val) {
__proto__: Object

jsfiddle

Если, однако, вы спрашиваете, почему вы не видите его значение: это потому, что значение теперь является частным и может быть прочитано только с помощью геттера.

console.log(o.p);

Обновление: прочитайте метод мутатора

Метод мутатора

Из Википедии, бесплатной энциклопедии

В информатике метод мутатора — это метод, используемый для управления изменениями переменной. Они также широко известны как «установочные» методы. Часто установщик сопровождается '''геттером'' (также известным как метод доступа), который возвращает значение закрытой переменной-члена. Метод мутатора, иногда называемый «установщиком», чаще всего используется в объектно-ориентированном программировании в соответствии с принципом инкапсуляции. В соответствии с этим принципом переменные-члены класса делаются закрытыми, чтобы скрыть и защитить их от другого кода, и могут быть изменены только с помощью общедоступной функции-члена (метода-мутатора), которая принимает желаемое новое значение в качестве параметра, необязательно проверяет его и изменяет закрытую переменную-член.

Рассмотрим этот пример

function MyClass() {
    var privateVar = 0;

    this.getPrivate = function () {
        return privateVar;
    }

    this.setPrivate = function (value) {
        privateVar = value;
    }
}

var newObject = new MyClass();

console.log(newObject);

console.log(newObject.getPrivate());

Выход

MyClass {getPrivate: function, setPrivate: function}
getPrivate: function () {
setPrivate: function (value) {
__proto__: MyClass

0

На jsfiddle

Вы можете просмотреть объект и увидеть общедоступные методы getPrivate и setPrivate (похожие на настоящие геттеры и сеттеры, созданные Object.defineProperty), но вы не можете увидеть значение переменной-члена privateVariable. Вы можете просмотреть значение, только вызвав общедоступный метод getPrivate.

person Xotic750    schedule 18.07.2013
comment
Спасибо, но, честно говоря, я не принял это как ответ, потому что это действительно мало что объясняет. Да, на смену «свойству p» приходит пара get/set p. Я могу предположить, что есть много других, которые думают, что этот наблюдаемый факт немного сбивает с толку. Я надеялся, что этот вопрос может привести к некоторому объяснению, чтобы я/мы могли лучше понять Object.defineProperty, следовательно, лучше понять свойства объекта javascript. - person kakacii; 18.07.2013
comment
@kakacii ответил на ваш вопрос: Почему свойство невидимо?; Это не так. Попробуйте перефразировать свой вопрос. - person canon; 18.07.2013
comment
@ Xotic750 Я вижу твое обновление. Я ценю ваши усилия, чтобы помочь людям, но не обижайтесь, либо вы склонны все упрощать, либо вы мастер js. Я просто думаю, что дескрипторы свойств, присутствующие в объектах, бывают двух основных видов: дескрипторы данных и дескрипторы доступа, это нелогично и, по-видимому, не очень хороший дизайн. Может быть, это только я. - person kakacii; 19.07.2013
comment
@canon, если вы так говорите .. Я сделал единственный ответ принятым ответом. - person kakacii; 19.07.2013