JavaScript手册1

作为后端开发,工作中也经常需要开发后台页面,而无论是使用哪种Web前端框架都是要使用JavaScript开发的。这门语言经过多年的发展,不仅出现了ES2015这样的现代JavaScript标准,也出现了TypeScript这样的具有类型系统且可编译为JavaScript代码的语言。

之前写js代码基本就是参考着已有代码写,或者遇到不会的Google一下,这个月每天花二十分钟在excuteprogram上学习了js相关的4个课程(JavaScript Array、Modern JavaScript、TypeScript、Regex),都是基本的语法,好处是可以边学边练印象更深刻了。这里把常用的一些语法记录下备查。

JavaScript Array

BASICS

1
2
3
4
5
6
> a.length
array length
> a[i]
get index i
> a[i] = x
store x at index i

STACK

1
2
3
4
> a.push(x)
append x to array a
> a.pop()
remove last element of a

FOR EACH

1
2
> a.forEach(f)
call f on each element

SLICE

1
2
3
4
5
6
> [10,20,30].slice(1)
[20, 30]
> [10,20,30].slice(1, 2)
[20]
> a.slice()
copy array

MAP

1
2
> a.map(f)
[f(a[0]), f(a[1]), ...]

SLICE WITH NEGATIVE ARGUMENTS

1
2
3
4
> [10, 20, 30, 40, 50].slice(-2)
[40, 50]
> [10, 20, 30].slice(-3, -1)
[10, 20]

JOIN

1
2
3
4
5
6
> [1, 2].join()
'1,2'
> [1, 2].join('')
'12'
> [1, 2].join('_')
'1_2'

CONCAT

1
2
> a1.concat(a2)
combine two arrays

INCLUDES

1
2
3
4
> [10, 20].includes(10)
true
> [10, 20].includes(30)
false

REDUCE

1
2
> [1,2].reduce((sum, x) => sum + x)
3

INDEX OF

1
2
> [10,20].indexOf(20)
1

NEW AND FILL

1
2
3
4
5
6
> new Array(2).length
2
> new Array(2)[0]
undefined
> new Array(2).fill('a')
['a', 'a']

FILTER

1
2
3
4
> [1, 2].filter(x => x > 1)
[2]
> [1, 2].filter(x => x < 3)
[1, 2]

SORT

1
2
3
4
5
6
> ['a', 'b'].sort()
['a', 'b']
> [10, 2].sort()
[10, 2]
> [10, 2].sort((x, y) => x - y)
[2, 10]

FIND INDEX

1
2
> [5, 6].findIndex(x => x === 6)
1

SOME AND EVERY

1
2
3
4
> [10, 20].some(x => x > 10)
true
> [10, 20].every(x => x > 10)
false

SHIFT

1
2
3
4
> a.shift()
remove element 0
> a.unshift(x)
insert at element 0

FIND

1
2
3
4
> [10, 20].find(x => x > 10)
20
> [10, 20].find(x => x < 0)
undefined

REVERSE

1
2
> [1, 2].reverse()
[2, 1]

REDUCE RIGHT

1
2
> ['a','b'].reduceRight((a,x)=>a+x)
'ba'

EMPTY SLOTS

1
2
3
4
5
6
> new Array(1)[0]
undefined
> 0 in ['something']
true
> 0 in new Array(1)
false

FLAT AND FLATMAP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> [
[1, 2],
[3, 4]
].flat()
[1, 2, 3, 4]
> [
[1, 2],
[
3,
[4]
]
].flat(1)
[1, 2, 3, [4]]
> [
{numbers: [1, 2]},
{numbers: [3, 4]},
].flatMap(obj => obj.numbers)
[1, 2, 3, 4]

Modern JavaScript

Modern JavaScript features, from ES5 (released in 2009) through ES2017

STRICT MODE

1
2
3
4
5
6
> function defineX() {
x = 1
return 'ok'
}
defineX()
ReferenceError: x is not defined

LET

1
2
3
4
5
> if (true) {
let x = 1
}
x
ReferenceError: x is not defined

