eslint-plugin-unicorn
eslint-plugin-unicorn copied to clipboard
Rule proposal: `no-this-outside-of-class`
Description
In modern JavaScript, this should not appear outside of an class.
Fail
function foo () {
this.bar;
}
function Foo(name) {
this.name = name;
}
class Foo {
foo() {
function bar() {
this.baz;
}
}
}
Pass
class Foo {
foo() {
this.name;
}
}
class Foo {
foo() {
const bar = () => {
this.name;
}
}
}
Proposed rule name
no-this-outside-of-class
Additional Info
No response
This rule should be easy to implement. It is similar to this rule #2525
Once this rule is accepted, I will work on it.
@sindresorhus Is this rule acceptable?
Accepted
Should we exclude class modification pattern?
Foo.prototype.bar = function () {
this.baz()
}
Should we exclude class modification pattern?
I don't think modifying prototype manually in morden JavaScript is a good practice.
I don't think modifying prototype manually in morden JavaScript is a good practice.
What's the alternative? Subclass shouldn't be the same thing.
Also, should we allow this in object methods?
What's the alternative? Subclass shouldn't be the same thing.
I have no alternatives. Modifying an existing constructor's prototype seems unnecessary, except polyfills or intercepting/overriding something. Intercepting/Overriding something by modifying prototype is a little bit hacky. It breaks the open–closed principle.
Also, should we allow this in object methods?
I don't use it but I feel ok to allow it.
Should we allow this in the top-level scope?
Many umd modules and some special environments may not have window and global, and this is needed for detection
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define([], factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.MyModule = factory();
}
}(typeof self !== 'undefined' ? self : this, function () {
const MyModule = {
greet: function (name) {
return `Hello, ${name}!`;
},
add: function (a, b) {
return a + b;
}
};
return MyModule;
}));
Also, should we allow
thisin object methods?
It should be allowed, Vue2 options is this mode, otherwise there are many false positives
<script>
export default {
methods: {
foo () {
this.name = 'xxx'
}
}
}
</script>
Examples of false positives
new SDK({
appKey: 'xxx',
appId: 'xxx',
onReady: function () {
this.xxxxx
}
})
<script>
export default {
methods: {
refresh: debounce(async function () {
this.list = await getList()
}, 500)
}
}
</script>
Should we allow this in the top-level scope?
Personally no. Your umd example is not modern JS. 99% projects do not need this. People, who really need this, should turn off this rule.
It should be allowed, Vue2 options is this mode, otherwise there are many false positives
Vue2 is EOL.
Vue2 is EOL, But Vue's options mode is not.
And similar situations
export default defineComponent({
methods: {
mounted() {
this.xxxxxx //
}
}
})
Maybe we should wait for more feedback.