博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

js 手写apply call bind

Posted on 2021-03-05 17:17  米粒3  阅读(97)  评论(0编辑  收藏  举报

手写call:

        Function.prototype.ownCall=function(newObj,...args){
            if(typeof newObj=='function'){
                throw new TypeError('type error');
            }

            let fn=Symbol('fn');//唯一值,保证不会覆盖函数原属性
            newObj=newObj||window //如果没有传入对象则绑定到window
            newObj[fn]=this//把函数绑定到传入对象的某个属性
            let result=newObj[fn](...args);//调用传入对象的参数返回结果
            delete newObj[fn] //删除函数声明
            return result;
        }

        function showName(){
           console.log(this.name);
        }
        var db={
           name:'zhangsan'
        }
        showName.ownCall(db);

手写apply(和call类似,只是传入参数类型不同:一个是逗号分割的字符串,一个是数组)

Function.prototype.ownApply=function(newObj,args){
     if(typeof newObj=='function'){
         throw new TypeError('type error');
    }

    //唯一值,防止属性覆盖
    let fn=Symbol('fn');
    //如果没有则赋值给window
    newObj=newObj||window;
    //把函数赋值到新对象的某个属性
    newObj[fn]=this
   //调用传入对象的参数返回对象
   let result=newObj[fn](...args);
   delete newObj[fn]
   return result;
};

function showName(){
   console.log(this.name);
}
let db={
   name:'lisi'
}
showName.apply(db);

 手写bind:

       //考虑返回的函数作为构造函数使用的情况,这是绑定函数中this指向构造函数自身,并且绑定函数原型也和构造函数原型相同
        Function.prototype.ownBind=function(newObj,...args){
            if(typeof newObj=='Function'){
                throw new TypeError('type error');
            }
            let _self=this
            function fnBound(){
               //如果绑定函数中this和构造函数this相同,则判定是new
               let _this=this instanceof _self?this:newObj
               //把绑定对象和传入参数传入原函数
               return _self.apply(_this,args.concat([].slice.apply(arguments,[0])))
            }
let fn=function(){}
if(this.prototype){ fn.prototype=this.prototype fn.prototype.constructor=this }
fnBound.prototype=new fn();
return fnBound; }

        function sum(name){
           this.name=name; 
        }
        let obj={}
        
        let output=sum.ownBind(obj);
        output('zhangsan');
        console.log(obj.name);
       
        let o=new output('lisi');
        console.log(obj.name);
        console.log(o.name);