手写bind函数:this、返回值是一个函数

this

与变量索值不同,this的值在执行上下文中

通常情况下,如果没有在方法后面添加 (),例如 onClick={this.handleClick},你应该为这个方法绑定 this。

函数可以关联至一个对象,这时称之为方法。对象被隐式传递给其所调用的方法,方法可以访问和操作对象里的数据,通过 this 关键字引用对象。
当函数作为对象的方法被调用时,this 指向该对象
普通函数调用,即普通函数方式,此时的 this 总是指向全局对象
构造器里的 this 就指向返回的对象

构造器调用的返回值

返回:对象本身:构造器无显性返回值,或者是返回一个非对象类型的数据

var MyClass = function(){ 
 this.name = 'sven'; 
}; 
var obj = new MyClass(); 
alert ( obj.name ); // 输出:sven指向new的对象
var MyClass = function(){ 
 this.name = 'sven' 
 return 'anne'; // 返回 string 类型
}; 
var obj = new MyClass(); 
alert ( obj.name ); // 输出:sven

构造器显式地返回了一个 object 类型的对象

var MyClass = function(){ 
 this.name = 'sven'; 
 return { // 显式地返回一个对象//花括号封装对象
 name: 'anne' 
 } 
}; 
var obj = new MyClass(); 
alert ( obj.name ); // 输出:anne 

在这里插入图片描述

返回值是一个函数

func执行结束后返回一个part函数,再次()调用返回值,执行part函数。part函数返回自己,所以可以一直调用下去。

var func = function(x){
    var way = "func";
    var part = function(x){
        console.log("这里是函数的成员变量part");
        way = way +"+part";//没用var,全局变量诶
	return part;
    }//报错?还没有建立好
    
	part.toString = function(){
        return way;
    }//alert默认打印出函数体,修改为way的值
	
    console.log("这里是func");
    return part;
} 
alert(func(1)(2)(3)());//

运行结果
在这里插入图片描述

其次想到了之前的报错,对比这里并没有访问undefined的对象的属性,所以不报错
在这里插入图片描述

前提

bind 是 ES5 中新增的一个方法,可以改变函数内部的this指向,是ES6中箭头函数绑定this的基础。
大部分高级浏览器都实现了内置的 Function.prototype.bind,call、apply语法是bind的基础。
bind与call、apply区别于立即执行还是等待执行。

bind语法:
func.bind(thisArg[, arg1[, arg2[, …]]])
thisArg 当绑定函数被调用时,该参数会作为原函数运行时的this指向。当使用new 操作符调用绑定函数时,该参数无效。
arg1, arg2, … 当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。

注意,除了把函数绑定到对象上,bind方法还会将其他参数做绑定

let sum=(x,y)=>x+y;
let suc=sum.bind(null,1);//x=1
suc(2);//3

没有原生的 Function.prototype.bind 实现,我们也可自己写代码如下:
加入了一些输出来观察整个过程
在这里插入图片描述

var name="xxx";//全局的name
Function.prototype.bind = function( context ){ 
	 var self = this; // 保存原函数
	 console.log("2bind执行中");
	 return function(){ // 返回一个新的函数
		 //新函数的执行体为空,只有返回值
		 console.log("4执行bind返回的func");
		 return self.apply( context, arguments ); // 执行新的函数的时候,会把之前传入的 context 
		 // 当作新函数体内的 this 
	 } 
}; 
var obj = { 
 name: 'obj' 
}; 
console.log("1绑定前的全局name属性是"+ this.name ); 
var func = function(){ 
  console.log("5这里在执行 被绑定的函数"); 
  console.log( "6"+this.name ); // 输出:obj
}.bind( obj); 
console.log("3bind完毕,下面开始调用绑定的返回值"); 
func();

bind() 函数会创建一个新函数(称为绑定函数)作为返回值,不执行被调函数。新函数与被调函数(绑定函数的目标函数)具有相同的函数体,实质上新函数就是返回一个对被调函数实施apply。当新函数被调用的时候实质上执行了两个函数体:新函数(apply)+被调函数。

常见应用实例

调用函数和编写函数的时候格外注意this

<html> 
 <body> 
 <div id="div1">我是一个 div</div> 
 </body> 
 <script> 
 var getId = document.getElementById; 
 getId( 'div1' ); 
 </script> 
</html> 

抛出了一个异常。这是因为许多引擎的 document.getElementById 方法的内部实现中需要用到 this。这个 this 本来被期望指向document,当 getElementById 方法作为 document 对象的属性被调用时,方法内部的 this 确实是指向 document 的。但当用 getId 来引用 document.getElementById 之后,再调用 getId,此时就成了普通函数调用,函数内部的 this 指向了 window,而不是原来的 document。

可以尝试利用 apply 把 document 当作 this 传入 getId 函数,帮助“修正”this:

document.getElementById = (function( func ){ 
 return function(){ 
 return func.apply( document, arguments ); 
 } 
})( document.getElementById ); 
var getId = document.getElementById; 
var div = getId( 'div1' ); 
alert (div.id); // 输出: div1

div 节点的 onclick 事件
假如该事件函数中有一个内部函数 func,在事件内部调用 func 函数时,func 函数体内的 this就指向了 window,而不是我们预期的 div,见如下代码:

document.getElementById( 'div1' ).onclick = function(){ 
 alert( this.id ); // 输出:div1 
 var func = function(){ 
 alert ( this.id ); // 输出:undefined 
 } 
 func(); //func.call( this ); 修正 func 函数内的 this,使其依然指向 div:
}; 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值