欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript this的指向和原理

程序员文章站 2024-02-08 21:43:34
...

1. this指向什么

先给出结论:函数内部的this指向的是此函数的调用者。
例子:

var primit = 'window环境'
var obj = {
	primit:'obj环境',
	foo:function(){
		console.log(this)
		console.log(this.primit)
	}
}
var foo = obj.foo
obj.foo() //输出“obj环境”
foo() //输出“window环境”

控制台输出:
JavaScript this的指向和原理
分析:
foo和obj.foo作为引用类型的地址都指向了存储在栈中的foo函数。obj.foo()执行时,obj是foo函数的调用者,输出obj的环境(上下文);foo()执行时,相当于执行window.foo(),此时window是foo函数的调用者,输出了window的环境。

2. 为构造函数调用时this指向情况

例子:

var primit = 'window环境', newEnvir
var obj = {
   primit:'obj环境',
   foo:function(){
   	this.primit='新对象环境'
   	console.log(this)
   	newEnvir = this
   }
}
var foo1 = new obj.foo()
console.log(foo1===newEnvir) //true

控制台输出:
JavaScript this的指向和原理
分析:
var obj = new M()中,new关键字一共做了三件事:

  1. 创建空的简单JavaScript对象(即{}
  2. obj继承M的prototype(obj.__ proto__ = M.prototype
  3. M的this指向obj,并执行M的函数体(执行M.call(obj)
  4. 返回新对象obj

根据new的作用,foo1作为obj.foo的调用者(new的过程中obj.foo()执行),此时obj.foo内部的this指向新对象foo1

3. 为什么this指向其调用者

JavaScript的数据是存储在栈内存和堆内存中的。
例子:

var obj = {
	aaa: '',
	fff: function(){}
}

这个obj对象在内存的存储情况如下图
JavaScript this的指向和原理
obj作为基本数据类型存储在栈中,其值时存储在堆中的引用数据类型对象{aaa:'',fff:function(){}}地址

函数也是存储在栈中的,作为独立的值,在内部的任何的任何操作都和obj没关系,在堆内存的对象的方法fff本质也是指向在栈中的函数的地址,可以通过obj.fff访问函数。
JavaScript this的指向和原理

函数作为单独的值,可以在任何不同的环境(上下文)执行。js允许函数内部访问当前环境的环境变量,
但是访问的前提是需要知道当前处于什么环境,此时this就起着告知函数当前的运行环境的作用,这是设计this的目的。