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

javascript - ERROR TypeError: Constructor Map requires 'new' in ES5? - Stack Overflow

programmeradmin3浏览0评论

Code is:

export class ExtendedMap<T, U> extends Map {
    constructor() {
        super();
    }

    toggle(key: T, value: U) {
        if (this.has(key)) {
            super.delete(key);
        } else {
            super.set(key, value);
        }
    }

    has(key: T): boolean {
        return super.has(key);
    }
}

I get this error for ES5 pilation:

ERROR TypeError: Constructor Map requires 'new'

I'm using it like this:

public registryLayers = new ExtendedMap<number, any>();

Snippet (without TypeScript parts mented out):

/*export*/ class ExtendedMap/*<T, U>*/ extends Map {
    constructor() {
        super();
    }

    toggle(key/*: T*/, value/*: U*/) {
        if (this.has(key)) {
            super.delete(key);
        } else {
            super.set(key, value);
        }
    }

    has(key/*: T*/)/*: boolean*/ {
        return super.has(key);
    }
}
/*public*/ registryLayers = new ExtendedMap/*<number, any>*/();
console.log("Worked without error");

Code is:

export class ExtendedMap<T, U> extends Map {
    constructor() {
        super();
    }

    toggle(key: T, value: U) {
        if (this.has(key)) {
            super.delete(key);
        } else {
            super.set(key, value);
        }
    }

    has(key: T): boolean {
        return super.has(key);
    }
}

I get this error for ES5 pilation:

ERROR TypeError: Constructor Map requires 'new'

I'm using it like this:

public registryLayers = new ExtendedMap<number, any>();

Snippet (without TypeScript parts mented out):

/*export*/ class ExtendedMap/*<T, U>*/ extends Map {
    constructor() {
        super();
    }

    toggle(key/*: T*/, value/*: U*/) {
        if (this.has(key)) {
            super.delete(key);
        } else {
            super.set(key, value);
        }
    }

    has(key/*: T*/)/*: boolean*/ {
        return super.has(key);
    }
}
/*public*/ registryLayers = new ExtendedMap/*<number, any>*/();
console.log("Worked without error");

Share Improve this question edited Mar 2, 2021 at 11:30 T.J. Crowder 1.1m200 gold badges2k silver badges2k bronze badges asked Mar 2, 2021 at 11:24 user14480036user14480036 12
  • 1 I was just about to point out that Map wasn't in ES5. Also note that there's no point to either the constructor or the has override in your code. You can inherit both, since neither does anything new. It would also probably be best to use this rather than super in toggle. – T.J. Crowder Commented Mar 2, 2021 at 11:32
  • 1 Then you'll need a polyfill, because ES5 didn't have Map. – T.J. Crowder Commented Mar 2, 2021 at 11:33
  • 1 FWIW here's a playground link – T.J. Crowder Commented Mar 2, 2021 at 11:37
  • 1 @T.J.Crowder wow! I mean - WOOOOOW. I have never used Symbol.species before. I should have follow your answers a long time ago – captain-yossarian from Ukraine Commented Mar 2, 2021 at 12:07
  • 1 @T.J.Crowder yes, I know, I saw it on your blog. This, defenitely, will be my next book. For now I have two others I did not finished yet )). I like that you went deeper into JS specification – captain-yossarian from Ukraine Commented Mar 2, 2021 at 12:25
 |  Show 7 more ments

1 Answer 1

Reset to default 6

TypeScript should be plaining about Map if you're targeting ES5 (it does in this example).

If you ignore that error from TypeScript and then run the code that TypeScript generates in a modern(ish) JavaScript engine, the problem is that the code TypeScript created is trying to call Map like an old-style constructor function. When you configure TypeScript to emit ES5 code, it doesn't emit class constructs because ES5 didn't have them. Instead, it emits constructor function syntax, and in your ExtendedMap constructor, it tries to call Map like this:

return _super.call(this) || this; // Where `_super` is set to `Map`

But in a modern environment, Map is defined as a class constructor and cannot be called that way, resulting in the error you're getting.

If you need your code to run in an ES5 environment, you need to include a Map polyfill (since Map didn't exist in ES5) that is written to be patible with an ES5 environment so that Map can be called via .call as above. And if your code is running in a modern(ish) environment that already has Map, you'll still need to include the polyfill because of the way it gets called.

发布评论

评论列表(0)

  1. 暂无评论