示例:
class Complex
constructor: (@a, @b) ->
conjugate: -> new Complex(@a, -@b)
class ComplexSon extends Complex
constructor: (@a, @b) ->
@c = 3.14
magnitude: -> @a*@a + @b*@b
我定义了以下方法:
dumpMethods = (klass) ->
Object.getOwnPropertyNames(klass.property).sort()
测试用例:
dumpMethods(Complex) == ['conjugate', 'constructor']
# success
dumpMethods(ComplexSon) == ['conjugate', 'constructor', 'magnitude']
# fails, returns ['constructor', 'magnitude']
dumpMethods的正确定义是什么?
答案 0 :(得分:2)
禁令,
Javascript(以及咖啡脚本)使用原型对象。
我建议你阅读它,因为事情相当复杂。
试着总结一下,每个对象都有一个原型。原型本身就是一个对象,有自己的属性,还有一个原型,等等。
原型链实际上定义了类层次结构。所以在你的情况下,ComplexSon将有一个Complex的原型,它将拥有一个原型,它是Object本身,是javascript中所有对象层次结构的根。
当你在一个实例上调用一个方法时,javascript将在该实例上搜索该方法,然后在其原型中搜索,然后在链上。找到的第一个是它将执行的方法。
与大多数编程语言一样,您可以“升级”层次结构并查看超类,但很少会出现问题,因为语言解释器本身很少需要它。然而,有一些变通方法,比如原型使用的变通方法,可以知道给定类的子类,但是AFAIK它们本身不在文章中,通常它们只是跟踪定义的类。
关于方法,在您的代码中,您正在查看ComplexSon的属性,它正确地只包含两个方法。另一个(coniugate)不存在因为它是通过原型到达的,你可以通过递归上传原型链来列出它们。
答案 1 :(得分:2)
根据Gianni的回答,我最终得到了以下实施方案。 dumpMethods遍历根类Object,但避免列出Object中的方法。
dumpMethods = (klass) ->
res = []
k = klass.prototype
while k
names = Object.getOwnPropertyNames(k)
res = res.concat(names)
k = Object.getPrototypeOf(k)
break if not Object.getPrototypeOf(k) # suppress Object
res.unique().sort()