왜 instanceof가 babel-node 아래에있는 Error 서브 클래스의 인스턴스에서 작동하지 않습니까?
OS X 에서 babel-node 버전 6.1.18 / Node 버전 5.1.0에서 실행할 때 instanceof연산자가 Error하위 클래스의 인스턴스에서 작동하지 않는 것으로 나타 났습니다. 왜 그런가요? 동일한 코드가 브라우저에서 잘 작동합니다 . 내 바이올린 을 예로 들어보십시오.
다음 코드 true는 브라우저에 출력 되는 반면 babel-node에서는 false입니다.
class Sub extends Error {
}
let s = new Sub()
console.log(`The variable 's' is an instance of Sub: ${s instanceof Sub}`)
난 단지 이후 인해 바벨 노드 버그이 존재를 상상할 수있는 instanceof것보다 다른 기본 클래스에 대한 작품 Error.
.babelrc
{
"presets": ["es2015"]
}
컴파일 된 출력
이것은 babel 6.1.18에 의해 컴파일 된 JavaScript입니다 :
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Sub = (function (_Error) {
_inherits(Sub, _Error);
function Sub() {
_classCallCheck(this, Sub);
return _possibleConstructorReturn(this, Object.getPrototypeOf(Sub).apply(this, arguments));
}
return Sub;
})(Error);
var s = new Sub();
console.log('The variable \'s\' is an instance of Sub: ' + (s instanceof Sub));
tl; dr Babel 6을 사용하는 경우 https://www.npmjs.com/package/babel-plugin-transform-builtin-extend 를 사용할 수 있습니다.
유형이 좋아 내장 확장 Array과 Error등이 바벨에서 지원 된 적이있다. 실제 ES6 환경에서 완벽하게 유효하지만 이전 브라우저와 호환되는 방식으로 트랜스 파일하기 매우 어려운 작업을 수행하기위한 요구 사항이 있습니다. Babel 5에서는 오류가 발생하지 않았지만 확장 된 하위 클래스에서 인스턴스화 된 객체가 예상대로 작동하지 않았다는 점에서 "작동"했습니다. 예를 들면 다음과 같습니다.
class MyError extends Error {}
var e1 = new MyError();
var e2 = new Error();
console.log('e1', 'stack' in e1);
console.log('e2', 'stack' in e2);
결과
e1 false
e2 true
오류가 발생하지는 않았지만 하위 클래스는 오류가 예상되는 것처럼 '스택'을 제대로 얻지 못합니다. 마찬가지로 확장 Array하면 배열처럼 동작하고 배열 메서드가있을 수 있지만 완전히 배열처럼 동작하지는 않습니다.
Babel 5 문서에서는 특히이를 인식해야 할 클래스의 가장자리 사례로 언급했습니다.
In Babel 6, classes were changed to be more spec-compliant in how subclassing is handled, and a side-effect of that is that now the above code will still not work, but it will not work in a different way than before. This has been covered in https://phabricator.babeljs.io/T3083, but I'll elaborate here on a potential solution.
To return Babel 5 subclassing behavior (which remember, is still not right or recommended), you can wrap the builtin constructor in your own temporary class, e.g.
function ExtendableBuiltin(cls){
function ExtendableBuiltin(){
cls.apply(this, arguments);
}
ExtendableBuiltin.prototype = Object.create(cls.prototype);
Object.setPrototypeOf(ExtendableBuiltin, cls);
return ExtendableBuiltin;
}
With this helper, rather than doing
class MyError extends Error {}
do
class MyError extends ExtendableBuiltin(Error) {}
In your specific case however, you have said that you are on Node 5.x. Node 5 has support for native ES6 classes without transpiling. I'd recommend you use those by dropping the es2015 preset and instead using node5 so you get native classes, among other things. In that context,
class MyError extends Error {}
will work the way you expect.
For people not on Node 4/5, or recent Chrome only, you may want to consider using something like https://www.npmjs.com/package/error. You can also explore https://www.npmjs.com/package/babel-plugin-transform-builtin-extend. The approximate option from that is the same behavior from Babel 5. Beware that the non-approximate behavior is definitely edge-casey and may not work in 100% of cases.
'IT TIP' 카테고리의 다른 글
| 어레이가 동일하게 유지 될 확률은 얼마입니까? (0) | 2020.10.24 |
|---|---|
| -D 매개 변수 또는 환경 변수를 Spark 작업에 전달하는 방법은 무엇입니까? (0) | 2020.10.24 |
| Docker : 마운트가 거부되었습니다. (0) | 2020.10.24 |
| Netbeans 프로젝트를 Maven 지원 프로젝트로 변환 (0) | 2020.10.24 |
| {before _,} {install, script} .travis.yml 옵션의 차이점은 무엇입니까? (0) | 2020.10.24 |