this

1.this引用的是函数执行的环境对象,this在代码执行过程中可能引用不同的对象,他实际最终指向的是那个调用它的对象。

​function a(){
    var user = "shisha";
    console.log(this.user); //undefined
    console.log(this); //Window}
a();

​

2.call,apply,bind

作用:改变this的指向

区别:它们的区别主要是在于方法的实现形式和参数传递上的不同

①:函数.call(在其中运行函数的作用域,传递给函数的参数(必须一一列举出来))

var foo={
	value:1
}
function bar(){
	console.log(this.value);
}
bar.call(foo)

js模拟实现call的方法,分为三步:

第一步:模拟添加属性方法

foo.fn=bar

第二步:调用方法

foo.fn()

第三步:删除方法

delete foo.fn

// es3模拟实现call

Function.prototype.callOne=function(context){
	//如果context是null,作用域是window
	context=context||window;
	//添加方法
	context.fn=this;
	var args=[];
	//如果直接把arguments[i]push给args,eval会先对args.toString,arguments[i]就会变成一个没有声明,会出错的变量
	for(var i=1;i<arguments.length;i++){
		args.push('arguments.push['+i+']');
	}
	var result=eval('context.fn('+args+')');
	delete context.fn;
	return result;
}
var foo={
	value:1
}
function bar(){
	console.log(this.value);
}
bar.callOne(foo)

②:函数.apply(在其中运行函数的作用域,参数数组(可以是Array实例也可以是arguments对象))

call和apply基本相同就是参数不同

// es3模拟实现apply

Function.prototype.callTwo=function(context,arr){
	context=context||window;
	arr=arr||[];
	context.fn=this;
	var args=[];
	for(var i=0;i<arr.length;i++){
		args.push('arr.push['+i+']');
	}
	var result=eval('context.fn('+args+')');
	delete context.fn;
	return result;
}
var foo={
	value:1
}
function bar(){
	console.log(this.value);
}
bar.callTwo(foo)

③:var ss=函数.bind(在其中运行函数的作用域,arg1,arg2,....)

https://blog.csdn.net/lisummit/article/details/80561786

b.bind(a)它是返回了一个被修饰的函数,bind() 之后函数并没有执行, 可以传给其他函数, 在某个适当的时机再调用,使用更加灵活。

// es3模拟实现bind

Function.prototype.bindOne=function(context){
	if(typeof this!=='function'){
		throw new Error('bound is not callable')
	}
	//留住this
	var self=this;
	//arguments转数组,并从index=1截取
	var args=Array.prototype.slice.call(arguments,1);
	var fNop=function (){};
	var fBound=function (){
		var boundArgs=Array.prototype.slice.call(arguments);
		return self.apply(this instanceof fNop?this:context,args.concat(boundArgs))
	}
	//原型链继承
	fNop.prototype=this.prototype;
	fBound.prototype=new fNop();
	return fBound;
}
var foo={
	value:1
}
function bar(){
	console.log(this.value);
}
var a=bar.bindOne(foo)
a();

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值