javaScript中this的用法

一、this定义


this是一个对象,在不同情况在指向不同的对象
当一个函数被调用的时候回产生一个对象(调用方式,调用地点,参数等等)
一般来说我们用this指向全局作用域或者局部作用域来代替当前使用的对象。
使用的用途主要有:
1,作为对象方法来调用
2,作为构造函数来调用
3.使用call或者apply改变this方向后调用

二、this指向

先上结论
1、对象调用this,调用那个对象this指向那个对象
2、没有定义就直接调用this函数 ,this指向全局作用域
3、通过new的方式调用时,this永远指向new的新对象。
4、箭头函数中的this,this指向定义函

对象调用

this对象调用比较简单,前面调用了那个对象,this就指向谁

数的继承上下文

var person ={
name:'十九'
age:‘22’
print:function(){
console.log(this)
console.log(this.nmae+‘:’+this.age)
}
}
person.print();
//this 指向的就是当前对象person

直接调用的函数

直接调用函数的时候this指向的是全局window函数

function print(){
cnsole.log(this);
}
print();
//this 指向全局作用域

通过new方式调用的函数


new方法调用的函数 this永远指向新创建的对象
function person(name,age){
this.name = name ;
this.age = age ;
console.log (this);
var shijiu = new person (‘十九’,22);
//this指向的就是新穿件的new函数
}

箭头函数中的this

箭头函数中的this要注意的没有单独的this值,箭头函数中的this与定义函数的上下文相同。

const person = {
a:() => {
console.log(this);
}
}
//对象调用箭头函数,
person.a();//this指向的是window

三、this指向改变

改变this指向有三种方法:
call
apply
bind

call

call中第一个参数是this指向,后面的参数是this的传参

function fn(x,y){
            console.log(this);  
        }
        var obj = {
            name:"pc"
        }
        fn(1,2);
        fn.call(obj,1,2);

apply

apply第一个参数是this指向,后面的参数用数组表示

function fn(x,y){
            console.log(this);  
        }
        var obj = {
            name:"pc"
        }
        fn(1,2);
        fn.apply(obj,[1,2]);

bind

bind只改变this指向,参数需要手动传递

function fn(x,y){
            console.log(this);  
        }
        var obj = {
            name:"zs"
        }
        fn(1,2);
        fn.bind(obj,1,2)();

三种方法相同点和不同点


共同点:
三者都能改变this指向,且第一个传递的参数都是this指向的对象,都是采用后续传参的形式
不同点:
call的传参是单个传递的,而apply传递的是数组,bind没有规定,单的参数和数组都可以。
call和apply的函数都是直接执行的,而bind函数会返回一个函数,调用的时候才会执行。

下面的内容是扩展内容:

手写call apply bind 源码
手写call


首先 context 为可选参数,如果不传的话默认上下文为 window ;
接下来给 context 创建一个 fn 属性,并将值设置为需要调用的函数;
因为 call 可以传入多个参数作为调用函数的参数,所以需要将参数剥离出来;
然后调用函数并将对象上的函数删除。

// this 为调用的函数 
// context 是参数对象 
Function.prototype.myCall = function(context){ 
	// 判断调用者是否为函数 
	if(typeof this !== 'function'){ 
		throw new TypeError('Error') 
}// 不传参默认为 window
 context = context || window 
 // 新增 fn 属性,将值设置为需要调用的函数
  context.fn = this
  // 将 arguments 转化为数组将 call 的传参提取出来 [...arguments]
  const args = Array.from(arguments).slice(1)
   // 传参调用函数 
   const result = context.fn(...args)
   // 删除函数 
   delete context.fn 
   // 返回执行结果 
   return result;
   }
  // 普通函数
  function print(age){ 
  console.log(this.name+" "+age);
   }
  // 自定义对象
  var obj = { name:'pc' }
  // 调用函数的 call 方法
 print.myCall(obj,1,2,3)

手写apply

首先 context 为可选参数,如果不传的话默认上下文为 window
接下来给 context 创建一个 fn 属性,并将值设置为需要调用的函数
因为 apply 传参是数组传参,所以取得数组,将其剥离为顺序参数进行函数调用
然后调用函数并将对象上的函数删除

// 手写一个 apply 方法 
Function.prototype.myApply = function(context){ 
	// 判断调用者是否为函数 
	if(typeof this !== 'function'){ 
		throw new TypeError('Error')
}
	// 不传参默认为 
	window context = context || window 
	// 新增 fn 属性,将值设置为需要调用的函数 
	context.fn = this // 返回执行结果 let result; 
	// 判断是否有参数传入 
	if(arguments[1]){ 
	result = context.fn(...arguments[1]) 
	}else{
	result = context.fn() 
	}
	// 删除函数 delete context.fn 
	// 返回执行结果 return result; 
}
// 普通函数 
function print(age,age2,age3){
	console.log(this.name+" "+ age + " "+ age2+" "+age3); 
}
// 自定义对象 
var obj = { 
	name:'pc' 
	}
	// 调用函数的 call 方法 
print.myApply(obj,[1,2,3])

手写bind

判断调用者是否为函数。
截取参数,注意:这里有两种形式传参。
返回一个函数,判断外部哪种方式调用了该函数(new | 直接调用)

// 手写一个 bind 函数 
Function.prototype.myBind = function (context) { 
	// 判断调用者是否为函数 
	if(typeof this !== 'function'){ 
		throw new TypeError('Error') 
		}
		// 截取传递的参数 
		const args = Array.from(arguments).slice(1) 
		// _this 指向调用的函数 
		const _this = this; 
		// 返回一个函数 
		return function F(){ 
		// 因为返回了一个函数,我们可以 new F(),所以需要判断
		 // 对于 new 的情况来说,不会被任何方式改变 this 
		 if(this instanceof F){ 
		 	return new _this(...args,...arguments) 
		 	}else{
		 	return _this.apply(context,args.concat(...arguments))
		 	}
		  } 
		}
		// 普通函数 
		function print(){ 
		// new 的方式调用 bind 参数输出换做 [...arguments] 
		console.log(this.name); 
		}
// 自定义对象 
var obj = { name:'pc' }
/ 调用函数的 call 方法 
let F = print.myBind(obj,1,2,3); 
// 返回对象 
let obj1 = new F(); 
console.log(obj1);
 //this用法总结:

    // 当以函数调用时this是window
    // 当以方法的形式调用时,谁调用方法this就是谁
    // 当以构造函数的形式调用时,this就是新创建的那个对象


        //  用函数的方式调用时this指向的是window
        //  用方法调用this时执行的是调用方法的对象

        // this指向的是一个对象 这个对象称为函数执行的上下文对象
        // 根据函数调用方式不同,this指向不同的对象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值