CONST

1
2
3
> const x = 1
x = 2
TypeError: Assignment to constant variable.

FOR OF LOOPS

1
2
3
4
5
6
7
> const letters = ['a', 'b', 'c']
const result = []
for (const letter of letters) {
result.push(letter)
}
result
['a', 'b', 'c']

REST PARAMETERS

1
2
3
4
5
> function f(...args) {
return args
}
f(1, 2, 3)
[1, 2, 3]

TEMPLATE LITERALS

1
2
> `1 + 1 = ${1 + 1}`
'1 + 1 = 2'

ACCESSORS IN OBJECT LITERALS

1
2
3
4
5
6
> const user = {
realName: 'Amir',
get name() { return this.realName },
set name(newName) { this.realName = newName },
}
undefined

BASIC ARRAY DESTRUCTURING

1
2
3
4
5
6
7
8
> const letters = ['a', 'b', 'c']
const [a, b, c, d] = letters;
[c, d]
['c', undefined]
> const letters = ['a', 'b', 'c']
const [a, ...others] = letters
others
['b', 'c']

COMPUTED PROPERTIES

1
2
3
4
5
> const loginCounts = {
['Be' + 'tty']: 7
}
loginCounts.Betty
7

BASIC OBJECT DESTRUCTURING

1
2
3
4
5
6
7
8
> const user = {name: 'Amir', email: 'amir@example.com', age: 36}
const {name, age} = user;
[name, age]
['Amir', 36]
> const key = 'NaMe'
const {[key.toLowerCase()]: value} = {name: 'Amir'}
value
'Amir'

SHORTHAND PROPERTIES

1
2
3
4
5
6
7
8
> const name = 'Amir'
const catName = 'Ms. Fluff'
const city = 'Paris'
const age = 36

const user = {name, catName, city, age};
[user.name, user.age]
['Amir', 36]

DESTRUCTURING

1
2
3
4
5
6
7
8
9
> function city({address: {city}}) {
return city
}
city({name: 'Amir', address: {city: 'Paris'}})
'Paris'
> const users = [{name: 'Amir'}, {name: 'Betty'}]
const [, {name}] = users
name
'Betty'

SHORTHAND METHODS

1
2
3
4
5
6
7
> const address = {
city: 'Paris',
country: 'France',
addressString() { return `${this.city}, ${this.country}` },
}
address.addressString()
'Paris, France'

BIND

1
2
3
4
5
6
7
> const user = {name: 'Amir'}
function userName() {
return this.name
}
const userNameBound = userName.bind(user)
userNameBound()
'Amir'

ARROW FUNCTIONS

1
2
3
4
5
6
7
8
9
> [1, 2, 3].map(x => x * 2)
[2, 4, 6]
> const user = {name: 'Amir'}
const getName = ({name}) => name
getName(user)
'Amir'
> const rest = (first, ...rest) => rest
rest(1, 2, 3, 4)
[2, 3, 4]

CLASSES

1
2
3
4
5
6
7
8
9
10
11
12
13
> class Cat {
constructor(name, vaccinated) {
this.name = name
this.vaccinated = vaccinated
}

needsVaccination() {
return !this.vaccinated
}
}

new Cat('Ms. Fluff', true).needsVaccination()
false

EXTENDING CLASSES

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> class Animal {
constructor(name) {
this.name = name
}
}

class Cat extends Animal {
constructor(name) {
super(name + ' the cat')
}
}

new Cat('Ms. Fluff').name
'Ms. Fluff the cat'

FUNCTION NAME PROPERTY

1
2
3
4
5
6
7
8
9
> (
function() { return 5 }
).name
''

> const f = function() { return 5 }
const f2 = f
f2.name
'f'

ANONYMOUS AND INLINE CLASSES

1
2
3
4
5
6
7
8
> new (
class {
speak() {
return 'yaong'
}
}
)().speak()
'yaong'

ACCESSOR PROPERTIES ON CLASSES

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
> class User {
constructor(name) {
this.actualName = name
}
get name() {
return `${this.actualName} the user`
}
}
new User('Betty').name
'Betty the user'

