2017-02-22 36 views
1

Я создаю javascript-библиотеку, и я хотел бы иметь возможность делать то же, что и PHP __get.Переопределить значение по умолчанию в классе javascript, таком как __get в php

В моей библиотеке есть свойство attributes, в котором хранятся атрибуты каждой модели. Теперь я могу получить атрибут, используя метод .get. Но я смогу сделать это с помощью геттера. Давайте скажем, что Пользователь расширяет мой модельный класс.

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

Я хочу быть в состоянии сделать instance.firstname, который будет вызывать метод .get проходящее «ПгвЬЫата» в качестве параметра. В PHP вы можете сделать это так: http://php.net/manual/fr/language.oop5.overloading.php#object.get

Возможно ли это?

Спасибо всем

ответ

0

Это легко с помощью 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 

вот (упрощенный), выводимый из Бабеля:

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.

EDIT

То, что вы хотите, это возможно, но только в родных ES 6 средах, а Proxy не может быть polyfilled.

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' 
+0

Я уже все это знаю.Дело в том, что свойства - это динамика. Я хочу, чтобы 'foo.bar' называет' foo.get ('bar') 'и что' foo.baz' вызывает 'foo.get ('baz')', короче –

+0

@NicolasBoisvert обновлен. Его возможно, но не очень портативным. –

0

Довольно просто присваивают свойства в цикле:

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

User.prototype = { 
    // further methods 
} 

Используя синтаксис класса ES6, - я должен признать, что я не вижу смысла писать вещи таким образом:

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

    // further methods 
} 

Помните: второй синтаксис именно то, что происходит с первым, только с некоторым сахаром на вершине.

+0

Я видел такие вещи, дело в том, что атрибуты всегда меняются. Что вы предлагаете, при создании объекта, итерации через атрибут для создания геттеров? –

+0

Не уверен, что я полностью понимаю, но если они динамичны, ну почему бы и нет? Объект properties является простым объектом; вы можете построить его так, как хотите. – ccprog

+0

Ах. Теперь я вижу. Вы хотите разместить несколько атрибутов с одной единственной функцией, в то время как я думал о функции геттера, которая могла бы преобразовывать данные перед выходом. Я поменяю свой пример на вашу проблему. – ccprog