Live Note

Remain optimistic

Promise 的特点

  1. 对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Fulfilled(已成功)、Rejected(已失败)。只有异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
  2. 一旦状态改变就不会再变,任何时候得到的都是这个结果。Promise 对象的状态改变只有两个可能:从 Pending 变为 Fulfilled,从 Pending 变为 Rejected。只要这两种情况发生,这时就成为 resolve。就算改变已经发生,再对 Promise 对象添加回调函数,也会立即得到这个结果。与 Event 完全不同,Event 一旦错过再监听是得不到结果的。

基本用法

1
2
3
4
5
6
7
8
9
var promise = new Promise(function (resolve, reject) {
//some code

if (/*异步操作成功*/) {
resolve(value);
} else {
reject(error);
}
})
Read more »

  1. 从 Reflect 对象上可以获得语言内部的方法
  2. 修改某些 Object 方法的返回结果,让其变得更合理。比如 Object.defineProperty 在无法定义属性时会抛出一个错误,而 Reflect.defineProperty 则会返回 false
  3. 让 Object 操作都变成函数行为。
  4. 只要是 Proxy 对象的方法,就能在 Reflect 对象上找到相应的方法,无论 Proxy 怎么修改默认行为,总可以在 Reflect 上获取默认行为

静态方法

  • Reflect.apply(target, thisArg, args)
    等同于 Function.prototype.apply.call(func, thisArg, args),用于绑定 this 对象后执行给定函数。

  • Reflect.construct(target, args)
    等同于 new target(…args),提供了一种不使用 new 来调用构造函数的方法:

    1
    2
    3
    4
    5
    6
    7
    8
    function Greeting(name) {
    this.name = name
    }
    //new 的写法
    const instance = new Greeting("张三")

    //Reflect.construct 写法
    const instance = Reflect.construct(Greeting, ["张三"])
Read more »

Proxy 用于修改某些操作的默认行为,等同与在语言层面做出修改,属于一种 meta programming。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let obj = new Proxy(
{},
{
get: function (target, key, receiver) {
console.log(`getting ${key}`)
return Reflect.get(target, key, receiver)
},
set: function (target, key, receiver) {
console.log(`setting ${key}`)
return Reflect.set(target, key, receiver)
},
}
)
obj.count = 1
//setting count
obj.count
//getting count
Read more »

ES6 提供了 Map 数据结构,它类似对象,也是键值对的集合,但是‘键’的范围不限于字符串,各种类型的值(包括对象)都可以当做键。Map 结构是一种更完善的 Hash 结构实现。如果需要‘键值对’的数据结构,Map 比 Object 更合适。

1
2
3
4
let m = new Map()
const o = { p: "hello" }
m.set(o, "content")
m.get(o) //'content'

Map 也可以接受一个数组作为参数,该数组的成员是一个表示键值对的数组:

1
2
3
4
5
6
7
8
const map = new Map([
["name", "张三"],
["title", "test"],
])

map.size //2
map.has("name") //true
map.get("name") //'张三'

Map 构造函数接受数组作为参数,实际上执行的是下面的算法:

1
2
3
4
5
6
const item = [
["name", "张三"],
["title", "test"],
]
const map = new Map()
item.forEach(([key, valule]) => map.set(key, value))
Read more »

基本用法

Set 类似于数组,但是成员的值都是唯一的,没有重复。Set 本身是一个构造函数。

1
2
3
4
5
6
7
8
9
10
11
const set = new Set()
;[1, 2, 3, 4].forEach((x) => set.add(x))
for (let value of set) {
console.log(value) //1, 2, 3, 4
}

const set = new Set([1, 2, 3, 4])
;[...set] //[1, 2, 3, 4]

//数组除重
;[...new Set(array)]

在 Set 内部,NaN 是相等的,两个对象总是不相等的。

1
2
3
4
5
6
7
8
let set = new Set()
let a = NaN
let b = NaN
set.add(a).add(b)
set.size //1

set.add({}).add({})
set.size //3
Read more »

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。
Symbol 值通过 Symbol 函数生成,也就是说,对象的属性名现在可以有两种类型:一种是字符串,另一种就是 Symbol 类型。只要属性名属于 Symbol 类型,就是独一无二的,可以保证不会与其他属性名冲突。

1
2
let s = Symbol()
typeof s //symbol

Symbol 函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在 console 显示。

1
2
let s = Symbol("str")
s.toString() //'Symbol(str)'

如果 Symbol 的参数是一个对象,就会调用该对象的 toString 方法,再生成 Symbol 值

1
2
3
4
5
6
7
const obj = {
toString() {
return "test"
},
}
const s = Symbol(obj)
s.toString() //'Symbol(test)'
Read more »

拖拽元素事件:

  • dragstart:拖拽前触发
  • drag:拖拽前到拖拽结束之间,连续触发
  • dragend:拖拽结束触发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<ul>
<li>li1</li>
<li>li2</li>
<li>li3</li>
</ul>

<script>
let aLi = document.querySelectorAll("li")
for (let li of aLi) {
let count = 0
li.ondragstart = function () {
this.style.backgroundColor = "red"
}
li.ondrag = function () {
console.log(count++) //连续触发
}
li.ondragend = function () {
this.style.backgroundColor = ""
}
}
</script>
Read more »

data 自定义数据在 query、mobile 常用。

1
2
3
4
5
6
7
<div id="div1" data-test="hello" data-test-last="world"></div>

<script>
let oDiv = document.getElementById("div1")
oDiv.dataset.test //'hello'
oDiv.dataset.testLast //'world'
</script>

eval()

eval 可以解析任何字符串变成 JS:

1
2
3
var str = "function testFunction() {console.log('test');}"
eval(str)
testFunction() //'test'

JSON.parse()

JSON.parse 只能解析 JSON 形式的字符串变成 JS,安全性比 eval 高一些。
字符串中的属性要严格加上引号

1
2
3
let str = '{ "name" : "hello" }'
let json = JSON.parse(str)
json.name //'hello'
Read more »

querySelector()

querySelector 只能选择一组中的第一个元素:

1
2
3
4
5
6
<div class="test">div1</div>
<div class="test">div2</div>

<script>
document.querySelector(".test").style.color = "red" //只有第一个会变红
</script>

querySelectorAll()

querySelectorAll 获取一组元素:

1
2
3
4
5
6
7
8
9
<div class="test">div1</div>
<div class="test">div2</div>

<script>
let aDiv = document.querySelectorAll(".test")
for (let div of aDiv) {
div.style.color = "red"
}
</script>
Read more »