You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Function.prototype.bind2=function(context){if(typeofthis!=="function"){thrownewError("Function.prototype.bind - what is trying to be bound is not callable");}varself=this;varargs=Array.prototype.slice.call(arguments,1);varfBound=function(){varinnerArgs=Array.prototype.slice.call(arguments);returnself.apply(thisinstanceoffNOP ? this : context,args.concat(innerArgs));};varfNOP=function(){};fNOP.prototype=this.prototype;fBound.prototype=newfNOP();returnfBound;};
Function.prototype.bind2=function(context){// 1. 判断调用bind的是不是一个函数if(typeofthis!=="function"){thrownewError("Function.prototype.bind - what is trying to be bound is not callable");}// 2. 外层的this指向调用者(也就是调用的函数)varself=this;// 3. 收集调用bind时的其它参数varargs=Array.prototype.slice.call(arguments,1);// 4. 创建一个返回的函数varfBound=function(){// 6. 收集调用新的函数时传入的其它参数varinnerArgs=Array.prototype.slice.call(arguments);// 7. 使用apply改变调用函数时this的指向// 作为构造函数调用时this表示的是新产生的对象, 不作为构造函数用的时候传递contextreturnself.apply(thisinstanceoffNOP ? this : context,args.concat(innerArgs));};// 5. 创建一个空的函数, 且将原型指向调用者的原型(为了能用调用者原型中的属性)// 下面三步的作用有点类似于 fBoun.prototype = this.prototype 但有区别varfNOP=function(){};fNOP.prototype=this.prototype;fBound.prototype=newfNOP();// 8. 返回最后的结果returnfBound;};
Promise
event loop它的执行顺序:
一开始整个脚本作为一个宏任务执行
执行过程中同步代码直接执行,宏任务进入宏任务队列,微任务进入微任务队列
当前宏任务执行完出队,检查微任务列表,有则依次执行,直到全部执行完
执行浏览器UI线程的渲染工作
检查是否有Web Worker任务,有则执行
执行完本轮的宏任务,回到2,依次循环,直到宏任务和微任务队列都为空
微任务包括:MutationObserver,Promise.then() 或 catch(),Promise为基础开发的其它技术,比如 fetch API , V8的垃圾回收过程,Node独有的process.nextTick。
27道this-45道Promise
参考:【建议👍】再来40道this面试题酸爽继续(1.2w字用手整理)
参考:【建议星星】要就来45道Promise面试题一次爽到底(1.1w字用心整理)
this的5种绑定方式:
1
默认绑定:
相当于
2
严格模式下
3
是因为改用 let 或者 const ,变量都不会绑定到 window 上的:
4
5
6
7
8
9
10
如果你把一个函数当成参数传递到另一个函数的时候,也会发生隐式丢失的问题,且与包裹着它的函数的this指向无关。在非严格模式下,会把该函数的this绑定到window上,严格模式下绑定到undefined。
因为doFoo本来就是obj2调用的 所以doFoo指向obj2 , 因为foo这个函数本来就是window的a就是 2
他只是把obj的foo传进了doFoo 是在doFoo函数内部执行
这是this中的例外情况 当作为参数被传递时 会发生隐式绑定丢失
第一红圈,是隐式绑定,因为doFoo作为obj2的属性被调用,所以第5行中的this指向obj2
第二个红圈,obj.foo作为参数被传递,此时foo中的this会丢失原有的隐式绑定,可以理解为foo作为一个单独的函数被调用,此时和obj脱离的关系
所以第6行等于wondow.foo了
倒数第二行,当把函数进行赋值传递的时候,变量会指向函数的引用,这个时候会发生隐式绑定的丢失,函数的调用会采用默认策略
11
.call()
或者.apply()
的函数是会直接执行的bind()
是创建一个新的函数,需要手动调用才会执行.call()
和.apply()
用法基本类似,不过call接收若干个参数,而apply接收的是一个数组call、apply、bind接收到的第一个参数是空或者null、undefined的话,则会忽略这个参数。
12
谁调用的函数,函数内的this指向的就是谁。
对于setTimeout中的函数,这里存在隐式绑定的隐式丢失,也就是当我们将函数作为参数传递时会被隐式赋值,回调函数丢失this绑定,因此这时候setTimeout中的函数内的this是指向window的。
13
14
15
16
17
call是会直接执行函数的,bind是返回一个新函数,但不会执行。
18
19
20
21
22
23
24
箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined。
箭头函数 它里面的this是由外层作用域来决定的,且指向函数定义时的this而非执行时。
25
26
27
手写一个new实现
手写一个call实现
ES3实现:
ES6实现:
手写一个apply实现
ES3实现:
ES6实现:
手写一个bind实现
Promise
event loop它的执行顺序:
微任务包括:MutationObserver,Promise.then() 或 catch(),Promise为基础开发的其它技术,比如 fetch API , V8的垃圾回收过程,Node独有的process.nextTick。
宏任务包括: script,setTimeout,setInterval,setImmediate,I/O,UI rendering
1
2
3
4
5
6
7
8
9
Promise.then是微任务,它会被加入到本轮中的微任务列表,而定时器timer3是宏任务,它会被加入到下一轮的宏任务中。
10
11
12
总结
.then
和.catch
都会返回一个新的Promise
。catch
不管被连接到哪里,都能捕获上层未捕捉过的错误。13
构造函数中的 resolve 或 reject 只有第一次执行有效,多次调用没有任何作用 。
14
catch不管被连接到哪里,都能捕获上层未捕捉过的错误。
至于then3也会被执行,那是因为catch()也会返回一个Promise,且由于这个Promise没有返回值,所以打印出来的是undefined。
15
16
17
18
返回任意一个非 promise 的值都会被包裹成 promise 对象,因此这里的return new Error('error!!!')也被包裹成了return Promise.resolve(new Error('error!!!'))。
19
.then 或 .catch 返回的值不能是 promise 本身,否则会造成死循环。
20
.then 或者 .catch 的参数期望是函数,传入非函数则会发生值透传。
第一个then和第二个then中传入的都不是函数,一个是数字类型,一个是对象类型,因此发生了透传,将resolve(1) 的值直接传到最后一个then里。
21
Promise.resolve('1')的值会进入成功的函数,Promise.reject('2')的值会进入失败的函数
如果把第二个参数去掉,就进入了catch()中
22
由于Promise调用的是resolve(),因此.then()执行的应该是success()函数,可是success()函数抛出的是一个错误,它会被后面的catch()给捕获到,而不是被fail1函数捕获。
23
24
25
26
.all()的作用是接收一组异步任务,然后并行执行异步任务,并且在所有异步操作执行完后才执行回调。
.race()的作用也是接收一组异步任务,然后并行执行异步任务,只保留取第一个执行完成的异步操作的结果,其他的方法仍在执行,不过执行结果会被抛弃。
27
在间隔一秒后,控制台会同时打印出1, 2, 3,还有一个数组[1, 2, 3]。
The text was updated successfully, but these errors were encountered: