覆盖 javascript class 中的默认值,例如 php 中的 __get

Override default get in javascript class such as __get in php

我正在构建一个 javascript 库,我希望能够像 PHP 的 __get 那样做。

我的库有一个 attributes 属性 存储每个模型的属性。现在,我被迫使用 .get 方法获取属性。但我可以用 getter 来完成。假设用户扩展了我的模型 class.

let instance = new User({firstname: 'John', lastname: 'Doe'});
console.log(instance.get('firstname')); // gives me 'John'

我希望能够执行 instance.firstname 这将调用 .get 方法并将 'firstname' 作为参数传递。在 PHP 中,您可以这样做:http://php.net/manual/fr/language.oop5.overloading.php#object.get

这可能吗?

谢谢大家

非常简单地在循环中分配属性:

User = function (attrs) {
    for (var name in attrs) {
        this[name] = attrs[name];
    }
}

User.prototype = {
   // further methods
}

使用 ES6 class 语法,- 我不得不承认我不明白这样写东西的意义:

class User {
    constructor (attrs) {
        for (var name in attrs) {
            this[name] = attrs[name];
        }
    }

    // further methods
}

记住:第二种语法与第一种语法完全相同,只是在上面加了一些糖。

这很容易使用 ES 2015 类:

class Foo {
  constructor () {
    this._bar = null;
  }

  get bar () {
    doStuff();
    return this._bar;
  }

  set bar (val) {
    doOtherStuff();
    this._bar = val;
    return this;
  }
};

var foo = new Foo();
foo.bar = 3; // calls setter function
console.log(foo.bar); // calls getter function

这是 babel 的(简化)输出:

var Foo = function () {
  function Foo() {
    this._bar = null;
  }

  _createClass(Foo, [{
    key: "bar",
    get: function get() {
      doStuff();
      return this._bar;
    },
    set: function set(val) {
      doOtherStuff();
      this._bar = val;
      return this;
    }
  }]);

  return Foo;
}();

请注意,这不仅适用于 类,任何任意对象都可以具有这些:

var baz = {
  get qux() {
    // arbitrary code
  },
  set qux(val) {
    // arbitrary code
  }
};

Source.

编辑


你想要的是可能的,但只能在原生 ES 6 环境中实现,因为 Proxy 无法填充。

var getter = function(target, property, proxy) {
  console.log(`Getting the ${property} property of the obj.`);
  return target[property];
};

var setter = function(target, property, value, proxy) {
  console.log(`Setting the ${property} property to ${value}.`);
  target[property] = value;
};

var emptyObj = {};

var obj = new Proxy(emptyObj, {
  get: getter,
  set: setter
});

obj.a = 3; // logs 'Setting the a property to 3'
var foo = obj.a; // logs 'Getting the a property of the obj'