最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ES6 use `super` out of class definition - Stack Overflow

programmeradmin0浏览0评论

I'm trying to add extra methods to class, and these extra methods should use the super methods.

If I add them in the model definition, it works.

class A {
    doSomething() {
        console.log('logSomething');
    }

}

class B extends A {
    doSomething() {
        super.doSomething();
        console.log('logSomethingElse');
    }
}

If I try to add the extra method to B.prototype, I'll get SyntaxError: 'super' keyword unexpected here.

class A {
    doSomething() {
        console.log('logSomething');
    }

}

class B extends A {
}

B.prototype.doSomething = function doSomething() {
    super.doSomething();
    console.log('logSomethingElse');
}

It is quite clear, why I get this error. This is a function and not a class method.

Let's try to define the method as a class method, and copy it to the original B class:

class A {
    doSomething() {
        console.log('logSomething');
    }

}

class B extends A {}

class X {
    doSomething() {
        super.doSomething();
        console.log('2 logSomethingElse');
    }
}

B.prototype.doSomething = X.prototype.doSomething;

In this case I'll get TypeError: (intermediate value).doSomething is not a function.

Is there any way to define methods (that refer to super) outside from the original class definition, and add these methods later to the original class?

I'm trying to add extra methods to class, and these extra methods should use the super methods.

If I add them in the model definition, it works.

class A {
    doSomething() {
        console.log('logSomething');
    }

}

class B extends A {
    doSomething() {
        super.doSomething();
        console.log('logSomethingElse');
    }
}

If I try to add the extra method to B.prototype, I'll get SyntaxError: 'super' keyword unexpected here.

class A {
    doSomething() {
        console.log('logSomething');
    }

}

class B extends A {
}

B.prototype.doSomething = function doSomething() {
    super.doSomething();
    console.log('logSomethingElse');
}

It is quite clear, why I get this error. This is a function and not a class method.

Let's try to define the method as a class method, and copy it to the original B class:

class A {
    doSomething() {
        console.log('logSomething');
    }

}

class B extends A {}

class X {
    doSomething() {
        super.doSomething();
        console.log('2 logSomethingElse');
    }
}

B.prototype.doSomething = X.prototype.doSomething;

In this case I'll get TypeError: (intermediate value).doSomething is not a function.

Is there any way to define methods (that refer to super) outside from the original class definition, and add these methods later to the original class?

Share Improve this question asked Oct 18, 2017 at 8:44 AdamAdam 5,2532 gold badges32 silver badges62 bronze badges 1
  • Sorry, I hastily closed as a duplicate of stackoverflow./questions/36273140/… - but that is about calling super() rather than the method on the super class. Pretty sure the answer may be the same though – CodingIntrigue Commented Oct 18, 2017 at 10:10
Add a ment  | 

3 Answers 3

Reset to default 9

super refers to ancestor of a class where the method was defined, it isn't dynamic. As Babel output illustrates this, super is hard-coded to Object.getPrototypeOf(X.prototype), and thus orphan class like this one doesn't make sense because it doesn't have super:

class X {
    doSomething() {
        super.doSomething();
        ...
    }
}

But super can be substituted with dynamic counterpart:

doSomething() {
    const dynamicSuper = Object.getPrototypeOf(this.constructor.prototype);
    // or
    // const dynamicSuper = Object.getPrototypeOf(Object.getPrototypeOf(this));
    dynamicSuper.doSomething();
    ...
}

class B extends A {}
B.prototype.doSomething = doSomething;

In this case it will refer to ancestor class of class instance where doSomething was assigned as prototype method.

While I think this could be assumed as anti-pattern, you shouldn't use super outside from a class.

You can achieve that using Object Literals.

Refer to Object.setPrototypeOf

const A = {
  sayHello() {
    console.log("I am A");
  },
  
  Factory() {
    return Object.create(this);
  }
}

const B = {
  sayHello() {
   super.sayHello();
  }
}

Object.setPrototypeOf(B, A);

const c = B.Factory();

c.sayHello();

If you don't make class X inherit from class B or A, the only way to call the method is A.prototype.doSomething() or more generally A.prototype.doSomething.call(this_substitute, ...args).

发布评论

评论列表(0)

  1. 暂无评论