XMLHttpRequest: Anpassung/Updates der vom Server gelieferten Seiten'use strict';)
this wird nicht an das gobale Object gebundenevalarguments.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 Paketmanagerlibuvboolean, number, string, null, undefined, Symbol (ES6)Array, Date, Error, Function, JSON, NaN, RegExp, ...value, writable, enumerable, configurableget, set, enumerable (for ... in), configurablefor ... 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()
}
setTimeoutpostMessage)pm2 und loopbackhttp://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:443Access-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 // falselet 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
})Promises 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 functionfunction 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 2this and functionsetTimeout(person.growOld,1000) führt growOld im Kontext von window auswindows.age === undefinedwindows.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) == 34let 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)::)anylet 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] = 100function 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).lengthinterface 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 compilationfunction 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 = MyImgJsgrunt, gulp: Low Level (~ant)
'use strict';)eslint und tslintReact 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 trueforceUpdate aufgerufencomponentWillUpdate(nextProps, nextState):
shouldComponentUpdate true zurück gabcomponentDidUpdate(prevProps, prevState):
shouldComponentUpdate true zurück gabcomponentWillUnmount():
Store.unlisten, timer)setState(nextState, callback?):
setState benutzencomponentDidUpdate)shouldComponentUpdaterendern ausforceUpdate():
rendernshouldComponentUpdate aufrender ausgelöstrender auch verwendet werden
(Ansonsten reicht eine Instanzvariable)setState ändernsetStateinterface 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?.