改变this指向
改变this指向的三大方法
- call
立即执行
参数传递为单个传递
- apply
立即执行
参数传递为数组
- bind
不立即执行,会返回一个函数,调用时才执行
参数传递可单个传递,也可传递数组
举例说明
<script> window.color = "red" document.color = "yellow" var obj = { color: "salmon" } function changeColor(newColor1,newColor2) { console.log(this.color) console.log(newColor1) console.log(newColor2) } changeColor.call(obj,"pink","grey") //salmon pink grey changeColor.apply(obj,["pink","grey"]) //salmon pink grey var bindColor=changeColor.bind(obj,"pink","grey") //salmon pink grey bindColor() var bindColor2=changeColor.bind(obj,'blue') bindColor2('green','pink') //salmon blue green </script>
手写解析
- 手写call
var obj = { color: "salmon" } function changeColor(newColor1,newColor2) { return{ color:this.color, newColor1,newColor1, newColor2:newColor2 } } var newCall=function(objarg){ //this指向调用的方法changeCOlor //objarg指向传递进来的第一个参数,为想要改变的this指向,必须为一个对象 objarg=objarg||window objarg.func=this //改变this指向 console.log(arguments)//第一个参数为改变this指向,后续参数为传的参数 var arr=[] for(let i=1;i<arguments.length;i++){ const elem=arguments[i] arr.push(elem) } var res=objarg.func(...arr) delete(objarg.func)//不能改变原对象,所以进行删除 return res //call有返回值,最终需要返回 } Function.prototype.newCall=newCall //绑定到原型上,所有函数都可以调用 console.log("===",changeColor.newCall(obj,'red','blue')) //{color:'salmon',newColor1:'red',newColor2:'blue'}
- 手写call实现了,实现手写apply就只用修改传参方式不通的问题
//不用去分析获取到arr,直接解构arguments的第1项 var res=objarg.func(...arguments[1])
var newApply=function(objarg){ objarg=objarg||window objarg.func=this //改变this指向 var res=objarg.func(...arguments[1]) delete(objarg.func) return res }
- 手写bind 在其中可用到手写的newCall或newApply
var newBind=function(obj){ var _this=this var arr1=Array.prototype.slice.newCall(arguments,1) //在此可能或获取到一部分参数 var newFunc=function(){ // 在此也可获取到一部分参数 var arr2=Array.prototype.slice.newCall(arguments) var list=arr1.concat(arr2) if(this instanceof newFunc){ return _this.newApply(this,list)// 返回的函数可以作为构造函数使用,实现作为构造函数时,this就失效了 }else{ return _this.newApply(obj,list) } } return newFunc }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)