var apples = 5;
if (true) {
var apples = 10;
console.log(apples); // 10
}
console.log(apples); // 10
let apples = 5;
if (true) {
let apples = 10;
console.log(apples); // 10
}
console.log(apples); // 5
console.log(a); // undefined
var a = 5;
alert(a); // Uncaught SyntaxError: ...
let a = 5;
const LANGUAGE = 'DE';
LANGUAGE = 'EN';
// Uncaught TypeError: Identifier 'LANGUAGE' has already been declared(…)
let apples = 2;
let oranges = 3;
const template = `
${apples} + ${oranges} = ${apples + oranges}
`;
function myDirective() {
return {
template,
controller: DirectiveController,
controllerAs: 'ctrl',
restrict: 'E',
bindToController: true,
scope: {}
};
}
npm install --save angular angular-ui-router
/*@ngInject*/
function routes($stateProvider) {
// state definitions here
}
export default angular.module('app.routes')
.config(routes);
const configObject = {baseUrl: 'http://some-url.com'};
export default angular.module('app.config')
.value(configObject);
import angular from 'angular';
import angularUiRouter from 'angular-ui-router';
import routes from './routes';
import config from './config';
export default angular.module('app', [
angularUiRouter,
config.name,
routes.name
]);
export let one = 1;
export let two = 2;
export let three = 3;
import {one, two as numberTwo} from "./numbers";
console.log(`${one} and ${numberTwo}`); // prints '1 and 2'
import * as numbers from "./numbers";
console.log(`${numbers.one} and ${numbers.two}`); // prints '1 and 2'
class MyController {
/* @ngInject */
constructor(userService) {
this.fullName = userService.getFullName();
}
}
export MyController;
angular.module('app').controller('MyController', MyController);
import { MyController } from './MyController';
angular.module('app', []).controller('MyController', MyController);
// or use this controller as directive controller somewhere
angular.module('app').directive('MyDirective', function() {
return {
controller: MyController,
controllerAs: 'vm',
...
};
});
class UserService {
/* @ngInject */
constructor($http) {
this.$http = $http;
this.firstName = 'John';
this.lastName = 'Doe';
}
// getter
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
// setter
set fullName(newValue) {
[this.firstName, this.lastName] = newValue.split(' ');
}
}
class MyService extends BaseService {
constructor(initialData) {
super(initialData);
//...
}
updateData() {
//...
super.update();
}
static defaultData() {
// usable by calling MyService.defaultData()
return 'no data available';
}
}
class UserService {
/* @ngInject */
constructor($http) {
this.$http = $http;
this.users = [];
}
fetchUsers() {
return this.$http
.get('http://super-cool-api.com/users')
.then(response => {
// arrows share the same lexical this
//as their surrounding code
this.users = response.data.users;
});
}
}
let arr = ['John', 'Doe'];
let [firstName, lastName, country = 'Germany'] = arr;
console.log(firstName); // John
console.log(lastName); // Doe
console.log(country); // Germany
let arr = [1, 2, 3, 4];
[a, ...rest] = arr;
console.log(a); // 1
console.log(rest); // [2, 3, 4]
let obj = {
firstName: 'John',
lastName: 'Doe'
};
const {firstName, lastName, country = 'Germany'} = obj;
console.log(firstName); // John
console.log(lastName); // Doe
console.log(country); // Germany
angular.directive('myDirective', function () {
return {
controller: myController,
require: ['ngModel', 'other'],
link: function(scope, element, attrs, controllers) {
// destructuring in action
const [ngModelCtrl, otherCtrl] = controllers;
// ..
}
};
});
angular.directive('myDirective', function () {
return {
controller: myController,
require: ['ngModel', 'other'],
// perform destructuring in function declaration
link: function(scope, element, attrs, [ngModelCtrl, otherCtrl]) {
//..
}
};
});
We now have official API for promises :)
function timeout() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('some value'), 2000);
});
}
timeout().then((value) => console.log(value));
Angular 1.3 introduces $q API similar to official spec
function myFunctionThatReturnsAPromise() {
return $q(function (resolve, reject) {
anAsyncFunction(function (success) {
resolve(success);
}, function (error) {
reject(error);
});
});
}
myFunctionThatReturnsAPromise().then(resolveFn, rejectFn);
// Map is a collection for storing values with arbitrary keys
var map = new Map();
map.set(2, 'value1');
map.set(true, 'value2');
// keys could be objects as well
console.log(map.get("2")); // value1
console.log(map.get(true)); // value2
// Set is a collection for storing unique values
var set = new Set();
set.add('value1').add('value2').add('value1');
assert(set.size === 2);
assert(set.has('value2') === true);
// Map / Set additionally have iteration methods - keys(), values(), forEach()
Same as Map / Set, but leak-free. Allows the garbage collector to delete its elements. If some object is stored only in WeakMap / WeakSet, then it's deleted from memory.
let users = [
{name: 'Peter'},
{name: 'John'},
{name: 'Kate'}
];
let weakMap = new WeakMap();
weakMap.set(users[0], 'some info 1');
weakMap.set(users[1], 'some info 2');
weakMap.set(users[2], 'some info 3');
users.splice(0, 1); // we deleted 'Peter' from users
console.log(weakMap.get(users[0])); // this is now 'some info 2'
Could be considered as private class variables. Additional benefit is memory management for free.
var _state = new WeakMap();
var _accountService = new WeakMap();
class SigninController {
constructor($state, accountService) {
_state.set(this, $state);
_accountService.set(this, accountService);
}
login() {
_accountService.get(this).login().then(()=> {
_state.get(this).go('somewhere');
});
};
}
function* generateSequence() {
yield 1;
yield 2;
return 3;
}
let generator = generateSequence();
console.log(generator.next()); // Object {value: 1, done: false}
console.log(generator.next()); // Object {value: 2, done: false}
console.log(generator.next()); // Object {value: 3, done: true}
let $http = require('request-promise-json');
let co = require('co');
function *bitcoinRate() {
let r = yield $http.get('http://api.bitcoinaverage.com/ticker/USD');
// next line won't be executed until HTTP request is completed
console.log('1 Bitcoin == ' + r.last + ' USD');
}
co(bitcoinRate);
var co = require('co');
var cats = require('./cats.json');
var EC = protractor.ExpectedConditions;
beforeEach(co.wrap(function* () {
yield http.put(DB_URL + '.json', cats);
yield browser.get('/index.html');
// wait for the for the model to be loaded (for the cats to be ready)
var mainElement = element(by.className('topcat-container'));
yield browser.wait(EC.presenceOf(mainElement));
yield browser.wait(function () {
return mainElement.evaluate('vm.ready');
});
}));
async function doAsyncOp () {
var val = await asynchronousOperation();
// this line will be executed only after previous one is completed
return val;
};
async function main() {
var val = await doAsyncOp();
// this line will be executed only after previous one is completed
console.log(val);
}
main();
If you return Promise from function then it could be used in await block.
async function doRequest() {
var value = await $http('http://awesome-website.com/api');
console.log(`Wow, we have this value - ${value}`);
}
function doRequest(number) {
return new Promise((resolve, reject) => {
doSomeAsyncOperation(number).then((value) => resolve(value));
});
}
it('should check that everything is ok', async () => {
let response = await doRequest(1000);
expect(variable).toEqual(response);
});
class MyService() {
myProp = 12;
static myStaticProp = 34;
constructor() {
console.log(this.myProp); // Prints '12'
console.log(MyService.myStaticProp); // Prints '34'
}
}
“Decorators make it possible to annotate and modify classes and properties at design time.”https://github.com/wycats/javascript-decorators
Decorators could be used for a lot of fancy stuff including reducing amount of boilerplate code.
@Inject('$http', 'UserService')
class Account {
constructor($http, UserService) {
this.$http = $http;
this.UserService = UserService;
}
}
function Inject(...dependencies) {
return function decorator(target, key, descriptor) {
// target is our class constructor
target.$inject = dependencies;
};
}
import {bootstrap, Component, FORM_DIRECTIVES} from 'angular2/angular2';
class Hero {
id: number;
name: string;
}
@Component({
selector: 'my-app',
template:`.. some template ..`
})
class AppComponent {
public title = 'Tour of Heroes';
public hero: Hero = {
id: 1,
name: 'Windstorm'
};
}
bootstrap(AppComponent);
- http://kangax.github.io/compat-table/es6/
- http://kangax.github.io/compat-table/es7/
- https://babeljs.io/docs/learn-es2015/
- http://habrahabr.ru/post/257305/
- http://www.michaelbromley.co.uk/blog/350/exploring-es6-classes-in-angularjs-1-x
- http://blog.thoughtram.io/angularjs/es6/2015/...html
- https://gist.github.com/stryju/545c67519dbf89014686
- http://martinmicunda.com/2015/07/13/how-to-use-ES2016-decorators-to-avoid-angular-1x-boilerplate-code/
- http://martinmicunda.com/2015/10/19/how-to-start-writing-unit-tests-with-es6-angular-1x-and-jspm/
- https://medium.com/@tomastrajan/proper-testing-of-angular-js-applications-with-es6-modules-8cf31113873f
- http://www.sitepoint.com/simplifying-asynchronous-coding-es7-async-functions/
- https://github.com/ngUpgraders/ng-forward
- https://github.com/MikeRyan52/angular-decorators
- https://github.com/wycats/javascript-decorators
- https://github.com/jeffmo/es-class-static-properties-and-fields