Javascript(ECMA-6)类魔术方法__call就像PHP一样

时间:2017-02-15 08:36:50

标签: javascript ecmascript-6

这是我的用例

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;
}

这是我的person class

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;
        });
    }
}

我已经完成Monitor All JavaScript Object Properties (magic getters and setters),尝试实施此JavaScript getter for all properties,但没有运气。

我知道我可以通过编写另一种方法来实现这一目标,这种方法会将我的first_name转换为getFirstName并给它一个机会。但有没有办法像ECMA-6那样在课堂上这样做。

感谢。

2 个答案:

答案 0 :(得分:12)

您可以使用proxy来检测对象所没有的属性的访问权限并处理它 - 这接近于PHP的__call

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

答案 1 :(得分:1)

在Javascript中没有像PHP中那样的特殊_Mocklogger.Verify(x =>x.LogMessage(LogSeverity.Error, expectedException, It.Is<System.Reflection.TargetParameterCountException>(CheckException)), Times.Once); private static bool CheckException(System.Reflection.TargetParameterCountException ex){ //... } ,所以你拥有的只有__methods()getterssetterstoString()

你可以给valueOf()一个镜头,因为你可以动态创建这样的getter:

Object.defineProperty()

mdn

结果类似于:

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

如果你需要调用一个对象的方法,你也可以这样做:

var obj = {
  get first_name () { return … }
}

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