<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          手撕前端面試代碼題大全

          共 14722字,需瀏覽 30分鐘

           ·

          2020-12-17 12:07

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

          加入我們一起學習,天天進步

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

          寫在前面

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

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

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

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

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

          4. 仔細想想,在二三十場面試中,很少有我完整寫出毫無瑕疵的答案的題目,但基本也都順利通過了.

            對比來看,我的同學中,答案能運行成功但面試沒通過的也大有人在.

            可以肯定的是,面試官不會只根據(jù)是否能運行成功來評價應(yīng)聘者.

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

          5. 如果實在做不出,也一定要和面試官說清你當前的進展和思路,而不是一句"我不會"就想結(jié)束問題.

          6. 當然,我指的只是前端這個對算法能力要求不強的崗位…

            有一場百度的面試我甚至直接和面試官說,我是個偏感性的人,喜歡但是不擅長做算法.都給我通過了.

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

          8. 來都來了,點個贊唄

          導讀

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

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

          • 因為精力有限,我只加了較為粗略但足以幫助讀者理解的注釋,因為多數(shù)題也只有幾行代碼而已.

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

            或者,先查詢該問題通常的解決思路,再回來參考我的實現(xiàn)

          • 代碼大量使用了ES6的語法

          • 學習手撕代碼,不只是理解的過程,更是實踐的過程

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

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

            • 不斷對代碼進行優(yōu)化

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

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

              再和之前的實現(xiàn)做對比,檢查錯誤

            • 反復閱讀和默寫,直到可以完全正確的默寫為之

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

            這就像歌手不可能到了舞臺上才去練習自己的聲音.他一定會在平時大量去練聲.

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

            工作不是給你練習的地方,工作是你的舞臺.

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

          • 我把代碼大致分成了幾個專題,一共包含了大致30個問題的解決方案

          • 除了文章中的問題,還有些我沒有提到的,都是頻率較低的問題

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

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

          • 有問題可以問我,我都會回復

          目錄

          DOM

          • 事件代理

          數(shù)組 對象

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

          字符串

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

          排序和查找

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

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

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

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

          • 單鏈表

          設(shè)計模式

          • 發(fā)布訂閱模式

          JS原生API實現(xiàn)

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

          HTTP請求

          • 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ù)組 對象

          扁平化

          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)建一個可以唯一標識對象的字符串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ù)實現(xiàn)

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

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

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

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

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

          字符串

          去除空格 - trim()

          function?myTrim(str)?{
          ?return?str.replace(/(^\s+)|(\s+$)/g,'')//將前空格和后空格替換為空
          }
          function?myTrim(str)?{//記錄前后空格的個數(shù),最后對字符串進行截取
          ?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)先實現(xiàn)

          function?combine(str)?{//抽出一個字符s,對其余的進行排列,將s放在每種排列開頭
          ?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)
          ??}
          ?}
          ????//可能會出現(xiàn)類似"aa"=>[aa,aa,aa,aa]的情況,需要去重
          ?return?[...new?Set(results)]
          }

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

          function?combine(str)?{//記錄已經(jīng)使用過的字符,深度優(yōu)先訪問所有方案
          ?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)
          ????//可能會出現(xiàn)類似"aa"=>[aa,aa,aa,aa]的情況,需要去重
          ?return?[...new?Set(result)]
          }

          排序和查找

          插入排序

          function?sort(arr)?{//原地
          ?for?(let?i?in?arr)?{//選一個元素
          ??while?(i>0&&arr[i]-1])?{//向前移動到合適的位置
          ???[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))]

          ?//對比+合并
          ?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

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

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

          ????//和基準值比較,分別插入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)寫法,不斷移動左右指針,縮小范圍
          ?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)?{
          ?//計數(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ù)實現(xiàn)

          setTimeout實現(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é)流

          實現(xiàn)了兩個加工方法,返回一個加工后的防抖/節(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é)點類
          ?[this.element,this.next]=[element,null]
          }

          class?LinkList?{//鏈表類
          ?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)?{//開頭添加
          ??let?node=new?Node(element)
          ??node.next=this.head.next
          ??this.head.next=node
          ?}
          ?shift(){//開頭刪除
          ??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è)計模式

          發(fā)布訂閱模式

          class?Observer?{
          ?constructor()?{
          ??this.events={}//事件中心
          ?}
          ?publish(eventName,...args)?{//發(fā)布=>調(diào)用事件中心中對應(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實現(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]實現(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)造新的空對象
          ?let?new_obj={}
          ?new_obj.__proto__=constructor_fn.prototype

          ?let?result=constructor_fn.apply(new_obj,args)
          ?//如果構(gòu)造函數(shù)沒有返回一個對象,則返回新創(chuàng)建的對象
          ?//如果構(gòu)造函數(shù)返回了一個對象,則返回那個對象
          ?//如果構(gòu)造函數(shù)返回原始值,則當作沒有返回對象
          ?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)

          實現(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)

          實現(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完整實現(xiàn)

          通過Promise/A+ test測試

          實現(xiàn)細節(jié)過多,還請參照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請求

          AJAX封裝

          function?ajax(method,url,params,callback)?{
          ?//對參數(shù)進行處理
          ?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ā)請求
          ?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)建一個供后端返回數(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中插入
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    影音先锋男人的资源 | 日逼黄片视频 | 俺去听听婷婷 | 91偷拍网| 成人国产精品秘 欧美高清 |