访问超类上的类字段 [英] Accessing a class field on a superclass

查看:56
本文介绍了访问超类上的类字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含以下代码的文件:

 class Animal {
    doSomething = () => {
        return 'Hi.';
    };
}

class Dog extends Animal {
    doSomething = () => {
        return super.doSomething() + ' Woof!';
    };
}

console.log(new Dog().doSomething()); 

注意:尝试运行上面的代码段可能无法正常工作,因为我不知道如何使用我的Babal设置来设置它.

无论如何,当我使用Babel编译它并在Node中运行它时,出现以下错误:

/Users/elias/src/classFieldTest/build/classFieldTest.js:15
            return super.doSomething() + ' Woof!';
                         ^

TypeError: (intermediate value).doSomething is not a function
    at Dog.doSomething (/Users/elias/src/classFieldTest/build/classFieldTest.js:15:26)
    at Object.<anonymous> (/Users/elias/src/classFieldTest/build/classFieldTest.js:21:23)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

我使用的是预设为stage-2的Babel 6.26.0和Node 8.11.1.如果有人在意,我可以显示我正在使用的命令.

为什么会这样?我猜想super不能用于访问类字段,但是我应该怎么做?如果我将AnimaldoSomething方法更改为传统方法(doSomething() { return 'Hi.'; }),则可以使用,但是我宁愿避免使用传统方法,而是用它们重新定义this的方式以及它引起的所有混乱.

有什么方法可以访问超类的类字段?

解决方案

为什么会这样?我猜想super不能用于访问类字段

是的.类字段是实例属性,但是super尝试访问超类的原型对象上的属性.您的Animal类根本没有doSomething方法-相反,每个Animal对象都有一个包含绑定函数的属性.

但是我该怎么办?如果我将其更改为传统方法,则可以使用

是的,您应该做到这一点.方法和super就是这样.

避免箭头功能在不需要它们时,尤其是类属性中的箭头函数可能不如我们想象的那么大.

有什么方法可以访问超类的类字段?

是-它是一个实例属性,您可以在覆盖它之前在其构造函数中对其进行访问:

class Animal {
    constructor() {
        this.doSomething = () => {
             return 'Hi.';
        };
    }
}

class Dog extends Animal {
    constructor() {
        super();
        const superDoSomething = this.doSomething;
        this.doSomething = () => {
            return superDoSomething() + ' Woof!';
        };
    }
}

或者,使用类字段proposal而不使用显式构造函数:

class Animal {
    doSomething = () => {
        return 'Hi.';
    }
}

class Dog extends Animal {
    doSomething = (superDoSomething => () => {
        return superDoSomething() + ' Woof!';
    })(this.doSomething)
}

I have a file with the following code:

class Animal {
    doSomething = () => {
        return 'Hi.';
    };
}

class Dog extends Animal {
    doSomething = () => {
        return super.doSomething() + ' Woof!';
    };
}

console.log(new Dog().doSomething());

Note: trying to run the snippet above probably won't work because I can't figure out how to make it use my Babal settings.

Anyway, when I compile it using Babel and run it in Node, I get the following error:

/Users/elias/src/classFieldTest/build/classFieldTest.js:15
            return super.doSomething() + ' Woof!';
                         ^

TypeError: (intermediate value).doSomething is not a function
    at Dog.doSomething (/Users/elias/src/classFieldTest/build/classFieldTest.js:15:26)
    at Object.<anonymous> (/Users/elias/src/classFieldTest/build/classFieldTest.js:21:23)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3

I am using Babel 6.26.0 with the stage-2 preset, and Node 8.11.1. I can show the commands I'm using if anyone cares.

Why is this happening? I am guessing that super can't be used to access a class field, but what am I supposed to do about this? If I change the doSomething method of Animal to a traditional method (doSomething() { return 'Hi.'; }), it works, but I would rather avoid traditional methods, with the way they redefine this and all the confusion it causes.

Is there any way to access a class field of a superclass?

解决方案

Why is this happening? I am guessing that super can't be used to access a class field

Yes. Class fields are instance properties, but super tries to access properties on the superclass' prototype object. Your Animal class simply doesn't have a doSomething method - instead, every Animal object has a property that contains a bound function.

but what am I supposed to do about this? If I change it to a traditional method, it works

Yes, you are supposed to do exactly that. This is how methods and super work.

Avoid arrow functions when you don't need them, and especially when they don't work. Also have a look at Arrow Functions in Class Properties Might Not Be As Great As We Think.

Is there any way to access a class field of a superclass?

Yes - it is an instance property, and you can access it in your constructor before overwriting it:

class Animal {
    constructor() {
        this.doSomething = () => {
             return 'Hi.';
        };
    }
}

class Dog extends Animal {
    constructor() {
        super();
        const superDoSomething = this.doSomething;
        this.doSomething = () => {
            return superDoSomething() + ' Woof!';
        };
    }
}

Alternatively, with the class fields proposal and no explicit constructor:

class Animal {
    doSomething = () => {
        return 'Hi.';
    }
}

class Dog extends Animal {
    doSomething = (superDoSomething => () => {
        return superDoSomething() + ' Woof!';
    })(this.doSomething)
}

这篇关于访问超类上的类字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