2

Q1: Can someone explain how to trigger setter in defineProperty, using it via function by this way?

Q2: How to get last key in setter?

fiddle is here

function test(root) {

  Object.defineProperty(this, 'subtree', {
    get: function() {
      console.log("get");
      return root.subtree;
    },
    set: function(value) { //doesn't triggered
      console.log("set");
      root.subtree = value;
    }
  });

}

var demo = new test({
    subtree: {
        state: null,
        test: 1
    }
});

console.log("START", demo.subtree);

demo.subtree.state = 13; // doesn't triggered setter, but change object

console.log("END", demo.subtree);
  • You can use get set functions, like demo.subtree.set({ state: 13, test: 1 }). To get key in setter use a object to store every time setter is fired. – Danish Nov 25 '17 at 13:21
  • Danish, result: Uncaught TypeError: demo.subtree.set is not a function. Any ideas? –  Nov 25 '17 at 13:38
  • [Read the manual please](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set). If you don't find any answer, come back. – An0num0us Nov 25 '17 at 13:40
  • var person = { firstName: 'Jimmy', lastName: 'Smith', get fullName() { return this.firstName + ' ' + this.lastName; }, set fullName (name) { var words = name.toString().split(' '); this.firstName = words[0] || ''; this.lastName = words[1] || ''; } } person.fullName = 'Jack Franklin'; console.log(person.firstName); // Jack console.log(person.lastName) // Franklin Try the above example.. – Danish Nov 25 '17 at 13:46
  • @PiotrKocia, i readed that also - [defineProperty](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty), and I really don't understand why [that](https://jsfiddle.net/tawvwpua/6/) setter works and why [that](https://jsfiddle.net/uat08xh6/7/) setter doesn't. –  Nov 25 '17 at 14:20
  • @Danish, ok but how to wrap it in function to call it in declaring object? And how to make it work without putting subkey name in it? –  Nov 25 '17 at 14:40
  • Try `demo.subtree = {state: 13}` to see your setter at work. – Bergi Nov 25 '17 at 15:15
  • @Bergi, thx it's worked, and now by Object.keys(value) i can get key name. But is there a way to make it works by calling it in this way: demo.subtree.state = 13? –  Nov 25 '17 at 15:31
  • @Romario For that you need to make `.state` of the `subtree` object a setter/getter property. – Bergi Nov 25 '17 at 16:20
  • @Bergi, example, please? –  Nov 25 '17 at 17:43
  • @Romario You will need to return an object from `get state` that is built similar to `new test()` – Bergi Nov 25 '17 at 18:48

1 Answers1

0

To make it simpler, this code

let variable = null;
let obj = {
    set variable(value) {
        variable = value;
    }
    get variable() {
        return variable;
    }
};

obj.variable = {a: 5};
console.log(obj.variable);

does exactly the same thing as this one

let variable = null;
let obj = {
    setVariable(value) {
        variable = value;
    }
    getVariable() {
        return variable;
    }
};

obj.setVariable({a: 5}); // equivalent to obj.variable = {a: 5}
console.log(obj.getVariable()); // equivalent to obj.variable

but the latter clearly shows what's going on.

We want to access a and set it to some value

console.log(obj.getVariable().a); // get a
obj.getVariable().a = 6; // set a!

Notice that we don't call setVariable to set a's value!!! This is exactly what happens in your code. You get subtree and set state to 13. To call setter, you do the following

obj.setVariable({a: 6});
obj.variable = {a: 6}; // getter/setter example
demo.subtree = {state: 13}; // your code

This and this (linked by you) present how scopes and capturing work, so you should get your hands on some book that covers all those things (or browse SO, there are (probably) plenty of questions about that).

An0num0us
  • 961
  • 7
  • 15
  • Ie, there is no way to run setter by 'tree.subtree = val'? Then how it works in vue.js? –  Nov 25 '17 at 15:53
  • @Romario what do you mean by `tree.subtree = val`? Full code sample maybe? – An0num0us Nov 25 '17 at 16:00
  • Piotr, there is no full code, only [fiddle from topic](https://jsfiddle.net/2rbor3qr/). Just trying to understand how reactive JS frameworks works and how to catch changes in object, and then do some magic with it. –  Nov 25 '17 at 16:14
  • Hahaha... You should have called the question "How do frameworks observe objects". Anyway, they do some magic inside (such as creating getters/setters for each property/function/whatever to notify appropriate observers). Notice that they don't know about things you don't tell them you did. You should read about *observer pattern* and write your own (simple!) observer. You should also read [vue's reactivity docs](https://vuejs.org/v2/guide/reactivity.html) (vue or any other framework) to learn how such pattern looks from the "outside". – An0num0us Nov 25 '17 at 18:24
  • Piotr, thx for your attention, but 'hahaha' what? I'm not programmer, it's my hobby. I've read that article before creating topic and seen 'Vue will walk through all of its properties and convert them to getter/setters using Object.defineProperty', then i've read about it on MDN, then tried some code and stucked with setter. As result i've created this topic. Main point of my question was "how to make setter works in this way", and under "this way" i meant calling a function with setter/getter inside while declaring an object. Not just setter/getter of object. –  Nov 25 '17 at 20:04