> class User {
constructor(name) {
this.actualName = name
}
set name(newName) {
this.actualName = newName
}
}
const user = new User('Amir')
user.name = 'Betty'
user.actualName
'Betty'

DEFAULT PARAMETERS

1
2
3
4
5
> function add(x, y=0) {
return x + y
}
[add(1, 2), add(1)]
[3, 1]

JSON STRINGIFY AND PARSE

1
2
3
4
5
6
7
8
9
10
11
12
> JSON.stringify({a: 2}) === '{"a":2}'
true

> JSON.parse('{"a": 1, "b" : 2}')
{a: 1, b: 2}

> const user = {
name: 'Amir',
toJSON: () => 'This is Amir!'
}
JSON.parse(JSON.stringify(user))
'This is Amir!'

STRING KEYED METHODS

1
2
3
4
5
> const user = {
'name of the ~user~'() { return 'Betty' }
}
user['name of the ~user~']()
'Betty'

STATIC METHODS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> class User {
static getUserName(user) {
return user.name
}
}
User.getUserName({name: 'Amir'})
'Amir'

> class User {
static get defaultName() {
return 'Amir'
}
}
User.defaultName
'Amir'

COMPUTED METHODS AND ACCESSORS

1
2
3
4
5
6
7
8
9
10
11
12
> class User {
constructor(name) {
this.name = name
}

get ['user' + 'Name']() {
return this.name
}
}

new User('Betty').userName
'Betty'

SYMBOL BASICS

1
2
3
4
5
6
7
8
9
10
11
12
> Symbol('a') === Symbol('a')
false

> const obj = {}
obj[true] = 1
Object.keys(obj)
['true']

> const nameSymbol = Symbol('name')
const user = {[nameSymbol]: 'Amir'}
user[nameSymbol]
'Amir'

SYMBOLS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
> class User {
constructor(name) {
this[Symbol.toStringTag] = name
}
}

const user = new User('Amir')
user.name = 'Betty'
user.toString()
'[object Amir]'

> const user = {
name: 'Amir',
[Symbol.toStringTag]: 'Amir'
}
JSON.parse(JSON.stringify(user))
{name: 'Amir'}

ISNAN

1
2
3
4
5
6
7
8
> isNaN(undefined)
true

> Number.isNaN(undefined)
false

> Number.isNaN(NaN)
true

NEW NUMBER METHODS

1
2
3
4
5
6
7
8
> Number.isFinite(-Infinity)
false

> Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)
false

> 2 ** 8
256

DEFINING ITERATORS

1
2
3
4
5
6
7
8
9
10
11
12
13
> const letters = ['a', 'b', 'c']
const iterator = letters[Symbol.iterator]()
iterator.next()
iterator.next()
{done: false, value: 'b'}

> const letters = ['a', 'b', 'c']
const iterator = letters[Symbol.iterator]()
iterator.next()
iterator.next()
iterator.next()
iterator.next()
{done: true, value: undefined}

GENERATORS

1
2
3
4
5
6
7
> function* numbersBelow(maximum) {
for (let i=0; i<maximum; i++) {
yield i
}
}
Array.from(numbersBelow(3))
[0, 1, 2]

PROBLEMS WITH OBJECT KEYS

1
2
3
4
5
6
> const obj = {
[{key1: 'value1'}]: 1,
[{key2: 'value2'}]: 2,
}
Object.keys(obj)
['[object Object]']

ITERATORS

1
2
3
4
5
6
7
8
9
10
11
12
13
> function* letters() {
yield 'a'
yield 'b'
yield 'c'
}
const [, b, c] = letters();
[b, c]
['b', 'c']

> const notAnIterator = 5
for (const x of notAnIterator) {
}
TypeError: notAnIterator is not iterable

MAPS

1
2
3
4
5
6
7
8
9
10
11
12
> const userEmails = new Map([
['Amir', 'amir@example.com'],
['Betty', 'betty@example.com']
])
userEmails.get('Betty')
'betty@example.com'

