• 【JavaScript】原生实现call bind apply


    回顾call apply bind用途

    let obj = {
    	name:"obj1"
    	say:function(){
    		//输出arguments
    		console.log(arguments);
    		console.log(this.name);
    	}
    	let obj2 = {
    		name:"obj2";
    	}
    	obj.say();
    	obj.say.call(obj2,1,2,3);
    	obj.say.apply(obj2,[1,2,3]);
    	sayClone = obj.bind(obj,1,2,3);
    	sayClone();
    }
    

    原生实现bind()

    bind的特点:

    1. 接受调用传参和新建对象构造函数传参
    2. 如果是外部没有传入this就要新建一个this
    3. 和call接受的参数和实现的回调功能一样
    4. 返回的是一个新创建的原来传入的this克隆的对象
    //函数的构造函数 : Function
    //用es6解构rest的方式传参
    Function.prototype.myBind = function(objThis,...params){
    	//定义指向当前函数this的指针
    	const thisTn = this;
    	//因为最终返回的是一个函数,所以声明一个函数返回
    	//用let表示块作用域
    	let funcForBind = function(...secondParams){
    		/*因为例如
    		let sayClone = obj.say.bind(obj2,1,2,3);
    		sayClone(4);
    		这里还是可以进行传参,最终传的就是1,2,3,4,所以可以用解构	...secondParams
    		*/
    		//判断是不是新创建的对象 如果新创建的对象的话 this就是当前函数的this 不是新创建的话就是传进来的那个对象的上下文
    		const isNew = this instanseof funcForBind;
    		const thisArg = isNew ? this : objThis;
    		//返回调用 并分别解构传入的参数params和创建对象传入的参数secondParams
    		return thisFn.call(thisArg,...params,...secondParams);
    	}
    	//因为bind返回的是克隆的对象,所以还要把原型链进行克隆
    	funForBind.prototype = Object.create(thisFn.prototype);
    	return funcForBind;
    }
    

    原生实现call()和apply()

    之前的例子:

    //给obj2增加一个obj的call的函数,然后用传入的参数进行调用返回最终值
    obj.say.call(obj2,1,2,3);
    
    Function.prototype.myCall = function(thisArg,...arr){
    	if(thisArg == null || thisArg == undefined){
    		thisArg = window;
    	}
    	//定义一个不重复的方法名称
    	const specialMethod = Symbol('anything');
    	//将这个不重复的方法Function的指针给thisArg的specialMethod方法
    	thisArg[specialMethod] = this;
    	//调用函数并结果返回
    	let result = thisArg[specialMethod](...arr);
    	//delete 新增的属性
    	delete thisArg[specialMethod];
    	return result;
    }
    obj.say.myCall(obj2,1,2,3);
    
    Function.prototype.myApply = function(thisArg,arr){
    	if(thisArg == null || thisArg == undefined){
    		thisArg = window;
    	}
    	//定义一个不重复的方法
    	const specialMethod = Symbol('anything');
    	//将这个不重复的方法的指针给thisArg的specialMethod方法
    	thisArg[specialMethod] = this;
    	//调用函数并结果返回
    	let result = thisArg[specialMethod](...arr);
    	//delete 新增的属性
    	delete thisArg[specialMethod];
    	return result;
    }
    obj.say.myApply(obj2,[1,2,3]);
    
  • 相关阅读:
    又一种Mysql报错注入
    PHP wget 增强脱裤脚本(PDO MYSQL)
    一种少见的跨目录写webshell方法
    过狗一句话
    在myql sqlserver里边怎么快速找到带有关键字的表
    php读取3389脚本
    学习OpenCV,看这些!
    Git 学习看这篇就够了!
    开发工具使用技巧和插件大总结
    (资源整理)带你入门Spark
  • 原文地址:https://www.cnblogs.com/SiriusZHT/p/14310756.html
Copyright © 2020-2023  润新知