浅谈Javascript中的this

目录

一、什么是this?

二、this的值

情景一:纯函数调用

情景二:作为对象的方法调用

情况三 apply 调用

情景四:构造函数中的this

情景五、箭头函数

详细的参考文章:


一、什么是this?

this是JavaScript中的一个关键字,在函数运行期间自动生成的对象,只可以在函数内部使用,表示函数在运行时候的环境对象。

其值在不同的地方表述的含义也不相同,下面做简单介绍。

二、this的值

情景一:纯函数调用

var name = 'lei';

function sayHi(){
    var name = 'hahaha'
 	console.log('hi '+ this.name);
}

sayHi(); // hi lei
window.sayHi();// hi lei

  这种情况下相当于全局调用,this指向全局对象。this.指向调用函数的对象。

情景二:作为对象的方法调用

var person =
    {
	    name : 'lei',
	    sayHi :function(){
            var name = 'hahaha';
		    console.log('hi,' + this.name);
		}
	}

person.sayHi(); //hi,lei

这种情况下this指向此对象。其实等同于上一种情况,这里的sayHi是函数,其this指向调用函数的对象。

情况三 apply 调用

沿用上面的代码。

		sayHi.call(person);
		sayHi.apply(person);

apply和call方法,可以使this指向传入的第一个参数。

func.apply(thisArg, [argsArray])
func.call(thisArg, arg1, arg2...)

如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。

情景四:构造函数中的this

function Person(name, age){
			this.name = name,
			this.age = age,
			this.sayInfo =function(){
				console.log('my name is ' + this.name+' and I\'m ' + this.age + ' years old!');
			}
		}

		let me = new Person('lei', 999);
		me.sayInfo();

这里设计到原型和原型链,我们先对new操作符做的一些事情进行简单介绍,然后在下一篇文章中给出关于原型及原型链的一些分析。

let me = new Person('lei', 999);

上面代码使用new操作符生成Person的实例,过程如下:

1)let me =new Object() //创建一个空对象,这里的new你先不要管他,学习了原型链之后就知道怎么回事了

2)me.__proto__ = Person.prototype //me继承自Person,把me对象挂在对应的原型链上

3)var obj = Person.call(me) //执行构造函数,这里我们用到了call(),使其this指向me

4)判断执行完构造函数后的返回值,若显式返回一个对象类型,则返回返回此对象,即3)中的obj;否则返回1)中创建的对象me;

if(typeof obj == 'object'){
    return obj;
}else return{
    return me;
}

 

情景五、箭头函数

箭头函数不会创建this,而是沿作用域链从上一级作用域继承this(父级执行上下文,这个概念以后做具体介绍)。

var name = 'lei'
setTimeout(() =>{
    var name = 'hahaha';
	console.log(this.name)
},1000) // lei

上面实例中,异步调用匿名函数,输出this.name。此时this继承于上一级作用域,也就是全局作用域,返回name属性值。

当遇到多层箭头函数嵌套的时候,只需要沿作用域链找出外层调用箭头函数的对象即是this的指向对象。

 

最后给出一道题

var a=11
function test1(){
  this.a=22;
  let b=function(){
    console.log(this.a);
  };
  b();
}
var x=new test1();
//熟悉闭包的同学马上会发现变量b是一个闭包,本质是一个函数
//那么我们参考情景一的情况,会发现找不到它的调用对象,因此在严格模式下其调用对象为undifined,而在非严格模式下,认为其调用对象为window,因此结果为 11;
/**********************************/
var a=11;
function test2(){
  this.a=22;
  let b=()=>{console.log(this.a)}
  b();
}
var x=new test2()

//变量b虽然也是一个闭包,但是箭头函数会继承来自父级执行上下文的this。
那么我们就找找父级执行上下文,参考红宝书中给出的案例,可以知晓其父级上下文为function test1(),那么this指向于test1,因此结果为22;

详细的参考文章:

1、执行上下文:https://segmentfault.com/a/1190000009041008

2、闭包:https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/00143449934543461c9d5dfeeb848f5b72bd012e1113d15000 

总结:

(1)this存在于函数中,指向调用对象的对象。

(2)若指向对象不存在,在非严格模式下默认指向全局对象,这个在闭包中常用。严格模式下指向undefined。

(3)箭头函数中无this,因此不能做构造函数,其this继承自父级执行上下文中的this。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值