【问题标题】:Javascript ES6 retrieve members of class [duplicate]Javascript ES6检索类的成员[重复]
【发布时间】:2016-03-15 07:52:49
【问题描述】:

这个想法是获取类的方法/属性列表。比如我有这个类:

// foo.js
class FooController {
    constructor() {
    }
    *bar(next) {
        yield next;
        return 'meh';
    }
    //,
    meh() {
        return 'bar';
    }
}
module.exports = FooController;

现在我想检索FooController 的成员。这对于 javascript plain object 应该很容易完成,但对于 class 则不然:

// index.js
var Foo = require('foo');
var foo = new Foo();

// inspect
console.log(foo); // expected: { bar, meh }, but got {}

// struggle with lodash
var _ = require('lodash');    
console.log(_.keys(foo)); // expected ['bar', 'meh'], but got []

有什么想法吗?提前感谢您的任何帮助或建议。

【问题讨论】:

  • *bar 后面的逗号是故意的吗?我在那里遇到语法错误。
  • 哦,抱歉,打错了——让我编辑一下,感谢您的更正!

标签: javascript class reflection ecmascript-6


【解决方案1】:

ES6 中的classes 只是在 ES5 中函数的 prototype 上定义方法的糖编码。所以对于你的例子:

class FooController {
    constructor() {
    }
    *bar(next) {
        yield next;
        return 'meh';
    }
    //,
    meh() {
        return 'bar';
    }
}
module.exports = FooController;

等效的 ES5 是:

var FooController = (function() {
    function FooController() { } // This method will act as our constructor

    // All methods defined on the prototype are equivalent with the
    // so called class methods in ES6
    FooController.prototype.bar = *function(next) { yield next; return 'meh'; };

    FooController.prototype.meh = function() { return 'bar'; };

    return FooController;
})();

要访问关闭FooController 的“公共”方法,您可以:

  1. 像这样显式访问原型:FooController.prototype

    console.log(FooController.prototype.meh()) // => 'bar'

  2. 像这样访问构造对象的原型:

    var foo = new FooController(); var proto = foo.__proto__; console.log(proto.meh()) // => 'bar'

当您调用new 关键字构造foo 时,会发生以下几个步骤:

  1. 将创建一个新对象
  2. 该对象的原型将指向FooController的原型;

只要您将class methods 视为prototype 方法的糖编码,就可以更容易地控制这种情况。

希望这会有所帮助。

【讨论】:

  • 它不工作,它在两个方向都显示[](参见:jsfiddle.net/budiadiono/r2wdgkmk/1)。我想我会使用@Dmitri Pavlutin 的答案。
  • mehbar 不是可枚举的属性。这就是Object.keys() 不起作用的原因。
  • 是的,Dimitri 是对的。我将编辑我的答案。您可以直接从原型访问方法,您不能使用keys() 方法列出它们。
  • 啊我现在明白了,很好的解释!谢谢安德烈!
【解决方案2】:

您应该查询Foo() 类实例的prototype 对象:

// index.js
var Foo = require('foo');
var foo = new Foo();

var _ = require('lodash');    
console.log(Object.getOwnPropertyNames((Object.getPrototypeOf(foo)))); // shows ['bar', 'meh', 'constructor']
// or
console.log(Object.getOwnPropertyNames(foo.__proto__)); // shows ['bar', 'meh', 'constructor']

提议的_.keys(foo)只返回对象拥有的属性(bar()meh()是继承的),实际上是空的[]

要检索您需要的方法:

  • 访问实例的prototype对象
  • 枚举prototype 的属性。因为所需的属性不可枚举(Object.keys()_.keys() 不起作用),所以必须使用Object.getOwnPropertyNames()

详细了解Object.getPrototypeOf()Object.getOwnPropertyNames()
有关完整示例,请参阅 this fiddle

【讨论】:

  • 在我的最后,它显示[]而不是['bar', 'meh']
  • @Adiono 哎呀。答案已更新。
  • 酷!它现在可以工作了,谢谢 Dmitri!
【解决方案3】:

选项 1:您可以打印 class constructor,得到所需的结果:

class FooController {
    constructor() {
    }
    *bar(next) {
        yield next;
        return 'meh';
    }
    meh() {
        return 'bar';
    }
}


var foo = new FooController();

console.log(foo.constructor);

function class FooController {
    constructor() {
    }
    *bar(next) {
        yield next;
        return 'meh';
    }
    meh() {
        return 'bar';
    }
}

选项 2:您可以直接打印 class object 而不绑定它:

class FooController {
    constructor() {
    }
    *bar(next) {
        yield next;
        return 'meh';
    }
    meh() {
        return 'bar';
    }
}

console.log(FooController);

function class FooController {
    constructor() {
    }
    *bar(next) {
        yield next;
        return 'meh';
    }
    meh() {
        return 'bar';
    }
}

【讨论】:

  • 问题是如何检索成员,而不是如何打印蓝图。
  • 是的,@zeroflagL 是对的!我想要成员而不是蓝图。
猜你喜欢
  • 2015-07-23
  • 1970-01-01
  • 2017-10-05
  • 2018-03-29
  • 2015-04-03
  • 1970-01-01
  • 2020-05-03
  • 2016-07-11
  • 2012-07-24
相关资源
最近更新 更多