前端面试笔记整理(四) —— 手写代码

  1 //手写call apply 
  2 Function.prototype.myCall = function(ctx,...args) {
  3     var ctx = ctx || window
  4  // 给 context 添加一个属性
  5   // getValue.call(a, 'yck', '24') => a.fn = getValue
  6     ctx.fn = this
  7     //调用
  8     let res = ctx.fn(...args)
  9     delete ctx.fn
 10     return res 
 11 }
 12 Function.prototype.myApplly = function(ctx,...args) {
 13     var ctx = ctx || window
 14     ctx.fn = this
 15     var res = args[1]? ctx.fn(...args[1]):ctx.fn()
 16     delete ctx.fn
 17     return res
 18 }
 19 
 20 
 21 
 22 //手写bind
 23 Function.prototype.myBind = function(ctx) {
 24     if(typeof this != 'function'){
 25         throw new TypeError('Error')
 26     }
 27     var _this = this
 28     //slice并不会删除 如果需要删除 用splic  因为第一个参数是ctx
 29     var ars = [...arguments].slice(1)
 30     return function F() {
 31         if(this instanceof F){
 32             return new _this(...ars,...arguments)
 33         }
 34         return _this.apply(ctx,args.concat(...arguments))
 35     }
 36 }
 37 
 38 
 39 
 40 
 41 //手写promise
 42 function myPromise(fn) {
 43     const that = this
 44     that.state = 'Pending'
 45     that.val = null
 46     that.resolvedCallbacks = []
 47     that.rejectCalbacks = []
 48     function resolve(val) {
 49         if(that.state === 'Pending'){
 50             that.state = 'Resolved'
 51             that.val = val
 52             that.resolvedCallbacks.forEach(ele => ele(that.val))
 53         }
 54     }
 55     function reject(val) {
 56         if(that.state === 'Pending') {
 57             that.state = "Rejected"
 58             that.val = val
 59             that.rejectCalbacks.forEach(ele => ele(that.val))
 60         }
 61     }
 62     try {
 63         fn(resolve,reject)
 64     } catch {
 65         reject(error)
 66     }
 67 }
 68 
 69 
 70 
 71 //手写promise.all
 72 Promise.all = arr => {
 73     let aResult = []
 74     return new _Promise(function(resolve,reject) {
 75         let  i = 0
 76         next()
 77         function next() {
 78             arr[i].then(function(res) {
 79                 aResult.push(res)
 80                 i++
 81                 if(i == arr.length) {
 82                     resolve(aResult)
 83                 } else {
 84                     next()
 85                 }
 86             })
 87         }
 88     })
 89 }
 90 
 91 
 92 // 大数相加
 93 function sumStrings(a,b){
 94     var res='', c=0;
 95     a = a.split('');
 96     b = b.split('');
 97     while (a.length || b.length || c){
 98         c += ~~a.pop() + ~~b.pop();
 99         res = c % 10 + res;
100         c = c>9?1:0;
101     }
102     return res.replace(/^0+/g,'');
103    
104   }
105 
106 //手写ajax
107 var xhr = new XMLHttpRequest()
108 xhr.open('get','text.html')
109 xhr.send()
110 xhr.onreadystatechange= function() {
111     if(ajax.readyState == 4 && ajax.status == 200 || ajax.status === 304){
112         console.log(ajax.responseText)
113     }
114 }
115 xhr.open('post','text.html')
116 xhr.send('name')
117 xhr.onreadystatechange = function() {
118     if(xhr.readyState ==4 && xhr.status == 200 || ajax.status === 304)
119     {
120         console.log(xhr.responseText)
121     }
122 }
123 
124 
125 
126 //手写深拷贝
127 function deepClone(obj) {
128     if (typeof obj !== 'object'|| obj == null){
129     console.log('此时传入的为'+ obj +',执行递归,直接拷贝');
130     return obj
131     }
132     let res 
133     if(obj instanceof Array) {
134         res = []
135     } else {
136         res = {}
137     }
138     for(let key in obj){
139         if(obj.hasOwnProperty(key)){
140             res[key] = deepClone(obj[key])
141         } else{
142             res[key] = obj[key]
143         }
144     }
145     return res
146 }
147 
148 // 深拷贝优化版
149 function deepClone(obj){
150     let res = Array.isArray(obj)?[]:{}
151     if(obj && typeof obj === "Object"){
152         for(let key in obj){
153             if(obj.hasOwnProperty(key)){
154                 if(obj && typeof obj === "Object"){
155                   res[key] = deepClone(obj[key])
156                 } else {
157                     res[key] = obj[key]
158                 }
159             }
160         }
161     }
162     return res
163 }
164 
165 
166 
167 
168 //手写new构造
169 //fn为构造函数
170 function myNew(fn) {
171     var obj = new Object
172     obj._proto_ = fn.prototype
173     k = fn.call(obj,...args)
174     typeof k === 'object' ? k: obj
175 }
176 
177 
178 
179 //手写双向绑定
180 //html
181 <input id="in" type="text" />
182 <div id="out"></div>
183  
184 //js
185 var obj = {
186 }
187   
188 var input = document.querySelector('#model')
189 var text = document.querySelector('#modelText')
190 
191 Object.defineProperty(obj,'name',{
192     get:function(){
193         console.log('获取')
194     },
195     set:function(val){
196        console.log('修改')
197        input.value = val
198        text.textContent = val
199     }
200 })
201 input.addEventListener('input',function(val){
202 console.log(input)
203 obj.name = input.value
204 })
205 //发布订阅模式
206 class EvenBus {
207     constructor() {
208         this.events = Object.create(null)
209     }
210     on(event,fn){
211         this.events.event = this.events.event || []
212         this.events.event.push(fn)
213     }
214     off(event,fn){
215         const index = (this.events.events||[]).indexOf(fn)
216         if(index < -1){
217             return
218         } else{
219             this.events.events.splice(index,1)
220         }
221     }
222     fire(event){
223         this.events.event.forEach(fn => fn())
224     }
225 }
226 var b = new EvenBus
227 b.on('onclick',function(){
228     console.log('b.on')
229 })
230 b.fire('onclick')
231 
232 
233 
234 //primise 串执行
235 const parallerPromise = promise.reduce(
236     (acc,cur) => acc.then(res => cur(res)),
237     Promise.resolve(val))
238 const paraller = promise.reduce(
239     (acc,cur) => acc.then(() => 
240         cur.then(print)
241     ),
242     Promise.resolve(val)
243 )
244 // async
245 var fn=async function(arr){
246     for(let i=0,len=arr.length;i<len;i++){
247         var result=await arr[i]
248         console.log(result)
249     }
250  }   
251  fn(arr)
252 //Generator
253 const Cgenerator = function (arr) {
254     const fn = function* () {
255         for (let i = 0, len = arr.length; i < len; i++) {
256             yield arr[i]
257         }
258     }
259     const gen = fn();
260     const step = function (nextF) {
261         let next=nextF()
262         if (next.done) {
263             return;
264         }
265         if (next.value) {
266             next.value.then((data) => {
267                 console.log(data)
268                 step(() => { return gen.next(); })
269             })
270         }
271     }
272     step(() => { return gen.next(); })
273 }
274 Cgenerator(arr)
275 
276 
277 //传统类的声明
278 function Animal() {
279     this.name = name  //通过this来表明这是一个构造函数
280 }
281 //es6声明
282 class Animal2 {
283     constructor(){
284         this.name = name
285     }
286 }
287 //实例化类的对象
288 new Animal()
289 new Animal2()
290 
291 //类的继承 依靠原型链来实现
292 // 1.借助构造函数实现继承
293 //(缺点:parent1原型链的属性并不可被child继承)
294 function Parent1() {
295     this.name = 'Parent1'
296 }
297 
298 function A(){}
299 function B(){
300     A.apply(this)
301 }
302 B.prototype = new A()
303 
304 
305 function Child1() {
306      /*     
307     此处用apply也可,原理是:把父函数在子函数执行同时
308     修改了this的指向,从而实现了父类的属性都挂载到
309     child属性上
310         */
311     Parent1.call(this)
312     this.type = 'Child1'
313 314  
315 //2.借助原型链实现继承
316 // 在一个类上实例化了多个对象 多个对象并不是相互独立的,原因是原型链的原型对象是公用的
317 function Parent2() {
318     this.name = 'Parent1'
319 }
320 function Child2() {
321     this.type = 'Child2'
322 }
323 Child2.prototype = new Parent2()
324 
325 //3.组合方式继承
326 // 缺点:父级的构造函数执行了多次
327 function Parent3() {
328     this.name = 'Parent3'
329 }
330 function Child3() {
331     Parent3.call(this)
332     this.type = 'Child3'
333 }
334 Child3.prototype = new Parent3()
335 
336 //4.组合继承优化
337 //缺点:instanceof 无法区分出一个对象是子类实例化的还是父类实例化的
338 function Parent4() {
339     this.name = 'Parent4'
340 }
341 function Child4() {
342     Parent4.call(this)
343     this.type = 'Child4'
344 }
345 Child4.prototype = Parent4.prototype
346 var s4 = new Chiled4()
347 s4 instanceof Child4 === s4 instanceof Parent4 //True
348 console.log(s4.constructor) // Parent4
349 
350 
351 //5.组合继承优化2[最优]
352 function Parent5() {
353     this.name = 'Parent5'
354 }
355 function Child5() {
356     Parent5.call(this)
357     this.type = 'Child5'
358 }
359 Child5.prototype = Object.create(Parent5.prototype)
360 Child5.prototype.constructor = Chiled5()
361 //重写Child5的构造方法
362 B.prototype = Object.create(a.prototype)
363 B.prototype.constructor = A()
364 
365 var s5 = new Chiled5()  
366  
367 //js去重
368 function unique(arr) {
369     var res = []
370     var obj = {}
371     for(let i = 0; i<arr.length;i++){
372         if (!obj[arr[i]]) {
373             obj[arr[i]] = 1
374             res.push(arr[i])
375         }
376     }
377     return res
378 }
379 //闭包实现
380 function add(num){
381     function res() {
382         num ++
383         return num
384     }
385     return res
386 }
387 //防抖函数
388 const throttle = (func,wait = 50) => {
389     let lastTime = 0
390     return function(...args) {
391         let now = +new Date()
392         if(now - lastTime > wait){
393             lastTime = now
394             func.apply(this,args)
395         }
396     }
397 }
398 
399 const debounce = (func,wait = 50) => {
400     let timer = 0
401     return function(...args) {
402         if(timer)clearTimeout(timer)
403         timer = setTimeout(()=>{
404             func.apply(this,func)
405         },wait)
406     }
407 }
408 for (var i = 0; i < 5; i++) {
409     return function() {
410        setTimeout(console.log(i),1000411     }()
412 }
413 console.log(i);
414 
415 // 二叉树遍历[非递归]
416 function preordeTraversal(root) {
417     if(!root) return []
418     let stack = []
419     let res = []
420     while(root || stack.length > 0){
421         while(root) {
422             res.push(root.val)
423             stack.push(root)
424             root = root.left
425         }
426         if(stack.length > 0) {
427             root = stack.pop()
428             root = root.right
429         }
430     }
431     return res
432 }
433 // 递归版本
434 let res= []
435 function preordeTraversal2(root) {
436         if(root) {
437             res.push(root.val)
438             preordeTraversal2(root.left)
439             preordeTraversa2(root.val)
440         }
441 }
442 
443 
444 
445 判断是否有环
446 
447 int IsCross(ListNode *p, ListNode *q){
448         if(p == NULL || q == NULL){
449                 return 0;
450         }
451         ListNode *t = p;
452         while(t->next != NULL){
453                 t = t->next;
454         }
455         t->next = p;
456         ListNode *fast = q;
457         ListNode *slow = q;
458         while(fast != NULL && fast->next != NULL){
459                 fast = fast->next->next;
460                 slow = slow->next;
461                 if(fast == slow){
462                         break;
463                 }
464         }
465         if(fast != NULL && fast->next != NULL){
466                 return 1;
467         }else{
468                 return 0;
469         }

猜你喜欢

转载自www.cnblogs.com/NaN-prototype/p/12669738.html
今日推荐