js
老派的 this
好题 只要记住
- function(){} 的 this 指向调用者
- ()=>{} 的 this 指向定义时的外层函数,若无就是 windows
Implicit Coercion
console.log('3' + 1) // 31 console.log('3' - 1) // 2 since subtraction operator ONLY trigger ToNumber() conversion, no string
Number(null) -> 0 Number(undefined) -> NaN. JSON doesn't have undefined value, when JSON stringify, undefined will be replaced with null in JSON data type.
Under Browser
- HTMLCollection 是类 Array, 要用 Array.from()
Object.defineProperty
Enumerable 属性:
Configurable属性:定义了后不仅再对这个对象做任何修改都会报错
而且 delete o.a也会无效。这个很重要 所有可以被删除的属性 都不能 Configurable: false
用点运算值和Object.defineProperty()为对象的属性赋值时 默认属性很不相同:
set, get:有set或get就不能有value 否则会报错,也不能有writable
//Uncaught TypeError: Invalid property descriptor.
//Cannot both specify accessors and a value or writable attribute, #
毕竟只能通过一个方法来更改obj的呀~
- value/writable被称为数据描述符(= 称为赋值运算符);get/set被称为存取描述符
- 用defineProperty时 所有可选键值均默认为undefined或false
p.s. How to observe an array?
// ×
Object.defineProperty(arr, i, {
configurable: false,
enumerable: false,
get: () => arr[i],
set: (value) => {
arr[i] = value // 会溢出
}
})
// ✅
let v
Object.defineProperty(arr, i, {
configurable: false,
enumerable: false,
get: () => v,
set: (value) => {
v = value
}
})
p.p.s.:关于属性统计表 这个超清晰
promise 相关
- 一个简易的自制promise
```javascript class Poppy { constructor(executor) { const self = this //原文是构造函数 为了避免下面的bind所以用了变量 但是class里面的方法没法访问到construtor里的变量呀… this.status = 'pending' //只是用作记录 this.data = undefined //同用作记录 this.onResolvedCallBack = [] //我感觉这里也永远都只会有一个 不用数组 try { executor(this.resolve.bind(this), this.reject) } catch (e) { this.reject(e) } return this }
resolve(val) {
if (val instanceof Promise) { return val.then(resolve, reject) }
// setTimeout(function () { // 异步执行所有的回调函数
if (this.status === 'pending') {
this.status = 'resolved'
this.data = val
//所以如果是没有异步时间的话 下面这行是没用的。下面这行的意义就在于先把res后要处理的函数存储起来,等待res后再来处理。 this.onResolvedCallBack.forEach(cb => cb(val)||val ) } // }) }
reject(){}
then(onResolved, onRejected) {
onResolved = typeof onResolved === 'function' ? onResolved : function (v) {}
// 中间无异步时,返回的也是new Poppy
if (this.status === 'resolved') {
return new Poppy((resolve, reject) => {
const x = onResolved(this.data)||this.data
if (x instanceof Poppy) return x.then(resolve, reject)
resolve(x)
})
}
// 中间有异步时
if (this.status === 'pending') {
return new Poppy((resolve, reject) => {
// 这一个then里要执行的暂存起来
// 下下个then就留给这个new Poppy去处理了。而这个new Poppy的执行完毕要等到这一个then处理完后。
// 就相当于是一个非常长久的waiting后再resolve的了。
// 所以只要一个Promise链中任何一个环节是有等待操作的,以后的每个then都是有等待操作,并经过这里处理了。
this.onResolvedCallBack.push((value) => {
const x = onResolved(value) || this.data
if(x instanceof Poppy) return x.then(resolve, reject)
resolve(x)
})
})
}
}
}
const a = new Poppy((res, reject) => { setTimeout(()=>{res(2)}, 100) // res(4) }) .then(r => { console.log(r) // return new Poppy(res => res(r)) }) .then(a => console.log('boom2', a))
```
- 浏览器的promise
- promise+generator的co库
-
浏览器通过async/await的实现
-
如何让forEach对异步函数parallely执行?使用不了。因为forEach的本质就是for循环的匿名函数 你又不能操作匿名函数给其加上async。
可以用for...of循环数组item(推荐) 或者
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
ref: https://lavrton.com/javascript-loops-how-to-handle-async-await-6252dd3c795/ d
注意:可别和for...in弄错了 for..in数组得到的是属性key 也就是0,1,2..和其他若有挂载的属性key
事件循环
通过人家代码的这个错误案例,可以体会:
var result = '';
var totalPage = 3;
for(var page=1; page<totalPage; page++) {
var ajax = new XMLHttpRequest();
ajax.open('get','https://001.980512.com/qun/api/topic_order_list.htm?size=10&topic_id=2592&mid=9657585943&page' + page);
ajax.send();
ajax.onreadystatechange = function () {
if (ajax.readyState==4 && ajax.status==200) {
var response = ajax.responseText;
var respJson = eval('(' + response + ')');
var data = respJson.data;
if(data.length > 0) {
for(var i=0; i<data.length; i++) {
result = result + data[i].address + ',' + data[i].total_fee + ',' + data[i].link_man + ',' + data[i].link_tel + '\n';
}
}
}
}
}
let start = Date.now();
while(Date.now()-start <= 5000);
console.log(result)
这里的 while, 当然要改为 setTimeOut() 移到下一个事件循环
marcrotask queue 包括:script, dom event, setTimeout 一般宏任务由宿主发起,微任务由 js 本身发起