首页 > 解决方案 > 是否有等效于 Python 的 getattr() 函数的 Javascript?

问题描述

Javascript 是否有等效的 getattr() 函数?或者我可以喜欢编写自己的函数吗?我真的不知道该去哪里。蟒蛇代码:

method = getattr(self, method_name)
method()

标签: javascriptpython

解决方案


与 Python 不同,在 Javascript 中,对象属性(使用点访问)和“项目”(使用方括号访问)之间没有区别。

因此,在 Javascript 中,可以使用方括号间接访问属性,即

someObj.propName

someObj[expression that returns 'propName']

做同样的事情,特别是,

someObj.foo === someObj['foo']

这与getattr所做的类似,但有一些注意事项需要牢记:

首先, distinct getattr[]如果属性不存在则不会抛出。它只是默默地返回undefined

其次,没有提供默认值的选项,因此如果需要,您必须使用条件

value = propName in someObj ? someObj[propName] : defaultValue

第三个也是最重要的,适用于所讨论的属性是方法时。在 python 中,myObject.someMethodorgetattr(someObj, methodName)将返回一个绑定函数,该函数知道它自己的宿主对象,或者self. 因此,您可以直接调用返回值:

class MyClass:
    def __init__(self):
        self.thing = 'hey'

    def test(self):
        print(self.thing)

myObject = MyClass()
methodName = 'test'

method = getattr(myObject, methodName)

method()  # ok

在 javascript 中,myObject.someMethodorsomeObj[methodName]将返回一个未绑定的函数,该函数“不知道”它属于哪个对象。因此,如果您将其存储在一个变量中并稍后调用它,那将不起作用:

class MyClass {
    constructor() {
        this.thing = 'hey'
    }
    test() {
        console.log(this.thing);
    }
}

myObject = new MyClass()
methodName = 'test'

method = myObject[methodName]

method() // NOT OK

您必须明确地“重新绑定”该方法才能调用它:

boundMethod = method.bind(myObject)
boundMethod() // ok

请注意,这只适用于将方法存储在变量中(或作为参数传递)时。当您立即调用它时,一切都按预期工作:

myObject[methodName]()  // ok

总而言之,python 的模糊模拟getattr在 Javascript 中可能如下所示:

function getattr(obj, prop, defaultValue = null) {

    if (prop in obj) {
        let val = obj[prop];
        if (typeof val === 'function')
            return val.bind(obj);
        return val;
    }

    if (arguments.length > 2) {
        return defaultValue;
    }

    throw new TypeError(`"${obj}" object has no attribute "${prop}"`)
}

推荐阅读