1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        手撕前端面試代碼題大全

        共 14722字,需瀏覽 30分鐘

         ·

        2020-12-17 12:07

        關(guān)注?程序員成長(zhǎng)指北,回復(fù)“1

        加入我們一起學(xué)習(xí),天天進(jìn)步

        轉(zhuǎn)載自:等不到你. https://blog.csdn.net/weixin_43758603/article/details/109895826

        寫(xiě)在前面

        1. 最近我終于找到了一份滿意的工作.準(zhǔn)備面試的過(guò)程中,我整理出了一些有用的筆記,這篇就是其中之一.

          既然寫(xiě)好了,不妨就放在這里分享給大家.

        2. 面試通常都有現(xiàn)場(chǎng)寫(xiě)代碼的題目,我基本每次都或多或少的翻車(chē).有意思的是,每次面試結(jié)束,自己改不到五分鐘就調(diào)試出來(lái)了.

        3. 所以面試中的寫(xiě)代碼的過(guò)程,一定不能緊張,要沉住氣慢慢來(lái).只要不是系統(tǒng)自動(dòng)檢查結(jié)果,只要是面試官看著你寫(xiě),就有很大的表現(xiàn)的機(jī)會(huì),哪怕最后做不出來(lái).

          我參加的最煩人的面試,是那種系統(tǒng)判定結(jié)果的面試,只要做不出來(lái),就絕對(duì)不可能通過(guò).

        4. 仔細(xì)想想,在二三十場(chǎng)面試中,很少有我完整寫(xiě)出毫無(wú)瑕疵的答案的題目,但基本也都順利通過(guò)了.

          對(duì)比來(lái)看,我的同學(xué)中,答案能運(yùn)行成功但面試沒(méi)通過(guò)的也大有人在.

          可以肯定的是,面試官不會(huì)只根據(jù)是否能運(yùn)行成功來(lái)評(píng)價(jià)應(yīng)聘者.

          所以,只需要順著正確思路穩(wěn)穩(wěn)地做就好了,不要怕最后運(yùn)行不成功.

        5. 如果實(shí)在做不出,也一定要和面試官說(shuō)清你當(dāng)前的進(jìn)展和思路,而不是一句"我不會(huì)"就想結(jié)束問(wèn)題.

        6. 當(dāng)然,我指的只是前端這個(gè)對(duì)算法能力要求不強(qiáng)的崗位…

          有一場(chǎng)百度的面試我甚至直接和面試官說(shuō),我是個(gè)偏感性的人,喜歡但是不擅長(zhǎng)做算法.都給我通過(guò)了.

        7. 總的來(lái)看,如果能完全掌握這篇文章的內(nèi)容,就足以應(yīng)付所有前端面試中的手撕代碼環(huán)節(jié)了.

        8. 來(lái)都來(lái)了,點(diǎn)個(gè)贊唄

        導(dǎo)讀

        關(guān)于這篇文章,有幾點(diǎn)我想先說(shuō)清楚,方便讀者更順利的學(xué)習(xí).

        • 這篇文章不適合前端小白閱讀,需要對(duì)JSES6有一定了解,否則遇到一些寫(xiě)法可能不太看得懂

        • 因?yàn)榫τ邢?我只加了較為粗略但足以幫助讀者理解的注釋,因?yàn)槎鄶?shù)題也只有幾行代碼而已.

          如果遇到還不懂的地方,我認(rèn)為讀者完全可以自己去查詢文檔來(lái)了解為什么這么做,為什么使用這個(gè)函數(shù).

          或者,先查詢?cè)搯?wèn)題通常的解決思路,再回來(lái)參考我的實(shí)現(xiàn)

        • 代碼大量使用了ES6的語(yǔ)法

        • 學(xué)習(xí)手撕代碼,不只是理解的過(guò)程,更是實(shí)踐的過(guò)程

          我在完全掌握(可以默寫(xiě)出每段代碼,并講清楚每一行的作用)以下代碼的過(guò)程中,做了以下幾件事

          • 參考別人的實(shí)現(xiàn),結(jié)合自己的思路,寫(xiě)出一個(gè)自己的版本

          • 不斷對(duì)代碼進(jìn)行優(yōu)化

            當(dāng)你嘗試去優(yōu)化一段代碼的時(shí)候,對(duì)它的理解和記憶會(huì)異常深刻

          • 不看之前的實(shí)現(xiàn),重新自己實(shí)現(xiàn)一次

            再和之前的實(shí)現(xiàn)做對(duì)比,檢查錯(cuò)誤

          • 反復(fù)閱讀和默寫(xiě),直到可以完全正確的默寫(xiě)為之

        • 作為一個(gè)專(zhuān)業(yè)的程序員,除了工作中的編碼,額外的無(wú)實(shí)際產(chǎn)出的練習(xí)(反復(fù)練習(xí)解決一個(gè)問(wèn)題,反復(fù)默寫(xiě)同一段代碼),也是必不可少的.

          這就像歌手不可能到了舞臺(tái)上才去練習(xí)自己的聲音.他一定會(huì)在平時(shí)大量去練聲.

          這就是我強(qiáng)調(diào)要反復(fù)敲代碼的原因.別想著平時(shí)只要理解,工作中再去熟能生巧.

          工作不是給你練習(xí)的地方,工作是你的舞臺(tái).

        • 下文中幾乎每一段代碼,都是我反復(fù)優(yōu)化后的結(jié)果,希望可以帶給讀者新的啟發(fā).

        • 我把代碼大致分成了幾個(gè)專(zhuān)題,一共包含了大致30個(gè)問(wèn)題的解決方案

        • 除了文章中的問(wèn)題,還有些我沒(méi)有提到的,都是頻率較低的問(wèn)題

          關(guān)于算法題,除了排序和查找我也基本沒(méi)有寫(xiě).因?yàn)樗惴▎?wèn)題千變?nèi)f化,需要的是解決問(wèn)題的思維,而不是固定的實(shí)現(xiàn)

        • 重要性與順序無(wú)關(guān)

        • 有問(wèn)題可以問(wèn)我,我都會(huì)回復(fù)

        目錄

        DOM

        • 事件代理

        數(shù)組 對(duì)象

        • 扁平化
        • 去重 - unique()
        • 拷貝
          • 淺拷貝
          • 深拷貝(copy()函數(shù)實(shí)現(xiàn)、JSON.stringify

        字符串

        • 去除空格 - trim()
        • 字符串全排列
          • 廣度優(yōu)先實(shí)現(xiàn)
          • 深度優(yōu)先實(shí)現(xiàn)

        排序和查找

        • 插入排序
        • 歸并排序
        • 快速排序
        • 二分查找
        • 找出出現(xiàn)次數(shù)最多的元素 - getMostItem()

        功能函數(shù)實(shí)現(xiàn)

        • setTimeout實(shí)現(xiàn)setInterval
        • 函數(shù)柯里化
        • 防抖 節(jié)流

        數(shù)據(jù)結(jié)構(gòu)

        • 單鏈表

        設(shè)計(jì)模式

        • 發(fā)布訂閱模式

        JS原生API實(shí)現(xiàn)

        • bind() call() apply()
        • InstanceOf
        • new
        • reduce() forEach()
        • Promise

        HTTP請(qǐng)求

        • AJAX封裝
        • JSONP

        DOM

        事件代理

        document.getElementById("father-id").onclick=function(event){
        ????event=event||window.event
        ????let?target=event.target||event.srcElement
        ????//可以自己打印一下event.target.nodeName,看看是什么
        ????if?(target.nodeName.toLowerCase()==='xxx'){
        ????????//事件內(nèi)容
        ????}
        }

        數(shù)組 對(duì)象

        扁平化

        function?flatten(arr)?{
        ?let?result=[]
        ?for?(let?i=0,len=arr.length;i??if?(Array.isArray(arr[i]))?{
        ???result=result.concat(flatten(arr[i]))
        ??}?else?{
        ???result.push(arr[i])
        ??}
        ?}
        ?return?result
        }

        去重 - unique()

        function?unique(arr)?{
        ????let?appeard=new?Set()
        ????return?arr.filter(item=>{
        ????????//創(chuàng)建一個(gè)可以唯一標(biāo)識(shí)對(duì)象的字符串id
        ????????let?id=item+JSON.stringify(item)
        ????????if?(appeard.has(id))?{
        ????????????return?false
        ????????}?else?{
        ????????????appeard.add(id)
        ????????????return?true
        ????????}
        ????})
        }

        拷貝

        淺拷貝

        function?copy(obj)?{
        ?let?result=Array.isArray(obj)?[]:{}
        ?Object.keys(obj).forEach(key=>result[key]=obj[key])
        ?return?result
        }
        otherStar={...star}
        Object.assign({},star)

        深拷貝

        copy()函數(shù)實(shí)現(xiàn)

        處理了循環(huán)引用key為symbol類(lèi)型的情況

        function?copy(obj,appeard=new?Map())?{
        ?if?(!(obj?instanceof?Object))?return?obj//如果是原始數(shù)據(jù)類(lèi)型
        ????if?(appeard.has(obj))?return?appeard.get(obj)//如果已經(jīng)出現(xiàn)過(guò)

        ????let?result=Array.isArray(obj)?[]:{}
        ????appeard.set(obj,result)//將新對(duì)象放入map

        ????//遍歷所有屬性進(jìn)行遞歸拷貝
        ????;[...Object.keys(obj),...Object.getOwnPropertySymbols(obj)]
        ?????.forEach(key=>result[key]=copy(obj[key],appeard))

        ????return?result
        }
        JSON.stringify
        • 只能處理純JSON數(shù)據(jù)
        • 有幾種情況會(huì)發(fā)生錯(cuò)誤
        • 包含不能轉(zhuǎn)成 JSON 格式的數(shù)據(jù)
        • 循環(huán)引用
        • undefined,NaN, -Infinity, Infinity 都會(huì)被轉(zhuǎn)化成null
        • RegExp/函數(shù)不會(huì)拷貝
        • new Date()會(huì)被轉(zhuǎn)成字符串
        new=JSON.parse(JSON.stringify(old))

        字符串

        去除空格 - trim()

        function?myTrim(str)?{
        ?return?str.replace(/(^\s+)|(\s+$)/g,'')//將前空格和后空格替換為空
        }
        function?myTrim(str)?{//記錄前后空格的個(gè)數(shù),最后對(duì)字符串進(jìn)行截取
        ?let?first=0,last=str.length
        ?for?(let?i?in?str)?{
        ??if?(str[i]==='?')?{
        ???first++
        ??}?else?{
        ???break
        ??}
        ?}
        ?for?(let?i=last;i>first;i--)?{
        ??if?(str[i]==='?')?{
        ???last--
        ??}?else?{
        ???break
        ??}
        ?}
        ?return?str.substr(first,last-first)
        }

        字符串全排列

        廣度優(yōu)先實(shí)現(xiàn)

        function?combine(str)?{//抽出一個(gè)字符s,對(duì)其余的進(jìn)行排列,將s放在每種排列開(kāi)頭
        ?if?(str.length===1)?return?[str]
        ?let?results=[]
        ?for?(let?i?in?str)?{
        ??for?(let?s?of?combine(str.slice(0,i)+str.slice(1+(+i))))?{
        ???results.push(str[i]+s)
        ??}
        ?}
        ????//可能會(huì)出現(xiàn)類(lèi)似"aa"=>[aa,aa,aa,aa]的情況,需要去重
        ?return?[...new?Set(results)]
        }

        深度優(yōu)先實(shí)現(xiàn)

        function?combine(str)?{//記錄已經(jīng)使用過(guò)的字符,深度優(yōu)先訪問(wèn)所有方案
        ?let?result=[]
        ?;(function?_combine(str,path=''){
        ??if?(str.length===0)?return?result.push(path)
        ??for?(let?i?in?str)?{
        ???_combine(str.slice(0,i)+str.slice((+i)+1,str.length),path+str[i])
        ??}
        ?})(str)
        ????//可能會(huì)出現(xiàn)類(lèi)似"aa"=>[aa,aa,aa,aa]的情況,需要去重
        ?return?[...new?Set(result)]
        }

        排序和查找

        插入排序

        function?sort(arr)?{//原地
        ?for?(let?i?in?arr)?{//選一個(gè)元素
        ??while?(i>0&&arr[i]-1])?{//向前移動(dòng)到合適的位置
        ???[arr[i],arr[i-1]]=[arr[i-1],arr[i]]
        ???i--
        ??}
        ?}
        }

        歸并排序

        function?sort(arr)?{
        ?if?(arr.length===1)?return?arr

        ?//分成兩部分
        ?let?mid=Math.floor(arr.length/2)
        ?let?[part1,part2]=[sort(arr.slice(0,mid)),sort(arr.slice(mid))]

        ?//對(duì)比+合并
        ?let?result=[]
        ?while?(part1.length>0&&part2.length>0)
        ??result.push((part1[0]0]?part1:part2).shift())
        ?return?[...result,...part1,...part2]
        }

        快速排序

        function?sort(arr)?{
        ?if?(arr.length<=1)?return?arr

        ????//選基準(zhǔn)值
        ?let?mid_pos=arr.length>>1
        ?let?mid=arr.splice(mid_pos,1)[0]

        ?let?left=[],right=[]

        ????//和基準(zhǔn)值比較,分別插入left,right數(shù)組
        ?arr.forEach(item=>(item<=mid?left:right).push(item))

        ?return?[...sort(left),mid,...sort(right)]//遞歸調(diào)用排序
        }

        二分查找

        function?search(arr,target)?{//循環(huán)寫(xiě)法,不斷移動(dòng)左右指針,縮小范圍
        ?let?left=0,right=arr.length-1

        ?while?(left<=right)?{
        ??const?mid_pos=Math.floor((left+right)/2)
        ??const?mid_val=arr[mid_pos]

        ??if?(target===mid_val)?{
        ???return?mid_pos
        ??}?else?if?(target>mid_val)?{
        ???left=mid_pos+1
        ??}?else?{
        ???right=mid_pos-1
        ??}
        ?}
        ?return?-1
        }

        找出出現(xiàn)次數(shù)最多的元素 - getMostItem()

        function?getMost(arr)?{
        ?//計(jì)數(shù)
        ?let?map=new?Map()
        ?arr.forEach(item=>{
        ??if?(map.has(item))?{
        ???map.set(item,map.get(item)+1)
        ??}?else?{
        ???map.set(item,1)
        ??}
        ?})

        ?//找出出現(xiàn)最多
        ?let?[max_vals,max_num]=[[arr[0]],map.get(arr[0])]
        ?map.forEach((count,item)=>{
        ??if?(count>max_num){
        ???max_vals=[item]
        ???max_num=count
        ??}?else?{
        ???max_vals.push(item)
        ??}?
        ?})
        ?return?max_vals
        }

        console.log(getMost(['1',?'2',?'3',?'3',?'55',?'3',?'55',?'55']))

        功能函數(shù)實(shí)現(xiàn)

        setTimeout實(shí)現(xiàn)setInterval

        function?myInterval(fn,interval,...args)?{
        ?let?context=this
        ?setTimeout(()=>{
        ??fn.apply(context,args)
        ??myInterval(fn,interval,...args)//別忘了為它傳入?yún)?shù)
        ?},interval)
        }


        myInterval((num)=>console.log(num),500,10)

        函數(shù)柯里化

        function?sum(...args1){
        ????return?function?(...args2)?{
        ????????return?[...args1,...args2].reduce((p,n)=>p+n)
        ????}
        }
        console.log(sum(1,?2,?2)(7))

        防抖 節(jié)流

        實(shí)現(xiàn)了兩個(gè)加工方法,返回一個(gè)加工后的防抖/節(jié)流函數(shù)

        防抖

        function?debounce(fn,delay)?{
        ?let?timer=null
        ?return?function?(){
        ??if?(timer)?clearTimeout(timer)
        ??timer=setTimeout(()=>fn.call(...arguments),delay)//別忘了為它傳入?yún)?shù)
        ?}
        }

        節(jié)流

        function?throttle(fn,delay)?{
        ?let?flag=true
        ?return?function()?{
        ??if?(!flag)?return

        ??flag=false
        ??setTimeout(()=>{
        ???fn(...arguments)//別忘了為它傳入?yún)?shù)
        ???flag=true
        ??},delay)
        ?}
        }

        數(shù)據(jù)結(jié)構(gòu)

        單鏈表

        function?Node(element)?{//結(jié)點(diǎn)類(lèi)
        ?[this.element,this.next]=[element,null]
        }

        class?LinkList?{//鏈表類(lèi)
        ?constructor()?{
        ??this.length=0
        ??this.head=new?Node()
        ??this.tail=new?Node()
        ??this.head.next=this.tail
        ?}
        ?get_all()?{
        ??let?result=[]
        ??let?now=this.head
        ??while?(now.next!==this.tail)?{
        ???now=now.next
        ???result.push(now.element)
        ??}
        ??return?result
        ?}
        ?unshift(element)?{//開(kāi)頭添加
        ??let?node=new?Node(element)
        ??node.next=this.head.next
        ??this.head.next=node
        ?}
        ?shift(){//開(kāi)頭刪除
        ??let?node=this.head.next
        ??this.head.next=this.head.next.next
        ??return?node.element
        ?}
        }
        let?list=new?LinkList()
        list.unshift(15)
        list.unshift(16)
        list.unshift(17)
        console.log(list.shift())//17
        console.log(list.get_all())//[?16,?15?]

        設(shè)計(jì)模式

        發(fā)布訂閱模式

        class?Observer?{
        ?constructor()?{
        ??this.events={}//事件中心
        ?}
        ?publish(eventName,...args)?{//發(fā)布=>調(diào)用事件中心中對(duì)應(yīng)的函數(shù)
        ??if?(this.events[eventName])
        ???this.events[eventName].forEach(cb=>cb.apply(this,args))
        ?}
        ?subscribe(eventName,callback)?{//訂閱=>向事件中心中添加事件
        ??if?(this.events[eventName])?{
        ???this.events[eventName].push(callback)
        ??}?else?{
        ???this.events[eventName]=[callback]
        ??}
        ?}
        ?unSubscribe(eventName,callback)?{//取消訂閱
        ??if?(events[eventName])
        ???events[eventName]=events[eventName].filter(cb=>cb!==callback)
        ?}
        }

        JS原生API實(shí)現(xiàn)

        bind() call() apply()

        apply()

        Function.prototype.myApply=function(context,args)?{
        ?context.fn=this//為context設(shè)置函數(shù)屬性
        ?let?result=context.fn(...args)//調(diào)用函數(shù)
        ?delete?context.fn//刪除context的函數(shù)屬性
        ?return?result
        }

        call()

        //除了...args
        //和apply都一樣
        Function.prototype.myCall=function(context,...args)?{
        ?context.fn=this
        ?let?result=context.fn(...args)
        ?delete?context.fn
        ?return?result
        }

        bind()

        Function.prototype.myBind=function(context,args1)?{//使用[閉包+apply]實(shí)現(xiàn)
        ?return?(...args2)=>this.apply(context,[...args1,...args2]);
        }

        InstanceOf

        function?myInstanceOf(son,father)?{//沿著父親的原型鏈向上查找是否有兒子的原型
        ?while?(true)?{
        ??son=son.__proto__
        ??if?(!son)?return?false
        ??if?(son===father.prototype)?return?true
        ?}
        }

        myInstanceOf([],?Array)??//?true

        new

        function?myNew(constructor_fn,...args)?{
        ?//構(gòu)造新的空對(duì)象
        ?let?new_obj={}
        ?new_obj.__proto__=constructor_fn.prototype

        ?let?result=constructor_fn.apply(new_obj,args)
        ?//如果構(gòu)造函數(shù)沒(méi)有返回一個(gè)對(duì)象,則返回新創(chuàng)建的對(duì)象
        ?//如果構(gòu)造函數(shù)返回了一個(gè)對(duì)象,則返回那個(gè)對(duì)象
        ?//如果構(gòu)造函數(shù)返回原始值,則當(dāng)作沒(méi)有返回對(duì)象
        ?return?result?instanceof?Object?result:new_obj
        }



        function?Animal(name)?{
        ??this.name?=?name;
        }

        let?animal?=?myNew(Animal,?'dog');
        console.log(animal.name)??//?dog

        reduce() forEach()

        reduce()

        api用法:

        arr.reduce(function(prev,?cur,?index,?arr){},?initialValue)

        實(shí)現(xiàn):

        Array.prototype.myReduce=function(fn,init_val){
        ?let?[val,idx]=init_val?[init_val,0]:[this[0],1]//設(shè)置初始值
        ?for?(let?i=idx,len=this.length;i??val=fn(val,this[i],i,this)//循環(huán)并迭代結(jié)果
        ?}
        ?return?val
        }

        console.log([1,2,3,4,5].reduce((pre,item)=>pre+item,0))?//?15

        forEach()

        api用法:

        [1,3,5,7,9].myForEach(function(item,index,arr)?{
        ????console.log(this)
        },15)

        實(shí)現(xiàn):

        Array.prototype.myForEach=function(fn,temp_this)?{
        ????for?(let?i=0,len=this.length;i????????fn.call(temp_this,this[i],i,this)//循環(huán)數(shù)組元素,為回調(diào)函數(shù)傳入?yún)?shù)
        ????}
        }

        Promise

        Promise.all()

        Promise.prototype.all=function(promiseList)?{
        ????return?new?Promise((resolve,reject)=>{
        ????????if?(promiseList.length===0)?return?resolve([])
        ????????let?result=[],count=0

        ????????promiseList.forEach((promise,index)=>{
        ????????????Promise.resolve(promise).then(value=>{
        ????????????????result[index]=value
        ????????????????if?(++count===promiseList.length)?resolve(result)
        ????????????},reason=>reject(reason))
        ????????})
        ????})
        }

        ES6所有API完整實(shí)現(xiàn)

        通過(guò)Promise/A+ test測(cè)試

        實(shí)現(xiàn)細(xì)節(jié)過(guò)多,還請(qǐng)參照Promise/A+規(guī)范閱讀

        也可以直接參考我關(guān)于promise的筆記

        深入理解promise

        https://blog.csdn.net/weixin_43758603/article/details/109641486

        class?Promise?{
        ?constructor(task)?{
        ??this.status="pending"
        ??this.value=undefined
        ??this.reason=undefined
        ??this.fulfilled_callbacks=[]
        ??this.rejected_callbacks=[]

        ??try?{
        ???task(this._resolve,this._reject)
        ??}?catch?(error)?{
        ???this._reject(error)
        ??}
        ?}
        ?then(onFulfilled,onRejected){
        ??if?(this.status==='fulfilled')?{
        ???let?promise2=new?Promise((resolve,reject)=>{
        ????setTimeout(()=>{
        ?????try?{
        ??????if?(!this._isFunction(onFulfilled))?{
        ???????resolve(this.value)
        ??????}?else?{
        ???????this._resolvePromise(promise2,onFulfilled(this.value))
        ??????}
        ?????}?catch?(error)?{
        ??????reject(error)
        ?????}
        ????},0)
        ???})
        ???return?promise2
        ??}?else?if?(this.status==='rejected')?{
        ???let?promise2=new?Promise((resolve,reject)=>{
        ????setTimeout(()=>{
        ?????try?{
        ??????if?(!this._isFunction(onRejected))?{
        ???????reject(this.reason)
        ??????}?else?{
        ???????this._resolvePromise(promise2,onRejected(this.reason))
        ??????}
        ?????}?catch?(error)?{
        ??????reject(error)
        ?????}
        ????},0)
        ???})
        ???return?promise2
        ??}?else?if?(this.status==='pending')??{
        ???let?promise2=new?Promise((resolve,reject)=>{
        ????this.fulfilled_callbacks.push(()=>{
        ?????try?{
        ??????if?(!this._isFunction(onFulfilled))?{
        ???????resolve(this.value)
        ??????}?else?{
        ???????this._resolvePromise(promise2,onFulfilled(this.value))
        ??????}
        ?????}?catch?(error)?{
        ??????reject(error)
        ?????}
        ????})
        ????this.rejected_callbacks.push(()=>{
        ?????try?{
        ??????if?(!this._isFunction(onRejected))?{
        ???????reject(this.reason)
        ??????}?else?{
        ???????this._resolvePromise(promise2,onRejected(this.reason))
        ??????}
        ?????}?catch?(error)?{
        ??????reject(error)
        ?????}
        ????})
        ???})
        ???return?promise2
        ??}
        ?}
        ?catch=onRejected=>this.then(null,onRejected)

        ?finally=onFinished=>this.then(onFinished,onFinished)

        ?static?deferred(){
        ??let?deferred={}
        ??deferred.promise=new?Promise((resolve,reject)=>{
        ???deferred.resolve=resolve
        ???deferred.reject=reject
        ??})
        ??return?deferred
        ?}
        ?static?resolve(value)?{
        ??if?(value?instanceof?Promise)?return?value
        ??return?new?Promise(resolve=>resolve(value))
        ?}
        ?static?reject=reason=>{return?new?Promise((resolve,?reject)=>reject(reason))}

        ?static?all(promiseList)?{
        ??return?new?Promise((resolve,reject)=>{
        ???if?(promiseList.length===0)?return?resolve([])
        ???let?result=[],count=0

        ???promiseList.forEach((promise,index)=>{
        ????Promise.resolve(promise).then(value=>{
        ?????result[index]=value
        ?????if?(++count===promiseList.length)?resolve(result)
        ????},reason=>reject(reason))
        ???})
        ??})
        ?}
        ?static?race(promiseList)?{
        ??return?new?Promise((resolve,reject)=>{
        ???if?(promiseList.length===0)?return?resolve()
        ???promiseList.forEach(promise=>{
        ????Promise.resolve(promise)
        ?????.then(value=>resolve(value),reason=>reject(reason))
        ???})
        ??})
        ?}
        ?static?allSettled(promiseList)?{
        ??return?new?Promise(resolve=>{
        ???let?result=[],count=0
        ???if?(len===0)?return?resolve(result)

        ???promiseList.forEach((promise,i)=>{
        ????Promise.resolve(promise).then(value=>{
        ?????result[i]={
        ??????status:'fulfilled',
        ??????value:value
        ?????}
        ?????if?(++count===promiseList.length)?resolve(result)
        ????},reason=>{
        ?????result[i]={
        ??????status:'rejected',
        ??????reason:reason
        ?????}
        ?????if?(++count===promiseList.length)?resolve(result)
        ????})
        ???})
        ??})
        ?}
        ?_resolve=value=>{
        ??if?(this.status!=='pending')?return
        ??setTimeout(()=>{
        ???this.status?='fulfilled'
        ???this.value?=?value
        ???this.fulfilled_callbacks.forEach(cb=>cb(this.value))
        ??},0)
        ?}
        ?_reject=reason=>{
        ??if?(this.status!=='pending')?return
        ??setTimeout(()=>{
        ???this.reason?=?reason
        ???this.status?='rejected'
        ???this.rejected_callbacks.forEach(cb=>cb(this.reason))
        ??},0)
        ?}
        ?_isFunction=f=>Object.prototype.toString.call(f).toLocaleLowerCase()==='[object?function]'
        ?
        ?_isObject=o=>Object.prototype.toString.call(o).toLocaleLowerCase()==='[object?object]'

        ?_resolvePromise(promise,x){
        ??if?(promise===x)?{
        ??????promise._reject(new?TypeError('cant?be?the?same'))
        ??????return
        ??}
        ??if?(x?instanceof?Promise)?{
        ???if?(x.status==='fulfilled')?{
        ????promise._resolve(x.value)
        ???}?else?if?(x.status==='rejected')?{
        ????promise._reject(x.reason)
        ???}?else?if?(x.status==='pending')?{
        ????x.then(value=>{
        ?????this._resolvePromise(promise,value)
        ????},reason=>{
        ?????promise._reject(reason)
        ????})
        ???}
        ???return
        ??}
        ??if?(this._isObject(x)||this._isFunction(x))?{
        ???let?then
        ???try?{
        ????then=x.then
        ???}?catch?(error)?{
        ????promise._reject(error)
        ????return
        ???}
        ???if?(this._isFunction(then))?{
        ????let?called=false
        ????try?{
        ?????then.call(x,value=>{
        ??????if?(called)?return
        ??????called=true
        ??????this._resolvePromise(promise,value)
        ?????},reason=>{
        ??????if?(called)?return
        ??????called=true
        ??????promise._reject(reason)
        ?????})
        ????}?catch?(error)?{
        ?????if?(called)?return
        ?????promise._reject(error)
        ????}
        ???}?else?{
        ????promise._resolve(x)
        ???}
        ??}?else?{
        ???promise._resolve(x)
        ??}
        ?}
        }
        module.exports?=?Promise

        HTTP請(qǐng)求

        AJAX封裝

        function?ajax(method,url,params,callback)?{
        ?//對(duì)參數(shù)進(jìn)行處理
        ?method=method.toUpperCase()
        ?let?post_params=null
        ?let?get_params=''
        ?
        ?if?(method==='GET')?{
        ??if?(typeof?params==='object')?{
        ???let?tempArr=[]
        ???for?(let?key?in?params)?{
        ????tempArr.push(`${key}=${params[key]}`)
        ???}
        ???params=tempArr.join('&')
        ??}
        ??get_params=`?${params}`
        ?}?else?{
        ??post_params=params
        ?}

        ?//發(fā)請(qǐng)求
        ?let?xhr=new?XMLHttpRequest()

        ?xhr.onreadystatechange=function(){
        ??if?(xhr.readyState!==4)?return
        ??callback(xhr.responseText)
        ?}

        ?xhr.open(method,url+get_params,false)
        ?if?(method==='POST')
        ??xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')

        ?xhr.send(post_params)?
        }

        ajax('get','https://www.baidu.com',{id:15},data=>console.log(data))

        JSONP

        function?jsonp(url,?params_obj,?callback)?{
        ?//創(chuàng)建一個(gè)供后端返回?cái)?shù)據(jù)調(diào)用的函數(shù)名
        ?let?funcName?=?'jsonp_'?+?Data.now()?+?Math.random().toString().substr(2,?5)

        ?//將參數(shù)拼接成字符串
        ?if?(typeof?params==='object')?{
        ??let?temp=[]
        ??for?(let?key?in?params)?{
        ???temp.push(`${key}=${params[key]}`)
        ??}
        ??params=temp.join('&')
        ?}

        ?//在html中插入
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

          <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            男人捅女人的鸡鸡 | 中文字幕精品一区二区三区精品 | 美女被草在线观看 | 又黄又爽又刺激的视频 | 四虎成人精品A片 | 午夜xxxx | 免费看黄的视频软件 | 日韩艹| 91黄色视频网站 | 一级黄色电影免费在线观看 |