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 }