zoukankan      html  css  js  c++  java
  • call apply bind sleep

    1.自己实现一个call
    1)利用对象的方式的形式改变this指针  funcion add;  add.call(temObj)
    只需要 在temObj对象临时添加一个方法即可
    Function.prototype.mycall2=function(context){
        context.fn=this;
        context.fn();
        Reflect.deleteProperty(context,'fn')
    }
    2)call还可以携带实参传入
    利用函数的arguments截取除了第一个即可
    Function.prototype.mycall2=function(context){
        var args=[];
        for(var i=1;i<arguments.length;i++){
            args.push('arguments['+i+']')
        };
        debugger
        context.fn=this;
        context.fn(args);  //但是args是一个类数组
        Reflect.deleteProperty(context,'fn')
    }
    3)实现拆解函数的参数
    将args这个类数组拆解为(args[0],args[1],....) Es6可以用扩展运算符
    也可以用new Function
    var result = new Function('context', 'arguments', 'context.fn(' + args + ')')(context, arguments)
    Es3可以利用eval语法,eval中,args 自动调用 args.toString()方法;而数组中的toString的效果就是[].join(',')
    var temArr=[1,2,3];
    temArr.toString(); //1,2,3
    temArr.join() //1,2,3
    temArr.join=temArr.shift
    temArr.toString()  //1
    最终效果  context.fn(arguments[1], arguments[2], ...);
    Function.prototype.mycall2=function(context){
        var args=[];
        for(var i=1;i<arguments.length;i++){
            args.push('arguments['+i+']')
        };
        context.fn=this;
        //context.fn(args);
        eval('context.fn('+args+')')
        Reflect.deleteProperty(context,'fn')
    }

      function test(x,y){
        debugger;
        return console.log(x+y+this.name)
      }

      var temObj={name:'penguin'}

      test.mycall2(temObj,1,2)

    4)实现当传null时候this指向window;还有有返回值
    Function.prototype.mycall2=function(context){
        var context = context || window;
        var args=[];
        for(var i=1;i<arguments.length;i++){
            args.push('arguments['+i+']')
        };
        context.fn=this;
        var result=eval('context.fn('+args+')')
        Reflect.deleteProperty(context,'fn')
        return result
    }

    参考:https://github.com/mqyqingfeng/Blog/issues/11

    实现一个apply
    Function.prototype.myApply=function(context,arr){
        var context=context||window;
        context.fn=this;
        var args=[],result;

        for (var i = 0, len = arr.length; i < len; i++) {
          args.push('arr[' + i + ']');
        }

      if(!arr){
            result=context.fn()
        }else{
            result=eval('context.fn('+args+')');
        }
        return result;
    }
    1.自己实现一个bind函数
    原理:通过apply或者call方法来实现。
    (1)初始版本
    Function.prototype.bind=function(obj,arg){
      var arg=Array.prototype.slice.call(arguments,1);
      var context=this;
      return function(newArg){
        arg=arg.concat(Array.prototype.slice.call(newArg));
        return context.apply(obj,arg);
      }
    }
    
    (2) 考虑到原型链
    为什么要考虑?因为在new 一个bind过生成的新函数的时候,必须的条件是要继承原函数的原型
    Function.prototype.bind=function(obj,arg){
      var arg=Array.prototype.slice.call(arguments,1);
      var context=this;
      var bound=function(newArg){
        arg=arg.concat(Array.prototype.slice.call(newArg));
        return context.apply(obj,arg);
      }
      var F=function(){}
      //这里需要一个寄生组合继承
      F.prototype=context.prototype;
      bound.prototype=new F();
      return bound;
    }
    如何实现sleep的效果(es5或者es6)
    (1)while循环的方式
    function sleep(ms){
       var start=Date.now(),expire=start+ms;
       while(Date.now()<expire);
       console.log('1111');
       return;
    }
    
    执行sleep(1000)之后,休眠了1000ms之后输出了1111。上述循环的方式缺点很明显,容易造成死循环。
    (2)通过promise来实现
    function sleep(ms){
      var temple=new Promise(
      (resolve)=>{
      console.log(111);setTimeout(resolve,ms)
      });
      return temple
    }
    sleep(500).then(function(){
       //console.log(222)
    })
    //先输出了111,延迟500ms后输出222
    
    (3)通过async封装
    function sleep(ms){
      return new Promise((resolve)=>setTimeout(resolve,ms));
    }
    async function test(){
      var temple=await sleep(1000);
      console.log(1111)
      return temple
    }
    test();
    //延迟1000ms输出了1111
    
    ####(4).通过generate来实现
    function* sleep(ms){
       yield new Promise(function(resolve,reject){
                 console.log(111);
                 setTimeout(resolve,ms);
            })  
    }
    sleep(500).next().value.then(function(){console.log(2222)})
    Function._proto_(getPrototypeOf)是什么?
    获取一个对象的原型,在chrome中可以通过__proto__的形式,或者在ES6中可以通过Object.getPrototypeOf的形式。
    那么Function.proto是什么么?也就是说Function由什么对象继承而来,我们来做如下判别。
    Function.__proto__==Object.prototype //false
    Function.__proto__==Function.prototype//true
    复制代码
    我们发现Function的原型也是Function。

    Function._proto_(getPrototypeOf)是什么?

    获取一个对象的原型,在chrome中可以通过__proto__的形式,或者在ES6中可以通过Object.getPrototypeOf的形式。

    那么Function.proto是什么么?也就是说Function由什么对象继承而来,我们来做如下判别。

    Function.__proto__==Object.prototype //false
    Function.__proto__==Function.prototype//true
    复制代码

    我们发现Function的原型也是Function。

  • 相关阅读:
    Halcon HWindowControl 控件中图像的缩放与移动
    OpenCV cv::mean()函数详解
    OpenCV 霍夫变换(Hough Transform)
    OpenCV 图像分割
    OpenCV 使用ROI进行图像切割
    OpenCV 轮廓查找与绘制-最小外接矩形
    OpenCV 提取轮廓的凸包、外包矩形、最小外包矩形、最小外包圆
    KubeDL 加入 CNCF Sandbox,加速 AI 产业云原生化
    DataWorks 功能实践速览
    coredump 瘦身风云
  • 原文地址:https://www.cnblogs.com/little-ab/p/11098845.html
Copyright © 2011-2022 走看看