首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javascript (ECMA-6)类像PHP一样的魔术方法__call

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

Stack Overflow用户
提问于 2017-02-15 16:36:50
回答 2查看 10.5K关注 0票数 17

这是我的用例

代码语言:javascript
复制
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

代码语言:javascript
复制
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的方式做到这一点呢?

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-15 16:56:41

您可以使用proxy来检测对对象没有的属性的访问,并对其进行处理--这类似于PHP语言的__call

代码语言:javascript
复制
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
        }
    }
});

你甚至可以在你的类的构造函数中这样做:

代码语言:javascript
复制
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 ...
    //
}

代理的好处是返回的对象仍然被认为是原始类的实例。使用上面的代码,下面的代码将是真的:

代码语言:javascript
复制
new Person() instanceof Person
票数 31
EN

Stack Overflow用户

发布于 2017-02-15 16:41:59

在Javascript中没有像在PHP中那样的特殊__methods(),所以你所拥有的就是那些getterssetterstoString()valueOf()

你可以给Object.defineProperty()一次机会,因为你可以像这样动态创建getters:

代码语言:javascript
复制
Object.defineProperty(obj, 'first_name', {
   get: function () { return … }
});

mdn

结果类似于:

代码语言:javascript
复制
var obj = {
  get first_name () { return … }
}

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

代码语言:javascript
复制
var prop = 'getFirstName',
    result = obj[prop]();

for循环中也可以做什么。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42244315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档