面试题—手写promise、jsonp、new等各种原理

1、手写promise

class MyPromise{
       constructor(fn){
           this.state = 'pending'
           this.value = undefined
           this.reason = undefined
           let resolve = value =>{
               if(this.state === 'pending'){
                   this.state = 'fulfilled';
                   this.value = value;
               }
           }
           let reject = value =>{
               if(this.state === 'pending'){
                   this.state = 'rejected';
                   this.reason = value;
               }
           }

           try{
               fn(resolve,reject)
           }catch(e){
               reject(e)
           }
       }

       then(onFulfilled,onRejected){
           switch (this.state){
               case 'fulfilled':
                   onFulfilled(this.value);
                   break;
               case 'rejected':
                   onRjeected(this.value);
                   break;
               default:
           }
       }
   }
//验证
   let pro = new MyPromise((resolve,reject)=>{
       setTimeout(()=>{
           resolve(123);
           console.log(pro);
       },3000)
   });

  console.log(pro);

2、手写jsonp原理

var $ = {
       ajax:function(options){
           var url = options.url;
           var dataType = options.dataType;

           var targetProtocol = '';
           var targetHost = '';

           // 判断是否为绝对路径
           if(url.indexOf('http://') == 0 && url.indexOf('https://') == 0){
               // 条件成立说明是绝对路径
               // 将用户传进来的地址(字符串)变成真正的url对象
               var targetUrl = new URL(url);
               targetProtocol = targetUrl.protocol;
               targetHost = targetHost.host;
           }else{
               // 否则是相对路径
               targetProtocol = location.protocol;  //返回地址对象的协议
               targetHost = location.host;   //返回地址对象的域名和端口号
           }

           // 如果请求方式不是jsonp
           if(dataType !== 'jsonp'){
               return;
           }

           // 判断是否为同域
           if(location.protocol == targetProtocol && location.host == targetProtocol){
               // 说明是同域,发送正常的ajax
           }else{
               // 不同源
               // 创建一个cb开头的函数名
               var callback = 'cb' + Math.floor(Math.random() * 10000000);
                    
               // 将生成的方法定义到window身上
               window[callback] = options.success;
               // 创建一个script标签
               var script = document.createElement('script');
               // 判断url中的参数
               if(url.indexOf('?') > 0){
                   // 说明有参数(有问号了)
                   script.src = url + '&callback=' + callback;
               }else{
                   // 此时用户传入的参数中没有?(问号)
                   script.src = url + '?callback=' + callback;
               }
               document.head.appendChild(script);
           }
       }
   }

3、手写new原理

//手写new原理
function createNew(){
    let obj = {};
    let constructor = [].shift.call(arguments);
    obj.__proto__ = constructor.prototype;
    let result = constructor.apply(obj,arguments);

    return typeof result === 'object'? result : obj; 
}

//测试
function People(name,age){
    this.name = name;
    this.age = age;
}

var peo = createNew(People,'张小宝',18);
console.log(peo);
console.log(peo.name);
console.log(peo.age);

4、手写call函数

// 实现一个call函数
   Function.prototype.mycall = function(context){
       if(typeof this !== 'function'){
           throw new TypeError('not function')
       }
       context = context || window
       context.fn = this
       let arg = [...arguments].slice(1);
       let result = context.fn(...arg);
       delete context.fn
       return result;
   }

   // 测试
   function Person(name,age){
       this.name = name;
       this.age = age;
   }
        
   function Son(name,age,sex,hobby){
       Person.mycall(this,name,age);
       this.sex = sex;
       this.hobby = hobby;
   }

    var son = new Son('康小杰',18,'男','编程');
    console.log(son);

5、实现apply函数

......

谢谢访问!

持续更新中…

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值