Javascript(ECMA-6)类魔术方法___;调用类似PHP

Javascript(ECMA-6)类魔术方法___;调用类似PHP,javascript,ecmascript-6,Javascript,Ecmascript 6,这是我的用例 getSomeFields(persons, fields){ let personsWithSpecificFields = []; _.each(persons, (person) => { let personSpecificFields = {}; _.each(fields, (field) => { // here im thinking to modify the field

这是我的用例

getSomeFields(persons, fields){

    let personsWithSpecificFields = [];

    _.each(persons, (person) => {

        let personSpecificFields = {};

        _.each(fields, (field) => {
            // here im thinking to modify the field to match the method name 
            // ( if something like __call as in php is available)
            // e.g. field is first_name and i want to change it to getFirstName
            personSpecificFields[field] = person[field]();

        });

        personsWithSpecificFields.push(personSpecificFields);
    });

    return personsWithSpecificFields;
}
这是我的
个人类

import _ from 'lodash';

export default class Person{

    // not working..
    __noSuchMethod__(funcName, args){
        alert(funcName);
    }

    constructor( data ){
        this.init(data);
    }

    init(data) {
        _.each(data, (value, key) => {
           this[key] = value;
        });
    }
}
我经历过,试图实现这一点,但没有运气

我知道我可以通过编写另一个方法来实现这一点,该方法将我的
first\u name
转换为
getFirstName
,并试一试。但是在ECMA-6中有没有什么方法可以像在课堂上那样做到这一点呢


谢谢。

在Javascript中没有像PHP中那样的特殊方法(),所以您只有那些
getter
setter
toString()
valueOf()

您可以给
Object.defineProperty()
一个快照,因为这样您就可以动态创建getter,如下所示:

Object.defineProperty(obj, 'first_name', {
   get: function () { return … }
});

结果类似于:

var obj = {
  get first_name () { return … }
}
如果需要调用对象的方法,也可以这样做:

var prop = 'getFirstName',
    result = obj[prop]();
for
循环中也可以做些什么。

您可以使用来检测对对象没有的属性的访问,并对其进行处理——这接近PHP的
\u调用

var person = new Person();
// Wrap the object in a proxy
var person = new Proxy(person, {
    get: function(person, field) {
        if (field in person) return person[field]; // normal case
        console.log("Access to non-existent property '" + field + "'");
        // Check some particular cases:
        if (field == 'first_name') return person.getFirstName;
        // ...
        // Or other cases:
        return function () {
            // This function will be executed when property is accessed as a function
        }
    }
});
您甚至可以在类的构造函数中执行此操作:

class Person {
    constructor(data) {
        this.init(data);
        return new Proxy(this, {
            get: function(person, field) {
                if (field in person) return person[field]; // normal case
                console.log("Access to non-existent property '" + field + "'");
                // Check some particular cases:
                if (field == 'first_name') return person.getFirstName;
                // ...
                // Or other cases:
                return function () {
                    // This function will be executed when property is accessed as a function
                    return 15; // example
                }
            }
        });
    }
    // other methods ...
    //
}
代理的好处是,返回的对象仍然被视为原始类的实例。使用上述代码,将实现以下情况:

new Person() instanceof Person

对象实例就是任何对象。函数是对象。因此,函数也可以具有属性,这些属性也可以是其他方法。如果你想要一个“可调用对象”,那就把它变成一个函数。好:你搜索了其他的解决方案。坏:你找到了第一个答案后就停止阅读了。无论如何,当您执行ES6时,请尝试
Proxy
解决方案。@Boldewyn让我试试,先生,它已过时,get对字段有效,但对方法无效。get对方法也有效,但请注意不要在代理中调用它们,而只返回函数引用。例如,请注意,在示例代码中,我没有在
person.getFirstName
之后添加括号。方法本质上也是属性,它们恰好是函数类型。对于
JSON.stringify