Прикрепить функцию get/set к объекту в js

У меня по существу есть объект:

var foo = function() {
  this.setting = false;
  this.refresh = function() { ... };
}

let a = new foo();
a.setting = true; // a.refresh() is triggered

Мне нужно вызвать обновление в любое время .setting. Я чувствую, что это имеет какое-то отношение к bind, но я не мог это получить.

Ответ 1

Вам нужно использовать геттер и сеттер для вашего объекта. Один из способов - напрямую использовать функции getter/setter:

var foo = function()
{
   this.setting = false;
   this.getSetting = function() { return this.setting; }
   this.setSetting = function(val) { this.setting = val; this.refresh(); }
   this.refresh = function()
   {...}
}

Если вы хотите использовать foo.setting прозрачно как атрибут, для этого существуют языковые конструкции, но, к сожалению, они не совместимы между браузерами. В некотором роде назад к 3 годам ранее, один метод поддерживался Mozilla, Safari, Chrome и Opera и другим методом для Internet Explorer. Это стандартный метод:

http://robertnyman.com/2009/05/28/getters-and-setters-with-javascript-code-samples-and-demos/

В IE9 есть что-то еще, и я не уверен, работает ли он даже для объектов, отличных от DOM.

Ответ 2

Вы можете использовать JavaScript-получатели и сеттеры. См. документацию по MDC по теме и запись в блоге Джона Ресига по этому вопросу. Обратите внимание, что не все браузеры поддерживают это.

var Foo = function()//constructor
{
   this._settings = false;//hidden variable by convention
   this.__defineGetter__("settings", function(){
     return _settings;//now foo.settings will give you the value in the hidden var
   });

   this.__defineSetter__("settings", function(s){
      _settings = s;//set the hidden var with foo.settings = x
      this.refresh();//trigger refresh when that happens
   });

   this.refresh = function(){
      alert("Refreshed!");//for testing
   }
}

var a = new Foo();//create new object
a.settings = true;//change the property
//a.refresh() is triggered

Попробуйте!

Ответ 3

Вы ищете установщик настроек? Что-то вроде этого?

// renamed settings property with underscore
this._settings = false;

this.settings = function(s) {
     if(s !== undefined) {
        this._settings = s;
        this.refresh();
     }

     return this._settings;
};

...


var f = new foo();
f.setSettings(mySettings);

Я стараюсь объединить свой getter и setter в один метод в JavaScript, так как это так легко сделать. Недостатком этого является _settings, который по-прежнему остается открытым на вашем объекте, и каждый может напрямую писать ему. Единственный способ скрыть это - использовать закрытие, которое требует совершенно другого подхода к созданию ваших объектов.

Ответ 4

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

Ответ 5

Я не понимаю, почему вы пытаетесь использовать "новый" оператор, вам лучше использовать литерал объекта. Теперь, если вы похожи, скажем, на свойства С#, вы можете сделать что-то вроде этого:

var myObject = function(){
    //Private Members
    var myProperty = '';

        //Privileged Setter
        this.setMyProperty = function(value){
            myProperty = value;
        };

        //Privileged Getter
        this.getMyProperty = function(){
            return myProperty;
        }

}

var MyNewObject = new myObject();
MyNewObject.setMyProperty("Hello, World!");
MyNewObject.getMyProperty();

Для получения дополнительной информации я рекомендую следующее: http://www.crockford.com/javascript/private.html

Ответ 6

Я знаю, что это уже старый вопрос, на который уже был дан ответ, но я хотел бы предложить решение, которое использует синтаксис последнего JavaScript.


Определите class с getter и setter:

class Foo {
  constructor() {
    this._setting = false;
  }

  get setting() {
    return this._setting;
  }

  set setting(value) {
    this._setting = value;
    this.refresh();
  }

  refresh() {
    console.log("refresh!");
  }
}

let foo = new Foo();
foo.setting = true; // foo.refresh() is called