XMLHttpRequest
: Anpassung/Updates der vom Server gelieferten Seiten'use strict';
)
this
wird nicht an das gobale Object gebundeneval
arguments.caller
und arguments.callee
sind verbotenObject.create()
defineProperty()
, …keys()
, getOwnPropertyNames()
preventExtensions()
, seal()
, freeze()
, …Function.prototype.bind()
every
, filter
, forEach
, map
, …parse
und stringify
)'use strict';
npm
Paketmanagerlibuv
boolean, number, string, null, undefined, Symbol (ES6)
Array, Date, Error, Function, JSON, NaN, RegExp, ...
value, writable, enumerable, configurable
get, set, enumerable (for ... in), configurable
for ... in
ist definiert (siehe enumerable
)length
propertyarguments
Variable// creates the property x on the global object
x = 42
// creates the property y on the global object,
// and marks it as non-configurable
var y = 43
myobj = {
h: 4,
k: 5,
}
// Dot notation
myobj.h // 4
myobj.nothing // undefined
// Index notation
myobj["h"]
myobj["nothing"]
// x is a property of the global object and can be deleted
delete x // returns true
// y is not configurable, so it cannot be deleted
delete y // returns false
// delete doesn't affect certain predefined properties
delete Math.PI // returns false
// user-defined properties can be deleted
delete myobj.h // returns true
var fruits = ["Banana", "Orange", "Apple", "Mango"]
// convert to string
document.getElementById("demo").innerHTML = fruits.toString()
// # Banana,Orange,Apple,Mango
fruits.join(" * ")
// # Banana * Orange * Apple * Mango
// Changes the first element of fruits to "Kiwi"
fruits[0] = "Kiwi"
// The first parameter (2) defines
// the position where new elements should be spliced in.
// The second parameter (0) defines
// how many elements should be removed.
// The rest of the parameters ("Lemon" , "Kiwi") define
// the new elements to be added.
fruits.splice(2, 0, "Lemon", "Kiwi")
// # ["Kiwi", "Orange", "Lemon", "Kiwi", "Apple", "Mango"]
// Sorts the elements of fruits
fruits.sort()
// length of array
fruits.length
// File greetings.js
module.exports = {
sayHelloInEnglish: function() {
return "HELLO"
},
sayHelloInSpanish: function() {
return "Hola"
},
}
var greetings = require("./greetings.js")
Courtesy of JS Event Loop Explained.
Non-blocking IO, daher oft Callbacks
request('http://www.google.com',
function(error, response, body) {
console.log(body)
})
console.log('Done!')
Event Loop basiert
while(queue.waitForMessage()){
queue.processNextMessage()
}
setTimeout
postMessage
)pm2
und loopback
http://www.aaronstannard.com/intro-to-nodejs-for-net-developers/
Node’s true innovation is its evented + asynchronous I/O model.
Request URL:https://test.wroomer.com/v1/storage/filter/list
Request Method:GET
Status Code:200 OK
Remote Address:91.xxx.149.xxx:443
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Set-Cookie
Access-Control-Expose-Headers:Set-Cookie
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Connection:keep-alive
Content-Encoding:gzip
Content-Type:application/json;charset=UTF-8
Date:Thu, 15 Dec 2016 13:08:28 GMT
Expires:0
Pragma:no-cache
Server:nginx/1.6.2
Transfer-Encoding:chunked
Vary:Accept-Encoding
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-XSS-Protection:1; mode=block
{"number_of_filters_found":0,"stored_filters":[]}
Browserunterschiede werden mittels Polyfill ausgeglichen
A shim that mimics a future API providing fallback functionality to older browsers.
https://remysharp.com/2010/10/08/what-is-a-polyfill
The No-Nonsense Guide to HTML5 Fallbacks
https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills
Reduce LOC and improve clarity of your application logic with Lodash
http://colintoh.com/blog/lodash-10-javascript-utility-functions-stop-rewriting
let ownerArr = [{
"owner": "Colin",
"pets": [{"name":"dog1"}, {"name": "dog2"}],
}, {
"owner": "John",
"pets": [{"name":"dog3"}, {"name": "dog4"}],
}]
// Array's map method.
ownerArr.map(function(owner){
return owner.pets[0].name
})
// Lodash
_.map(ownerArr, 'pets[0].name')
let objA = {
"name": "colin"
}
// Normal method? Too long. See Stackoverflow for solution: http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript
// Lodash
let objB = _.cloneDeep(objA)
objB === objA // false
let objA = {"name": "colin", "car": "suzuki"}
let objB = {"name": "james", "age": 17}
let objC = {"pet": "dog"}
// Lodash
_.assign(objA, objB, objC)
// {"name": "james", "car": "suzuki", "age": 17, "pet": "dog"}
// Naive method: Remove an array of keys from object
Object.prototype.remove = function(arr) {
let that = this
arr.forEach(function(key){
delete(that[key])
})
}
let objA = {"name": "colin", "car": "suzuki", "age": 17}
objA.remove(['car', 'age'])
objA // {"name": "colin"}
// Lodash
objA = _.omit(objA, ['car', 'age']) // {"name": "colin"}
let objA = {"name": "colin", "car": "suzuki", "age": 17}
// Lodash
objA = _.omit(objA, 'car') // {"name": "colin", "age": 17}
objA = _.omit(objA, _.isNumber) // {"name": "colin"}
let myImage = document.querySelector('img')
fetch('flowers.jpg')
.then(function(response) {
return response.blob()
})
.then(function(myBlob) {
let objectURL = URL.createObjectURL(myBlob)
myImage.src = objectURL
})
Promise
s sind eine Alternative zur Callback Hölle// let and const
function f() {
{
let x
{
// okay, block scoped name
const x = "sneaky"
// error, const
x = "foo"
}
// error, already declared in block
let x = "inner"
}
}
// DESTRUCTION
// list matching
let [a, , b] = [1,2,3]
// object matching
let { op: a, lhs: { op: b }, rhs: c }
= getASTNode()
// object matching shorthand
// binds `op`, `lhs` and `rhs` in scope
let {op, lhs, rhs} = getASTNode()
// Can be used in parameter position
function g({name: x}) {
console.log(x)
}
g({name: 5})
// Fail-soft destructuring
let [a] = []
a === undefined
// Fail-soft destructuring with defaults
let [a = 1] = []
a === 1
// Default parameters
function f(x, y=12) {
// y is 12 if not passed (or passed as undefined)
return x + y
}
f(3) == 15
// Rest arguments
function f(x, ...y) {
// y is an Array
return x * y.length
}
f(3, "hello", true) == 6
// Spread operator
function f(x, y, z) {
return x + y + z
}
// Pass each elem of array as argument
f(...[1,2,3]) == 6
// String interpolation
let name = "Bob", time = "today"
`Hello ${name}, how are you ${time}?`
// Expression bodies
let odds = evens.map(v => v + 1)
let nums = evens.map((v, i) => v + i)
let pairs = evens.map(v => ({even: v, odd: v + 1}))
// Statement bodies
nums.forEach(v => {
if (v % 5 === 0)
fives.push(v)
})
// Lexical this
let bob = {
_name: "Bob",
_friends: [],
printFriends() {
this._friends.forEach(f =>
console.log(this._name + " knows " + f))
}
}
this
and function
function Person(age) {
this.age = age
this.growOld = function() {
this.age++
}
}
let person = new Person(1)
setTimeout(person.growOld,1000)
setTimeout(function() { console.log(person.age) },2000)
// 1, should have been 2
this
and function
setTimeout(person.growOld,1000)
führt growOld
im Kontext von window
auswindows.age === undefined
windows.age === NaN
(wegen undefined + 1
)growOld
als Arrow Funktionthis
(kein späterer Kontext)let obj = {
// __proto__
__proto__: theProtoObj,
// Shorthand for ‘handler: handler’
handler,
// Methods
toString() {
// Super calls
return "d " + super.toString()
},
// Computed (dynamic) property names
[ 'prop_' + (() => 42)() ]: 42
}
// Sets
let s = new Set()
s.add("hello").add("goodbye").add("hello")
s.size === 2
s.has("hello") === true
// Maps
let m = new Map()
m.set("hello", 42)
m.set(s, 34)
m.get(s) == 34
let fibonacci = {
[Symbol.iterator]() {
let pre = 0, cur = 1
return {
next() {
[pre, cur] = [cur, pre + cur]
return { done: false, value: cur }
}
}
}
}
for (let n of fibonacci) {
// truncate the sequence at 1000
if (n > 1000)
break;
console.log(n)
}
let fibonacci = {
[Symbol.iterator]: function*() {
let pre = 0, cur = 1
for (;;) {
let temp = pre
pre = cur
cur += temp
yield cur
}
}
}
for (let n of fibonacci) {
// truncate the sequence at 1000
if (n > 1000)
break
console.log(n)
}
let MyClass = (function() {
// module scoped symbol
let key = Symbol("key")
function MyClass(privateData) {
this[key] = privateData
}
MyClass.prototype = {
doStuff: function() {
... this[key] ...
}
}
return MyClass
})()
var c = new MyClass("hello")
// Keine Sichtbarkeit des Properties von außen
c["key"] === undefined
// Proxying a normal object
let target = {}
let handler = {
get: function (receiver, name) {
return `Hello, ${name}!`
}
}
let p = new Proxy(target, handler)
p.world === 'Hello, world!'
// Proxying a function object
let target = function () { return 'I am the target' }
let handler = {
apply: function (receiver, ...args) {
return 'I am the proxy'
}
}
let p = new Proxy(target, handler)
p() === 'I am the proxy'
class SkinnedMesh extends THREE.Mesh {
constructor(geometry, materials) {
super(geometry, materials)
this.idMatrix = SkinnedMesh.defaultMatrix()
this.bones = []
this.boneMatrices = []
//...
}
update(camera) {
//...
super.update()
}
get boneCount() {
return this.bones.length
}
set matrixType(matrixType) {
this.idMatrix = SkinnedMesh[matrixType]()
}
static defaultMatrix() {
return new THREE.Matrix4()
}
}
this
ist praktisch immer notwendigthis
// Pseudo-code of Array
class Array {
constructor(...args) { /* ... */ }
static [Symbol.create]() {
// Install special [[DefineOwnProperty]]
// to magically update 'length'
}
}
// User code of Array subclass
class MyArray extends Array {
constructor(...args) { super(...args) }
}
// Two-phase 'new':
// 1) Call @@create to allocate object
// 2) Invoke constructor on new instance
let arr = new MyArray()
arr[1] = 12
arr.length == 2
// Defining a module
// lib/math.js
export function sum(x, y) {
return x + y
}
export let pi = 3.141593
// Using a module
// app.js
import * as math from "lib/math"
alert("2π = " + math.sum(math.pi, math.pi))
// Another way to use the module
// otherApp.js
import {sum, pi} from "lib/math"
alert("2π = " + sum(pi, pi))
// lib/mathplusplus.js
export * from "lib/math"
export let e = 2.71828182846
export default function(x) {
return Math.log(x)
}
// app.js
import ln, {pi, e} from "lib/mathplusplus"
alert("2π = " + ln(e)*pi*2)
::
)any
let isDone: boolean = false
let decimal: number = 6
let hex: number = 0xf00d
let binary: number = 0b1010
let octal: number = 0o744
let color: string = "blue"
let list: number[] = [1, 2, 3]
// Declare a tuple type
let x: [string, number]
// Initialize it
x = ["hello", 10] // OK
// Initialize it incorrectly
x = [10, "hello"] // Error
console.log(x[0].substr(1)) // OK
console.log(x[1].substr(1))
// Error, 'number' does not have 'substr'
let notSure: any = 4
notSure = "maybe a string instead"
notSure = false // okay, definitely a boolean
let notSure: any = 4
notSure.ifItExists() // okay, ifItExists might exist at runtime
notSure.toFixed()
// okay, toFixed exists (but the compiler doesn't check)
let prettySure: Object = 4
prettySure.toFixed()
// Error: Property 'toFixed' doesn't exist on type 'Object'.
let list: any[] = [1, true, "free"]
list[1] = 100
function warnUser(): void {
alert("This is my warning message")
}
let unusable: void = undefined
// Not much else we can assign to these variables!
let u: undefined = undefined
let n: null = null
// Function returning never must have unreachable end point
function error(message: string): never {
throw new Error(message)
}
// Inferred return type is never
function fail() {
return error("Something failed")
}
// Function returning never must have unreachable end point
function infiniteLoop(): never {
while (true) {
}
}
let someValue: any = "this is a string"
let strLength: number = (someValue as string).length
interface SquareConfig {
color: string // required property
width?: number // optional property
}
function createSquare(config: SquareConfig): {color: string; area: number} {
let newSquare = {color: "white", area: 100}
if (config.color) {
newSquare.color = config.color
}
if (config.width) {
newSquare.area = config.width * config.width
}
return newSquare
}
let mySquare = createSquare({color: "black"})
function identity<T>(arg: T): T {
return arg
}
let output = identity("myString") // type of output will be 'string'
interface Lengthwise {
length: number
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length)
// Now we know it has a .length property, so no more error
return arg
}
function extend<T, U>(first: T, second: U): T & U {
let result = <T & U>{}
for (let id in first) {
(result as any)[id] = (<any>first)[id]
}
for (let id in second) {
if (!result.hasOwnProperty(id)) {
(result as any)[id] = (<any>second)[id]
}
}
return result
}
class Person {
constructor(public name: string) { }
}
interface Loggable {
log(): void
}
class ConsoleLogger implements Loggable {
log() {
// ...
}
}
let jim = extend(new Person("Jim"), new ConsoleLogger())
let n = jim.name
jim.log()
function padLeft(value: string, padding: string | number) {
if (typeof padding === "number") {
return Array(padding + 1).join(" ") + value
}
if (typeof padding === "string") {
return padding + value
}
throw new Error(`Expected string or number, got '${padding}'.`)
}
padLeft("Hello world", 4)
// returns " Hello world"
let indentedString = padLeft("Hello world", true)
// errors during compilation
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined
}
type Name = string
type NameResolver = () => string
type NameOrResolver = Name | NameResolver
function getName(n: NameOrResolver): Name {
if (typeof n === "string") {
return n
}
else {
return n()
}
}
https://basarat.gitbooks.io/typescript/content/docs/async-await.html
interface Foo {
doIt()
}
interface Foo {
doSomething()
doSomethingDifferent()
}
interface Foo {
doSomething()
doSomethingDifferent()
doIt()
}
declare let foo: number
declare function greet(greeting: string): void
declare namespace myLib {
function makeGreeting(s: string): string
let numberOfGreetings: number
}
declare
kann in *.d.ts Dateien weg gelassen werden (d.h. ist implizit)import MyImgJs from '../../Common/MyImg.js'
const MyImg: new() => any = MyImgJs
grunt
, gulp
: Low Level (~ant
)
'use strict';
)eslint
und tslint
React Native
React Router
Sonstiges
zone.js
: thread-local storageReact.createElement()
)const element: React.ReactNode = (
<h1 className="greeting">
Hello, world!
</h1>
)
const element: React.ReactNode = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
)
createElement
-> React Element// Note: this structure is simplified
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world'
}
}
const title: string = response.potentiallyMaliciousInput
// This is safe:
const element: React.ReactNode = <h1>{title}</h1>
// Inside a React Component ...
getGreeting(user) {
if (user) {
return <h1>Hello, {this.formatName(this.user)}!</h1>
}
return <img src={this.user.avatarUrl} />
}
formatName(user) {
return user.firstName + ' ' + user.lastName
}
const user = {
firstName: 'Harper',
lastName: 'Perez',
avatarUrl: 'http://...',
}
interface IWelcome {
name: string,
}
class Welcome extends React.Component<IWelcome, {}> {
render() {
return <h1>Hello, {this.props.name}</h1>
}
}
const element: React.ReactNode = <Welcome name="Sara" />
ReactDOM.render(
element,
document.getElementById('root')
)
const element: React.ReactNode = (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
)
ReactDOM.render(
element,
document.getElementById('root')
)
interface IClockComponentState {
date: Date,
}
class Clock extends React.Component<{}, IClockComponentState> {
timerID: number
constructor(props) {
super(props);
this.state = {date: new Date()}
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
)
}
componentWillUnmount() {
clearInterval(this.timerID)
}
tick() {
this.setState({date: new Date()})
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
)
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
)
constructor(props)
:
componentWillMount()
:
setState
möglichcomponentDidMount()
:
Actions
(und Store.listen
)render()
ncomponentWillReceiveProps(nextProps)
:
setState
möglichshouldComponentUpdate(nextProps, nextState): boolean
:
return true
forceUpdate
aufgerufencomponentWillUpdate(nextProps, nextState)
:
shouldComponentUpdate
true
zurück gabcomponentDidUpdate(prevProps, prevState)
:
shouldComponentUpdate
true
zurück gabcomponentWillUnmount()
:
Store.unlisten
, timer)setState(nextState, callback?)
:
setState
benutzencomponentDidUpdate
)shouldComponentUpdate
render
n ausforceUpdate()
:
render
nshouldComponentUpdate
aufrender
ausgelöstrender
auch verwendet werden
(Ansonsten reicht eine Instanzvariable)setState
ändernsetState
interface INameFormState {
value: string,
}
class NameForm extends React.Component<{}, INameFormState> {
constructor(props) {
super(props)
this.state = {value: ''}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
this.setState({value: event.target.value})
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value)
event.preventDefault()
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
)
}
}
bind
benötigt wird
Courtesy of Fluxxor - What is Flux?.
Courtesy of Fluxxor - What is Flux?.
Courtesy of Fluxxor - What is Flux?.
Courtesy of Fluxxor - What is Flux?.