The Good - The Bad - The Ugly
true> [] + []
''
> [] + {}
'[object Object]'
> {} + []
0> alert.call.call.call.call.call.apply(function (a) {return a}, [1,2])2> true === 1false> true + true === 2> 999999999999999910000000000000000> 0.1 + 0.2 === 0.3false> '2' + 1'21'> '2' - 11> 0 === -0true1/0 === 1/-0falsetrue1/0 === Infinityfalse> NaN == NaNfalse> isNaN(NaN)> isNaN("foo")true> Number.isNaN(NaN)true> Number.isNaN("foo")false> NaN !== NaNtrue> parseInt(NaN, 24)13511> parseInt("20foo")20> NaN === NaNtrue1 / -0 === -Infinitytrue> +"20foo"NaNfalse> typeof Infinityfalse> Number.MIN_VALUE5e-324> Math.max() > Math.min()> Math.max()-Infinity> Math.min()Infinity> [10, 9, 8, 3, 2, 1, 0].sort()[0, 1, 10, 2, 3, 8, 9]> Number.MIN_VALUE < 0Number> typeof NaNNumber> (![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]'fail'> [,,,].length3> Number()0> Number(undefined)NaN> <!-- valid comment toofalse> 1 < 2 < 3true> typeof 'foo''string'> 'foo' instanceof String> new String('foo') == 'foo'true> typeof new String('foo')> 3 > 2 >= 1true> 3 > 2 > 1false'object'> f = () => 10; f()10> f = () => {}; f()undefinedvar x = {
foo() {
return this;
},
};
var y = x.foo;
x.foo();
y();function foo() {
return this;
}
foo.call(console);
foo.call(undefined);
foo.bind(foo)();var foo = {
number: 1,
foo() {
return this.number;
}
};
var bar = {
number: 23;
};
var x = foo.foo;
foo.foo();
x();
x.call(bar);
Declarations
var foo = 1;
{
var foo = 2;
}
console.log(foo);
// 2var foo = 1;
{
let foo = 2;
}
console.log(foo);
// 1var foo = 1; // this is const, do not change!
function evil() {
foo = 2;
}
evil();
console.log(foo);
// 2const foo = 1; // this is const, do not change!
function evil() {
foo = 2;
}
evil(); // TypeError, Assignment to constant variable.
console.log(foo);const foo = { a: 1 };
foo.a = 2;
console.log(foo.a);
// 2var foo = 1;
var foo = 2;let foo = 1;
const foo = 2; // Throws, foo already declaredvar foo = {
bar: 1,
batz: 2
};
var bar = foo.bar;const foo = {
bar: 1,
batz: 2,
};
const { bar } = foo;var a = [1, 2, 3]
var b = a[0];
var c = a[2];const a = [1, 2, 3];
const [b, , c] = a;function foo(a) {
if (a === undefined) {
a = 1;
}
}var a = 1;
var b = 2;
// Swap
var c = a;
a = b;
b = c;const a = 1;
const b = 2;
// Swap
[a, b] = [b, a]function foo(a = 1) {
}function foo(a = { a: 1, b: 2 }) {}
function bar({ a = 1, b = 2 }) {}
function bar({ a = 1, b = 2 } = {}) {}
function foo() {
var a = arguments; // EVIL!
}function foo(...a) {
}function foo(a, b, ...c) {
}var a = [1, 2, 3];
var b = [2, 4, 6];
var c = a.concat(b);const a = [1, 2, 3];
const b = [2, 4, 6];
const c = [...a, ...b];console.log.apply(console.log, ...[1, 2, 3]);
console.log.call(console.log, 1, 2, 3);
function foo(...a, b, ...c) { // NOPE
}function() {
return 1;
}() => 1function() {
return { a: 1 };
}function(a) {
return a;
}var self = this;
function() {
return self.foo;
}() => this.foo;a => a() => ({ a: 1 });var x = 'foo\nbar';const x = `foo
bar`;var a = 'foo' + 1 + 'bar';const a = `foo ${1} bar`;var x = {
foo: function() {},
bar: bar,
};
x['batz'] = 123;const x = {
foo() {},
bar,
['batz']: 123,
};
class Foo extends Bar {
static foo = 123; // ESNext (Stage 3)
foo = 123; // ESNext (Stage 3)
constructor() {
super();
}
static bar() {
}
bar() {
super.bar();
}
}
new Foo().bar();
Foo.foo;function later () {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("yay"), 1500)
})
}
function muchLater () {
return later().then(later)
}
const p = later()
p
.then(x => x.y.z)
.catch(err => console.error(err))
.then(muchLater)
.then(x => console.log(x))
.then(x => console.log(x))
const p2 = p.then(later)
p2.then(x => console.log(x))
p2.then(x => x.y.z)
.catch(err => console.error(err))
.then(x => fetch("http://google.com"))function* generator() {
yield 'f'
yield 'o'
yield 'o'
}const foo = generator();
for (let bar of foo) {
console.log(bar)
}
// 'f'
// 'o'
// 'o'[...foo()]
// ['f', 'o', 'o']function* genGenerator() {
yield* 'foo';
}
[...genGenerator()];
// ['f', 'o', 'o']function* generator() {
yield 1;
console.log(1);
yield 2;
console.log(2);
yield 3;
console.log(3);
}function* generator() {
yield 1;
yield 2;
return 3;
yield 4;
}
// [...generator()]
// [1, 2]function a() {
return Promise.resolve()
.then(() => 1);
}async function a() {
await Promise.resolve();
return 1;
}function b() {
return a()
.then(n => n + 1);
}async function b() {
const n = await a();
return n + 1;
}let a = (() => {
var ref = _asyncToGenerator(function* () {
yield Promise.resolve();
return 1;
});
return function a() {
return ref.apply(this, arguments);
};
})();
let b = (() => {
var ref = _asyncToGenerator(function* () {
const n = yield a();
return n + 1;
});
return function b() {
return ref.apply(this, arguments);
};
})();Map
WeakMap
Set
WeakSet
const symbol = Symbol();
const descriptiveSymbol = Symbol('foo');
symbol !== Symbol();
descriptiveSymbol !== Symbol('foo');const S1 = Symbol.for('foo');
const S2 = Symbol.for('foo');
S1 === S2const foo = {
[Symbol()]: 'foo',
[Symbol('foo')]: 'bar',
[Symbol.for('bar')]: 'baz',
what: 'ever'
};console.log(Object.keys(foo))
// <- ['what']
console.log(JSON.stringify(foo))
// <- {"what":"ever"}
for (let key in foo) {
console.log(key)
// <- 'what'
}
console.log(Object.getOwnPropertyNames(foo))
// <- ['what']
console.log(Object.getOwnPropertySymbols(foo))
// <- [Symbol(), Symbol('foo'), Symbol.for('bar')]module.exports = {
'extends': 'marudor',
'env': {
'browser': true,
},
'globals': {
},
'rules': {
'quote-props': 1,
'no-console': 0,
'no-unused-expressions': 1,
'class-property/class-property-semicolon': 2,
'generator-star-spacing': 0,
},
'plugins': [
'class-property',
],
};
| Babel | |
| Closure | |
| Traceur | |
| Typescript | Microsoft |
{
"presets": ["es2015"]
}{
"presets": [["env", {
"targets": {
"chrome": 43,
"firefox": 42,
"safari": 9,
"opera": 30,
"edge": 12,
"iOS": 9
},
"useBuiltIns": true, "loose": true
}], "stage-2", "react"
],
"plugins": [
"transform-decorators-legacy"
],
"env": {
"development": {
"plugins": [
"transform-react-jsx-source",
"flow-react-proptypes",
"transform-dev-warning"
]
},
"production": {
"plugins": [
"transform-react-constant-elements"
]
}
}
}
class Foo extends Bar {
static foo = 123; // ESNext
foo = 123; // ESNext
constructor() {
super();
}
static bar() {
}
bar() {
super.bar();
}
}
new Foo().bar();
Foo.foo;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 Foo = function (_Bar) {
_inherits(Foo, _Bar);
// ESNext
function Foo() {
_classCallCheck(this, Foo);
var _this = _possibleConstructorReturn(this, _Bar.call(this));
_this.foo = 123;
return _this;
} // ESNext
Foo.bar = function bar() {};
Foo.prototype.bar = function bar() {
_Bar.prototype.bar.call(this);
};
return Foo;
}(Bar);
Foo.foo = 123;
new Foo().bar();
Foo.foo;var a = require('./a');
a.foo();
var b = require('./b');
b();import { a } from './a';
import andererName from './b';
a();
andererName();module.exports = {
a: function() {
return 'Ich bin a';
}
};module.exports = function() {
return 'Ich bin b';
}a.js
b.js
export function a() {
return 'Ich bin a';
}export default function() {
return 'Ich bin b';
}
Standard existiert, Node bleibt bei CommonJS (vorerst)
Browser -> Bundler
Node -> Babel
var foo = { a: 1, b: 2, c: 3 };
var a = foo.a;
var r = { b: foo.b, c: foo.c };const foo = { a: 1, b: 2, c: 3 };
const { a, ...r } = foo;
class Cat {
@readonly
meow() {
return 'meow';
}
}const dog = new Cat();
dog.meow = () => 'wuff'; // Exception: readonlyfunction readonly(target, key, descriptor) {
descriptor.writable = false;
return descriptor;
}@Cat / @Cat('mau')
class Animal {
}const cat = new Animal();
cat.meow();
// meowfunction Cat(target) {
return class Cat extends target {
meow() {
console.log('meow');
}
}
}function Cat(fnName) {
return function(target) {
return class Cat extends target {
[fnName]() {
console.log('meow');
}
}
}
}
function square(a) {
return a * a;
}
square(3);
square('3');// @flow
function square(a) {
return a * a;
}
square(3);
square('3');
function square(a: any): number {
return a * a;
}
square(3);
square('3');// @flow
function square(a: number | string): number {
return a * a; // Error
}
square(3);
square('3');
function square(a: number): number {
return a * a;
}
square(3);
square('3'); // Error// @flow
function square(a: number): number { // Error
return a * a;
}
square(3);
square('3'); // Error
function square(a) {
if (Array.isArray(a)) {
return a.map(square);
}
return a * a;
}
square(3);
square([3, 4, 5]);
square([3, '4', 5]);
square('3');
square(square(3));// @flow
function square(a) {
if (Array.isArray(a)) {
return a.map(square);
}
return a * a;
}
square(3);
square([3, 4, 5]);
square([3, '4', 5]);
square('3');
square(square(3));
function square(a: any): any {
if (Array.isArray(a)) {
return a.map(square);
}
return a * a;
}
square(3);
square([3, 4, 5]);
square([3, '4', 5]);
square('3');
square(square(3));// @flow
function square(a: number | string | Array<number|string>): number | number[] {
if (Array.isArray(a)) {
return a.map(square);
}
return a * a; // Error
}
square(3);
square([3, 4, 5]);
square([3, '4', 5]);
square('3');
square(square(3));
function square(a: number | number[]): number | number[] {
if (Array.isArray(a)) {
return a.map(square); // Err
}
return a * a; // Err
}
square(3);
square([3, 4, 5]);
square([3, '4', 5]); // Error
square('3'); // Error
square(square(3));// @flow
function square(a: number | number[]): number | number[] {
if (Array.isArray(a)) {
return a.map(square); // Err
}
return a * a;
}
square(3);
square([3, 4, 5]);
square([3, '4', 5]); // Error
square('3'); // Error
square(square(3));// @flow
function square(a: number | string | [number, number | string, number]): number | number[] {
if (Array.isArray(a)) {
return a.map(square);
}
return a * a; // Error
}
square(3);
square([3, 4, 5]);
square([3, '4', 5]);
square('3');
square(square(3));
function square(a: number): number {
return a * a;
}
function arrSquare(a: number | number[]): number | number[] {
if (Array.isArray(a)) {
return a.map(square);
}
return square(a);
}
arrSquare(3);
arrSquare([3, 4, 5]);
arrSquare([3, '4', 5]); // Error
arrSquare('3'); // Error
arrSquare(arrSquare(3));// @flow
function square(a: number): number {
return a * a;
}
function arrSquare(a: number | number[]): number | number[] {
if (Array.isArray(a)) {
return a.map(square);
}
return square(a);
}
arrSquare(3);
arrSquare([3, 4, 5]);
arrSquare([3, '4', 5]); // Error
arrSquare('3'); // Error
arrSquare(arrSquare(3));interface Foo {
a: number,
b: number,
c?: number
}type Foo = {
a: number,
b: ?number,
c?: number,
}const a: Foo = {
a: 1,
b: undefined,
c: null
};const a: Foo = {
a: 1,
b: undefined,
c: null // Error
};const a: Foo = {
a: 1,
b: undefined,
};const a: Foo = {
a: 1,
b: undefined,
};const a: Foo = {
a: 1,
b: '2', // Error
c: 42
};const a: Foo = {
a: 1,
b: '2', // Error
c: 42
};http://definitelytyped.org/
https://github.com/flowtype/flow-typed
[ignore]
[include]
src/
[libs]
[options]
esproposal.decorators=ignore
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable
unsafe.enable_getters_and_setters=true
experimental.const_params=true
munge_underscores=true
module.system=haste
module.ignore_non_literal_requires=true