刷《一年半经验,百度、有赞、阿里面试总结》·手记 (2)

vuejs是利用Object.defineProperty来实现的MVVM,采用的是订阅发布模式。每个data中都有set和get属性,这种点对点的效率,比Angular实现MVVM的方式的效率更高。

<body> <input type="text"> <script> const input = document.querySelector('input') const obj = {} Object.defineProperty(obj, 'data', { enumerable: false, // 不可枚举 configurable: false, // 不可删除 set(value){ input.value = value _value = value // console.log(input.value) }, get(){ return _value } }) obj.data = '123' input.onchange = e => { obj.data = e.target.value } </script> </body> 1.7 实现Promise

这是一位大佬实现的Promise版本:过了Promie/A+标准的测试!!!网上能搜到的基本都是从这篇文章变形而来或者直接照搬!!!原文地址,直接戳:剖析Promise内部结构,一步一步实现一个完整的、能通过所有Test case的Promise类

下面附上一种近乎完美的实现:可能无法和其他Promise库的实现无缝对接。但是,上面的原文实现了全部的,欢迎Mark!

function MyPromise(executor){ var that = this this.status = 'pending' // 当前状态 this.data = undefined this.onResolvedCallback = [] // Promise resolve时的回调函数集,因为在Promise结束之前有可能有多个回调添加到它上面 this.onRejectedCallback = [] // Promise reject时的回调函数集,因为在Promise结束之前有可能有多个回调添加到它上面 // 更改状态 => 绑定数据 => 执行回调函数集 function resolve(value){ if(that.status === 'pending'){ that.status = 'resolved' that.data = value for(var i = 0; i < that.onResolvedCallback.length; ++i){ that.onResolvedCallback[i](value) } } } function reject(reason){ if(that.status === 'pending'){ that.status = 'rejected' that.data = reason for(var i = 0; i < that.onResolvedCallback.length; ++i){ that.onRejectedCallback[i](reason) } } } try{ executor(resolve, reject) // resolve, reject两个函数可以在外部传入的函数(executor)中调用 } catch(e) { // 考虑到执行过程可能有错 reject(e) } } // 标准是没有catch方法的,实现了then,就实现了catch // then/catch 均要返回一个新的Promise实例 MyPromise.prototype.then = function(onResolved, onRejected){ var that = this var promise2 // 值穿透 onResolved = typeof onResolved === 'function' ? onResolved : function(v){ return v } onRejected = typeof onRejected === 'function' ? onRejected : function(r){ return r } if(that.status === 'resolved'){ return promise2 = new MyPromise(function(resolve, reject){ try{ var x = onResolved(that.data) if(x instanceof MyPromise){ // 如果onResolved的返回值是一个Promise对象,直接取它的结果做为promise2的结果 x.then(resolve, reject) } resolve(x) // 否则,以它的返回值做为promise2的结果 } catch(e) { reject(e) // 如果出错,以捕获到的错误做为promise2的结果 } }) } if(that.status === 'rejected'){ return promise2 = new MyPromise(function(resolve, reject){ try{ var x = onRejected(that.data) if(x instanceof MyPromise){ x.then(resolve, reject) } } catch(e) { reject(e) } }) } if(that.status === 'pending'){ return promise2 = new MyPromise(function(resolve, reject){ self.onResolvedCallback.push(function(reason){ try{ var x = onResolved(that.data) if(x instanceof MyPromise){ x.then(resolve, reject) } } catch(e) { reject(e) } }) self.onRejectedCallback.push(function(value){ try{ var x = onRejected(that.data) if(x instanceof MyPromise){ x.then(resolve, reject) } } catch(e) { reject(e) } }) }) } } MyPromise.prototype.catch = function(onRejected){ return this.then(null, onRejected) } // 以下是简单的测试样例: new MyPromise(resolve => resolve(8)).then(value => { console.log(value) }) 1.8 Event Loop

题目:说一下JS的EventLoop

其实阮一峰老师这篇《JavaScript 运行机制详解:再谈Event Loop》已经讲的很清晰了(手动赞)!

这里简单总结下:

JS是单线程的,其上面的所有任务都是在两个地方执行:执行栈和任务队列。前者是存放同步任务;后者是异步任务有结果后,就在其中放入一个事件。

当执行栈的任务都执行完了(栈空),js会读取任务队列,并将可以执行的任务从任务队列丢到执行栈中执行。

这个过程是循环进行,所以称作Loop。

2. CSS相关 2.1 水平垂直居中

题目: 两种以上方式实现已知或者未知宽度的垂直水平居中

第一种方法就是利用CSS3的translate进行偏移定位,注意:两个参数的百分比都是针对元素本身计算的。

.wrap { position: relative; width: 100vw; height: 100vh; } .box { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdyys.html