1. 获取url传递的参数
方法一
/**
* @description 获取查询字段
* @param {string} searchKey 需要获取的查询 key
* @return {string | null} 返回查询结果
*/
export function getQueryString(searchKey: string : (string | null) ) {
// 正则匹配
let reg = new RegExp(`(^|&)${searchKey}=([^&]*)(&|$)`, 'i')
let r = window.location.search.substr(1).match(reg)
return r !== null ? decodeURI(r[2]) : null
}
方法二
export function getQueryString(searchKey: string) {
const urlSearch = location.search
if (!urlSearch) {
return ''
}
// 移除url中的问号
const queryString = urlSearch.slice(1)
// 将所有参数转化为数组
const queryArray = queryString.split('&')
// 将参数转化为二维数组,如[['name','fruit'],['language', 'zh-CN']]
const queryMap = queryArray.map( (item: string) => item.split('=') )
// 获取参数的value
const [ result ] = queryMap.filter( ([key, _value]: string[]) => key === searchKey ).map( ([_key, value]: string[]) => value )
return (result || '').replace(/[ +]/g, '%20').replace(/(%[a-f0-9]{2})+/ig, match => decodeURIComponent(match) )
}
2. 变量提升
var a = 2
function a() {
a = 3
}
a() // Uncaught TypeError: a is not a function
alert(a)
实际运行顺序
var a
function a() {
a = 3
}
a = 2
console.log(a) // 2
3. 异步执行顺序
参考文档:www.ruanyifeng.com/blog/2014/1…
3.1 宏任务和微任务的执行顺序
// 宏任务队列:setTimeout
// 微任务队列:Promise
// 异步宏任务
setTimeout(() => {
console.log('timeout')
}, 0)
// 异步微任务
const promise = new Promise((resolve, reject) => {
// 这里面的两个console.log方法是同步方法,因此先执行
console.log('promise init')
resolve(1) // 触发then微任务
console.log('promise end')
})
promise.then((res) => {
console.log('promise result', res)
})
// 执行结果
1. promise init
2. promise end
3. promise result 1
4. timeout
3.2 宏任务微任务交错执行
在代码执行的过程中,将宏任务和微任务放入相应的队列中。
只要见到setTimeout就会被塞到宏任务队列中,然后按塞入的顺序进行执行。
// 1. 此setTimeout先进入宏任务,但不执行
setTimeout(() => {
console.log('timeout1')
// 微任务先执行
Promise.resolve().then(() => {
console.log('promise1')
})
}, 0)
// 最先执行微任务
Promise.resolve().then(() => {
console.log('promise2')
// 2. 这个setTimeout,在执行文promise微任务后,再将这个setTimeout放入宏任务。因此这个宏任务比上一个setTimeout后执行。
setTimeout(() => {
console.log('timeout2')
}, 0);
})
// 执行结果
1. promise2
2. timeout1
3. promise1
4. timeout2
3.3 async await 拆解
async function fn() {
return await 1234
// 相当于返回如下代码,代码的执行结果相同,也就是说async会被包裹成Promise.resolve返回。
return Promise.resolve(1234)
}
fn().then(res => console.log(res))
async实际上是返回了一个promise
3.4 async thenable
返回一个包含then方法函数
async function fn() {
return await {
then(resolve) {
resolve(1234)
}
}
}
fn().then(res => console.log(res))
或
async function fn() {
// promise规范:当return返回一个对象或function时,并且存在一个then方法,就会当成promise处理,
return ({
then(resolve) {
resolve(1234)
// 如果resolve的也是then,则将会递归,如下
resolve({
then(r) {
// 遇到thenable会递归使用promise.then,调用,直到resolve返回值是一个基础类型
r(1)
}
})
}
})
}
fn().then(res => console.log(res))
3.5 使用async await顺序判断
async function async1() {
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2')
}
async1()
console.log('script')
// 执行结果
1. async1 start
2. async2
3. script
4. async1 end
或 将async转换成我们熟悉的promise
async function async1() {
// 同步方法
console.log('async1 start')
new Promise(resolve => {
// 同步方法
console.log('async2')
resolve()
// 异步方法
}).then(res => console.log('async end'))
}
async1()
// 同步方法
console.log('script')
// 执行结果
1. async1 start
2. async2
3. script
4. async1 end
3.6 如果promise没有resolve或reject
async function async1() {
console.log('async1 start')
await new Promise(resolve => {
console.log('promise1')
// 没有执行resolve或reject,就会导致整个promise永远没有完成,await下面的代码就永远不会执行
})
console.log('async1 success')
// return了一个undefined的promise
return 'async1 end'
}
console.log('script start')
async1().then(res => console.log(res))
console.log('script end')
// 执行结果
1. script start
2. async1 start
3. promise1
4. script end
3.7 再来一个
js代码从上到下执行,先执行同步任务,再执行微任务,最后执行宏任务。
async function async1() {
console.log('async1 start')
// 调用的async会返回一个promise,因此await会等一下
await async2()
// await执行完,才会继续执行,先进入异步微任务,先执行
console.log('async1 end')
}
// async会返回一个promise,因此await会等一下
async function async2() {
console.log('async2')
}
console.log('scrpit start')
setTimeout(() => {
console.log('setTimeout')
}, 0)
async1()
new Promise(function(resolve) {
// 同步执行
console.log('promise1')
resolve()
}).then(function() {
console.log('promise2')
}).then(function() {
console.log('promise3')
}).then(function() {
console.log('promise4')
}).then(function() {
console.log('promise5')
})
console.log('scrpit end')
// 执行结果
1. scrpit start
2. async1 start
3. async2
4. promise1
5. scrpit end // 第一轮执行完成
6. async1 end
7. promise2
8. promise3
9. promise4
10. promise5
11. setTimeout
3.8 最后一个
async function async1() {
console.log('async1 start')
return new Promise(resolve => {
resolve(async2())
// resolve执行完成后,抛出一个then的微任务,塞到队里中
}).then(() => {
console.log('async1 end')
})
}
function async2() {
console.log('async2')
}
setTimeout(() => {
console.log('setTimeout')
}, 0)
async1()
new Promise(function(resolve) {
console.log('promise')
resolve()
}).then(function() {
console.log('promise2')
}).then(function() {
console.log('promise3')
}).then(function() {
console.log('promise4')
})
// 执行结果
1. async1 start
2. async2
3. promise
4. async1 end
5. promise2
6. promise3
7. promise4
8. setTimeout
改一下
resolve处理thenable,也会包裹一层promise
async function async1() {
// 1. 打印async1 start
console.log('async1 start')
// 2. 将promise塞入异步队列
return new Promise(resolve => {
//4. 执行resolve,执行async2。resolve处理thenable也会再包裹一层promise
resolve(async2())
}).then(() => {
console.log('async1 end')
})
}
// 6.将async塞入异步队列,自己本身已是一个promise
async function async2() {
console.log('async2')
}
setTimeout(() => {
console.log('setTimeout')
}, 0)
async1()
// 3. 将promise塞入异步队列
new Promise(function(resolve) {
// 5. 打印promise,执行resolve,将下一个then塞入异步队列
console.log('promise')
resolve()
}).then(function() {
console.log('promise2')
}).then(function() {
console.log('promise3')
}).then(function() {
console.log('promise4')
})
// 执行结果
1. async1 start
2. async2
3. promise
4. promise2
5. promise3
6. sync1 end
7. promise4
8. setTimeout
async function async1() {
console.log('async1 start')
return new Promise(resolve => {
resolve(async2())
}).then(() => {
console.log('async1 end')
})
}
// 去掉async,并包裹成thenable
function async2() {
console.log('async2')
return { then(r){r()} }
}
setTimeout(() => {
console.log('setTimeout')
}, 0)
async1()
new Promise(function(resolve) {
console.log('promise')
resolve()
}).then(function() {
console.log('promise2')
}).then(function() {
console.log('promise3')
}).then(function() {
console.log('promise4')
})
// 执行结果
1. async1 start
2. async2
3. promise
4. promise2
5. sync1 end
6. promise3
7. promise4
8. setTimeout
总结:
async本身会返回一个promisejs代码从上到下执行,先执行同步任务,再执行微任务,最后执行宏任务- 遇到
async await的时候要想办法转成promise
4. nodejs中的EventLoop
4.1
APPLICATION: 相当于我们的react或vue的程序
4.2 nodejs中的任务队列
| 宏任务 | 微任务 |
|---|---|
| setTimeout | Promise(async) |
| setInterval | process.nextTick |
| setImmediate | |
| IO |
4.3 nodejs中的任务比较
1. 比较setImmediate和setTimeout的执行顺序
2. 理解process.nextTick
3. 比较process.nextTick和setImmediate
5. 基础
console.log(a) // 1
console.log(typeof fruit(a)) // Uncaught TypeError: fruit is not a function
var flag = true
if (flag) {
var a = 1
}
if (flag) {
function fruit(a) {
fruit = a
console.log("fruit1")
}
} else {
function fruit(a) {
fruit = a
console.log('fruit2')
}
}
function fn() {
console.log(this.length)
}
var fruit = {
length: 5,
method: function() {
"use strict"
fn()
arguments[0]()
}
}
const result = fruit.method.bind(null)
result(fn, 1)
// 打印结果
0
2
3.如下,请问变量a会被GC回收吗
function test() {
var a = 'fruit'
return function() {
eval('')
}
}
test()()
会,因为a是局部变量
- 写出以下代码输出值,并解释原因
Object.prototype.a = 'a'
Function.prototype.a = 'a1'
function Person() {}
var fruit = new Person()
console.log(Person.a)
console.log(fruit.a)
console.log(1..a)
console.log(fruit.a)
console.log(fruit.__proto__.__proto__.constructor.constructor.constructor)
Object.prototype和Funtion.prototype打印的内容差距很大原因是什么
-{
var a = 1
const b = 2
function test(){}
test = 3
console.log(typeof test)
}
console.log(a)
console.log(typeof test)
console.log(b)
- ES6的元编程
- 解释下
babel编译后的async原理
let a = 0
let fruit = async () => {
a = a + await 10
console.log(a)
}
fruit()
console.log(++a)
async function async1() {
console.log(1)
await async2()
console.log(3)
}
async function async2() {
console.log(2)
}
async1()
console.log(4)
$('#test').click(function(argument) {
console.log(1)
})
setTimeout(function() {
console.log(2)
}, 0)
while(true) {
console.log(Math.random())
}
const pro = new Promise((resolve, reject) => {
const innerpro = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 0)
console.log(2)
resolve(3)
})
innerpro.then(res => console.log(res))
resolve(4)
console.log('fruit')
})
pro.then(res => console.log(res))
console.log('end')
var s = []
var arr = s
for (var i = 0; i < 3; i++) {
var pusher = {
value: 'item' + 1
},tmp
if (i !== 2) {
tmp = []
pusher.chuldren = tmp
}
arr.push(pusher)
arr = tmp
}
console.log(s[0])