公司前端最近开始强推ESlint,很多文件需要逐步修改为符合ESlint规则的形式。
结果遇到了一个神奇的问题,有一段类似这样的代码:
let obj = {
init: function($el) { // 此处ESlint检查提示‘Expect method shorthand.(Object-shorthand)’
this.$el = $el;
}
};
obj.init.prototype = {
log() { console.log(this); }
};
new obj.init('o');
因为eslintrc中Object-shorthand
规则的设置,这种类内的函数成员要缩写成ES6 的Method方式,也就是下面这样:
let obj = {
init($el) { // 修改为Method形式,通过了ESlint检查
this.$el = $el;
}
};
obj.init.prototype = {
log() { console.log(this); }
};
new obj.init('o'); // TypeError: obj.init is not a constructor
这就让人郁闷了,这都能报错,这两种写法不是等价么?接着进行了一些对比:
let obj = {
init: function($el) {
this.$el = $el;
}
};
console.log(Object.getOwnPropertyNames(obj.init));// [ 'length', 'name', 'arguments', 'caller', 'prototype' ]
console.log(obj.init.prototype);// { log: [Function: log] }
obj.init.prototype = {
log() { console.log(this); }
};
console.log(Object.getOwnPropertyNames(obj.init));// [ 'length', 'name', 'arguments', 'caller', 'prototype' ]
console.log(obj.init.prototype);// { log: [Function: log] }
new obj.init('o').log(); // { '$el': 'o' }
let obj = {
init($el) {
this.$el = $el;
}
};
console.log(Object.getOwnPropertyNames(obj.init));// [ 'length', 'name' ]
console.log(obj.init.prototype);// undefined
obj.init.prototype = {
log() { console.log(this); }
};
console.log(Object.getOwnPropertyNames(obj.init));// [ 'length', 'name', 'prototype' ]
console.log(obj.init.prototype);// { log: [Function: log] }
new obj.init('o').log();// TypeError: obj.init is not a constructor
对比结果成功颠覆了我一直以来的认知。ES6的Method竟然和一般的函数不一样,不能作为构造函数来使用。
后来在https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions此处找到了下面这一段: