<!-- Love javascript-obfuscator? Please consider supporting our collective: 👉 https://opencollective.com/javascript-obfuscator/donate --> <!--- Provide a general summary of the issue in the Title above --> ## Expected Behavior <!--- Tell us what should happen --> The obfuscated output should preserve the original binding semantics. A semantically correct result would be equivalent to: ```js import { i as _imp } from './runtime.js'; function factory() { return 'factory-result'; } var P = class _cls { static instance; static getInstance() { return _cls.instance ||= new _cls(), _cls.instance; } }; var x = _imp(factory(), 1); export { P, x }; ``` or: ```js import { i as _imp } from './runtime.js'; function factory() { return 'factory-result'; } var _P = class { static instance; static getInstance() { return _P.instance ||= new _P(), _P.instance; } }; var x = _imp(factory(), 1); export { _P as P, x }; ``` ## Current Behavior <!--- Tell us what happens instead of the expected behavior --> The obfuscated output rewrites the class self-reference to the imported binding. It becomes effectively: ```js import { i as _0x48e620 } from './runtime.js'; function factory() { return 'factory-result'; } var P = class e { static ['instance']; static ['getInstance']() { return _0x48e620['instance'] ||= new _0x48e620(), _0x48e620['instance']; } }; var x = _0x48e620(factory(), 0x1); export { P, x }; ``` This is incorrect because `_0x48e620` is the imported binding, not the class. If the imported binding is a function or arrow function, runtime execution fails with: ```text TypeError: function is not a constructor ``` ## Steps to Reproduce <!--- Provide a link to a live example, or an unambiguous set of steps to --> <!--- reproduce this bug. Include code to reproduce, if relevant --> 1. Open https://obfuscator.io/legacy-playground 2. Paste `runtime.js` and the main module code below into the editor 3. Use the obfuscator options listed below 4. Run obfuscation 5. Inspect the generated `getInstance()` method 6. Notice that the class self-reference is rewritten to the imported binding ## JavaScript Obfuscator Edition - JavaScript Obfuscator Open Source - JavaScript Obfuscator Pro via API or [http://obfuscator.io](http://obfuscator.io]) ## Your Environment <!--- Include as many relevant details about the environment you experienced the bug in --> - `javascript-obfuscator`: `4.2.2` - Also reproduced after testing newer versions, including `5.3.0` - Node.js: `20.x` - OS: macOS # Stack trace <!--- Include stack trace --> ## Minimal working example that will help to reproduce issue <!--- Include code --> ```js // runtime.js export const i = (value, flag) => ({ value, flag }); ``` ```js import { i as e } from './runtime.js'; function factory() { return 'factory-result'; } var P = class e { static instance; static getInstance() { return e.instance ||= new e(), e.instance; } }; var x = e(factory(), 1); export { P, x }; ```
Activity
sanex3339 commentedon Mar 21, 2026
Released as 5.3.1