> const emails = new Map()
emails.set('Betty', 'betty.j@example.com')
emails.set('Betty', 'betty.k@example.com')
emails.get('Betty')
'betty.k@example.com'

SETS

1
2
3
4
5
6
7
8
9
10
> const names = new Set(['Amir', 'Betty', 'Cindy'])
names.add('Dalili')
names.has('Dalili')
true

> const names = new Set(['Amir'])
names.add('Betty')
names.add('Betty')
Array.from(names.values())
['Amir', 'Betty']

TAGGED TEMPLATE LITERALS

1
2
3
4
5
6
7
8
9
10
11
12
> function doubleNumbers(strings, ...values) {
let result = ''
for (let i=0; i<strings.length; i++) {
result += strings[i]
if (i < values.length) {
result += (2 * values[i]).toString()
}
}
return result
}
doubleNumbers`the numbers ${1} and ${2}`
'the numbers 2 and 4'

SPREAD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> const numbers = [
1,
...[2, 3],
4,
]
numbers
[1, 2, 3, 4]

> const amir = {
name: 'Amir',
age: 36,
}
const amirWithEmail = {
...amir,
email: 'amir@example.com'
}
amirWithEmail
{age: 36, email: 'amir@example.com', name: 'Amir'}

CLASS SCOPING

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> function createGorilla(name) {
class Gorilla {
constructor() {
this.name = name
}
}
return new Gorilla()
}
createGorilla('Michael').name
'Michael'

> if (true) {
class Cat { }
}
new Cat()
ReferenceError: Cat is not defined

CUSTOMIZING JSON SERIALIZATION

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
> JSON.parse(
JSON.stringify(
{name: 'Amir', age: 36, city: 'Paris'},
['name', 'city']
)
)
{city: 'Paris', name: 'Amir'}

> JSON.parse(
JSON.stringify(
{name: 'Amir', catName: 'Ms. Fluff', city: 'Paris'},
(key, value) => {
if (key === 'catName') {
return undefined
} else {
return value
}
}
)
)
{city: 'Paris', name: 'Amir'}

> JSON.parse(
`{"name": "Amir", "age": 36}`,
(key, value) => {
if (key === 'age' && value === 36) {
return 'thirty six'
} else {
return value
}
}
)
{age: 'thirty six', name: 'Amir'}

PROPERTY ORDER

1
2
3
4
5
> const user = {name: 'Amir', age: 36}
user.email = 'amir@example.com'
// Object keys come back in the order they were assigned.
Object.keys(user)
['name', 'age', 'email']

MAP ITERATORS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> const catAges = new Map([
['Ms. Fluff', 4],
['Keanu', 2],
])
Array.from(catAges.keys())
['Ms. Fluff', 'Keanu']

> const catAges = new Map([
['Keanu', 2],
['Ms. Fluff', 4],
])
Array.from(catAges.values())
[2, 4]

> const emails = new Map()
emails.set('Amir', 'amir@example.com')
emails.set('Betty', 'betty@example.com')
Array.from(emails)
[['Amir', 'amir@example.com'], ['Betty', 'betty@example.com']]

SET OPERATIONS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
> const set1 = new Set([1, 2, 3])
const set2 = new Set([2, 3, 4])
// Set union: all of the elements in either set.
const unionSet = new Set([...set1, ...set2]);
[unionSet.has(1), unionSet.has(4)]
Array.from(unionSet)
[1, 2, 3, 4]

> const set1 = new Set([1, 2, 3])
const set2 = new Set([2, 3, 4])
// Set intersection: all of the elements in both sets.
const intersectionSet = new Set(
Array.from(set1).filter(n => set2.has(n))
);
Array.from(intersectionSet)
[2, 3]

> const set1 = new Set([1, 2, 3])
const set2 = new Set([2, 3, 4])
// Set difference: all of the elements in set1 but not set2.
const differenceSet = new Set(
Array.from(set1).filter(n => !set2.has(n))
);
Array.from(differenceSet)
[1]

 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×