What is the property of __defineSetter__ and __defineGetter__ for?

3

Whenever I open the Chrome Console, I keep an eye on the autocomplete of properties, to see if there is anything new, something I have not yet learned. And it struck me to see that objects have the property called __defineSetter__ and __defineGetter__ .

I noticed that this property exists in the object window , as well as in literal objects we created.

I'd like to know exactly how this works.

These properties affect how values are defined in an object What is the purpose of these values?

I'd like to know details about browser compatibility (I'm asking this question in 2018) and it's related to Object.defineProperty

    
asked by anonymous 18.05.2018 / 20:06

2 answers

3

Both Object.prototype.__defineSetter__ and Object.prototype.__defineGetter__ are obsolete methods (and also not standardized ), in their places you can use the method:

The use of both obsolete methods as well as the new / standardized API is "detect / execute" when setting a value to a property of the object ( set ) and when it tries to get the value of a property (% with%).

But of course it's not just getting a value or setting one, actually at this point you as a programmer will decide if something will actually be set or something will return, similar to the magic methods get and __set of PHP.

Detecting when setting a value to an object

If you want a function to be triggered when set a value then you would do this in the old syntax:

var o = {};

o.__defineSetter__('foo', function(val) {
    console.log("foo:", val);
});

o.__defineSetter__('bar', function(val) {
    console.log("bar:", val);
});

document.getElementById("to-foo").onclick = function () {
    o.foo = new Date().toString();
};

document.getElementById("to-bar").onclick = function () {
    o.bar = new Date().toString();
};

document.getElementById("get-foo").onclick = function () {
    console.log(o.set);
};

document.getElementById("get-bar").onclick = function () {
    console.log(o.bar);
};
<button id="to-foo">Setar valor para o.foo</button>
<button id="to-bar">Setar valor para o.bar</button><br>
<button id="get-foo">Exibir valor de o.foo</button>
<button id="get-bar">Exibir valor de o.bar</button>

Standardized syntax:

var o = {};

Object.defineProperty(o, 'foo', {
    set: function(val) {
         console.log("foo:", val);
    }
});

Object.defineProperty(o, 'bar', {
    set: function(val) {
         console.log("bar:", val);
    }
});

document.getElementById("to-foo").onclick = function () {
    o.foo = new Date().toString();
};

document.getElementById("to-bar").onclick = function () {
    o.bar = new Date().toString();
};

document.getElementById("get-foo").onclick = function () {
    console.log(o.set);
};

document.getElementById("get-bar").onclick = function () {
    console.log(o.bar);
};
<button id="to-foo">Setar valor para o.foo</button>
<button id="to-bar">Setar valor para o.bar</button><br>
<button id="get-foo">Exibir valor de o.foo</button>
<button id="get-bar">Exibir valor de o.bar</button>

Note that no value has been set, on the display buttons __get only displays console.log , this means that we only intercept the execution / action of setar, but within undefined defined nothing is done, then it is at this point that you decide if something will occur and how it should occur.

Detecting when trying to get a value from an object

If you want to develope a custom value according to the need of your business / behavior then you would do this with old syntax:

var o = {};

o.__defineGetter__('foo', function(val) {
    return +new Date;
});

o.__defineGetter__('bar', function() {
    return +new Date;
});

document.getElementById("get-foo").onclick = function () {
    console.log("valor de foo:", o.foo);
};

document.getElementById("get-bar").onclick = function () {
    console.log("valor de bar:", o.bar);
};
<button id="get-foo">Pegar valor de o.foo</button>
<button id="get-bar">Pegar valor de o.bar</button>

Standardized syntax:

var o = {};

Object.defineProperty(o, 'foo', {
    get: function () {
       return +new Date;
    }
});

Object.defineProperty(o, 'bar', {
    get: function () {
       return +new Date;
    }
});

document.getElementById("get-foo").onclick = function () {
    console.log("valor de foo:", o.foo);
};

document.getElementById("get-bar").onclick = function () {
    console.log("valor de bar:", o.bar);
};
<button id="get-foo">Pegar valor de o.foo</button>
<button id="get-bar">Pegar valor de o.bar</button>

Using function with Object.defineProperty and get

One thing is that in standard syntax you do not need to do:

var o = {};

Object.defineProperty(o, 'bar', {
    get: function () {
       /* retorna valor */
    }
});

Object.defineProperty(o, 'foo', {
    set: function (val) {
       /* seta valor */
    }
});

o.foo = 'test'; //Executa set:
console.log(o.foo); //Executa get:

You can do this for set :

var o = {};

Object.defineProperty(o, 'foo', {
    get: function () {
       /* retorna valor */
    },
    set: function (val) {
       /* seta valor */
    }
});

o.foo = 'test'; //Executa set:
console.log(o.foo); //Executa get:

Operators o.foo and set

Alternatively to get you can use the operators:

var o = {
    set foo(val) {
       console.log("Seta valor para o.foo:", val);
    },
    set bar(val) {
       console.log("Seta valor para o.bar:", val);
    },
    set baz(val) {
       console.log("Seta valor para o.baz:", val);
    },
    get foo() {
       return +new Date;
    },
    get bar() {
       return +new Date;
    },
    get baz() {
       return +new Date;
    }
};

o.foo = 100;
o.bar = 220;
o.baz = 333;

console.log("Pega o valor de o.foo:", o.foo);
console.log("Pega o valor de o.bar:", o.bar);
console.log("Pega o valor de o.baz:", o.baz);

Object.defineProperty vs Object.defineProperty / get

Although some places claim that they are identical in their goals, the use of set in the third parameter (where we define Object.defineProperty and get ) has some specific settings:

  • set
  • configurable
  • enumerable (optional)
  • value (optional)
  

I'll be editing this part soon with details, I've never really used these settings to get the hang of it.

    
19.05.2018 / 06:29
2

They serve to define a method that will be called when something is trying to assign a new value to the current object, or when something tries to read the value of the current object.

Example.

var obj = "";
obj.__defineSetter__('value', function(val) { alert('x'); });

In the above case, if any method attempts to change the value of the obj variable, an alert with the text "x" will be issued.

Same thing for defineGetter , but for reading value.

    
18.05.2018 / 20:29