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),1000) 411 }() 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
今日推荐
周排行