首页 > 编程笔记 > JavaScript笔记 > JS函数
JS this和调用对象
JavaScript 函数的作用域是静态的,但是函数的调用却是动态的。由于函数可以在不同的运行环境内执行,因此 JavaScript 在函数体内定义了 this 关键字,用来获取当前的运行环境。
this 是一个指针型变量,它动态引用当前的运行环境。具体来说,就是调用函数的对象。调用对象是可以访问的 JavaScript 对象,而执行上下文的变量对象是一个不可访问的抽象概念。同时,在一个执行上下文中会存在多个调用函数的对象,但是只有一个变量对象。
问题的关键是如何正确理解“运行环境”。上面 3 种表达式中,obj.f = obj.f 是赋值表达式,把 obj.f 赋值给 obj.f,obj.f 是一个地址,把地址赋值给 obj.f 属性,表达式的运行环境发生在全局上下文中,所以此时函数 f 内的 this 就指向了全局上下文的调用对象 window。
false || obj.f 是一个逻辑表达式,左侧操作数为 false,则运算右侧操作数,返回 obj.f 的值,即引用地址。由于这个逻辑表达式运算发生在全局作用域内,此时的 f 函数内 this 就指向了全局对象。
obj.f,obj.f 是一个逗号运算表达式,逗号左侧和右侧的 obj.f 都是一个地址,都被运算一次,最后返回第 2 个操作数的值,即返回引用地址。由于这个操作发生在全局作用域内,所以 f 函数内 this 也指向了全局对象。
但是,对于下面形式的调用,不会返回 1,而是返回 2,即 this 指向 obj 对象。因为小括号不是一个运算符,它仅是一个逻辑分隔符,不执行运算,不会产生运行环境。当使用小括号调用函数时,此时发生的运行环境就是 obj 了。
this 是一个指针型变量,它动态引用当前的运行环境。具体来说,就是调用函数的对象。调用对象是可以访问的 JavaScript 对象,而执行上下文的变量对象是一个不可访问的抽象概念。同时,在一个执行上下文中会存在多个调用函数的对象,但是只有一个变量对象。
示例1
下面示例在全局上下文中声明一个变量 x,初始化值为 1。然后在 obj 对象内定义一个属性 x,初始化值为 2。使用函数 f 检测不同运行环境下 x 值的变化,以此检测 this 指针的引用对象。var x = 1; //声明全局变量并初始化 var obj = { f : function () { //定义方法f console.log(this.x); //访问当前运行环境中x的属性值 }, x : 2, //定义属性x,赋值为2 }; //obj环境执行 obj.f(); //2 var f1 = obj.f; //window环境运行 f1(); //1在上面代码中,obj.f() 表示在 obj 对象上调用 f 函数,则调用对象为 obj,此时 this 就指向 obj,this.x 就等于 obj.x,即返回结果为 2。若把 obj.f 赋值给变量 f1,然后在全局上下文中调用 f1 函数,则 f 函数体的运行环境在全局上下文中执行,此时 this 就指向 window,this.x 就等于 window.x,即返回结果为 1。
示例2
this 总是指代函数的当前运行环境。针对示例 1 的代码,如果使用下面 3 种方式调用 f 函数,会发现返回值都是 1。var x = 1; //声明全局变量并初始化 var obj = { f : function () { //定义方法f console.log(this.x); //访问当前运行环境中x的属性值 }, x : 2, //定义属性x,赋值为2 }; (obj.f = obj.f) (); //1 (false || obj.f) (); //1 (obj.f, obj.f) (); //1在上面代码中,小括号左侧都是一个表达式,表达式的值都是 obj.f,而在示例 1 中可以看到使用 obj.f() 调用函数 f,返回值是 2。为什么现在换一种表示方法返回值都是 1 呢?
问题的关键是如何正确理解“运行环境”。上面 3 种表达式中,obj.f = obj.f 是赋值表达式,把 obj.f 赋值给 obj.f,obj.f 是一个地址,把地址赋值给 obj.f 属性,表达式的运行环境发生在全局上下文中,所以此时函数 f 内的 this 就指向了全局上下文的调用对象 window。
false || obj.f 是一个逻辑表达式,左侧操作数为 false,则运算右侧操作数,返回 obj.f 的值,即引用地址。由于这个逻辑表达式运算发生在全局作用域内,此时的 f 函数内 this 就指向了全局对象。
obj.f,obj.f 是一个逗号运算表达式,逗号左侧和右侧的 obj.f 都是一个地址,都被运算一次,最后返回第 2 个操作数的值,即返回引用地址。由于这个操作发生在全局作用域内,所以 f 函数内 this 也指向了全局对象。
但是,对于下面形式的调用,不会返回 1,而是返回 2,即 this 指向 obj 对象。因为小括号不是一个运算符,它仅是一个逻辑分隔符,不执行运算,不会产生运行环境。当使用小括号调用函数时,此时发生的运行环境就是 obj 了。
(obj.f) (); //2
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算