JavaScript语言中this指向研究
2021-10-18周虎
周虎
摘要:JavaScript逐渐从一门简单的脚本语言进化成为一门强大的面向对象编程语言,尤其在对象的this指向上,不仅借鉴了其他高级语言的优点,并结合自身灵活的编程能力,在程序运行中可以动态改变this指向。该文针对this在全局变量、函数、对象中的指向,以及通过apply、call和bind改变绑定对象后this的指向进行了深入的探讨并进行了总结归纳,便于读者更深层次的理解JavaScript中的this指向问题。
关键词:JavaScript;this;bind;apply;call
中图分类号:TP312 文献标识码:A
文章編号:1009-3044(2021)26-0162-02
开放科学(资源服务)标识码(OSID):
1 背景
JavaScript是面向Web的编程语言,其动态以及面向对象的编程风格使得它已经从一门简单的脚本语言进化成为一门强大的编程语言[1]。在高级语言面向对象编程过程中,都会用到this关键字,一般用来指向构建的对象,同样在JavaScript编程语言中,在很多情况下也会用到this关键字,this在其不同的上下文环境中,this的指向会各不相同,尤其在全局变量、函数和对象中的指向,以及通过apply、call和bind在改变绑定对象后this的指向问题,对于初学者来说很容易混淆,并因此可能导致程序错误。本文根据this在不同上下文环境中的指向问题进行分类探讨,便于读者对JavaScript中的this指向问题的理解和应用。
2 JavaScript中的this指向分析
在JavaScript语言中,使用到this关键字的上下文通常包括全局变量、普通函数、构造函数、对象函数和箭头函数,以及通过关键字apply、call和bind改变对象指向后this的指向。下面就不同情况下this的指向进行分析探讨。
2.1 全局变量和函数中this指向
在全局变量中,this默认指向的是window对象,此时可以省略this,也可以使用window来代替,如下面代码所示:
var str="hello JavaScript";
function fn(){
console.log(this.str);
}
this.fn();
console.log(this);
在上面代码中this指向就是window对象,即使在普通函数fn()中,此时this也是指向的window对象,用来获取全局变量的值。但是在ES6以后,如果改用let来定义全局变量,此时全局变量将不再是window对象的属性了,如下面代码所示:
let str="hello JavaScript";
console.log(str);//hello JavaScript
console.log(this.str);//undefined
在上面代码中,可以使用变量名str直接访问,但是不能使用this.str来访问,因为let定义的全局变量不再属于window对象,此时将输出undefined。
2.2 构造函数中的this指向
JavaScript可以通过构造函数来创建并初始化对象,只不过JavaScript没有类定义和特殊的构造器定义,需要程序员自己定义一个构造函数来创建属性,而所有的函数都可以被用来定义构造函数[2]。在构造函数中使用this,这点和其他高级语言类似,this指向的是使用new创建的对象,如下面代码所示:
function Student(name,age)
{
this.name=name;
this.age=age;
}
var stu=new Student("zhangsan",15);
console.log(stu.name);//zhangsan
在上面代码中,构造函数中的this就指向了使用Student函数创建的当前对象stu,这一点和其他的高级语言构造函数中的this功能类似,都是指向当前对象本身。
2.3 对象函数中的this指向
面向对象编程思想的重点在“对象”上,对象实质上是“客观事物”在程序设计语言中的表现形式[3]。在JavaScript对象中可以使用this来访问对象的属性和函数,此时this的指向是当前对象,但是如果对象的函数是其他全局函数的引用,那么全局函数中的this指向就可能发生改变,如下面代码所示:
var name="zhangsan";
function show()
{
console.log(this.name);
}
var stu={
name:'lisi',
show:show
}
show();//输出zhangsan
stu.show();//输出lisi
在上面代码中,如果直接调用show()函数,则是输出全局变量name的值”zhangsan”,但是在stu对象中的show函数是对全局函数show()的引用,stu.show()在执行时show函数中的this则指向了stu对象,所以输出“lisi”。
如果对象属性还是一个对象,并且和父对象具有相同的属性,那么this则指向当前的属性对象,如下面代码所示: