javascript中的this作用域详解


Posted in Javascript onJuly 15, 2019

Javascript中this的指向一直是困扰我很久的问题,在使用中出错的机率也非常大。在面向对象语言中,它代表了当前对象的一个引用,而在js中却经常让我觉得混乱,它不是固定不变的,而是随着它的执行环境的改变而改变。

在Javascript中this总是指向调用它所在方法的对象。因为this是在函数运行时,自动生成的一个内部对象,只能在函数内部使用。

下面我们分几种情况深入分析this的用法:

1.全局的函数调用

function globalTest() {
    this.name = "global this";
    console.log(this.name);
  }
  globalTest(); //global this

以上代码中,globalTest()是全局性的方法,属于全局性调用,因此this就代表全局对象window。为了充分证明this是window,对代码做如下更改:

var name = "global this";

  function globalTest() {
    console.log(this.name);
  }
  globalTest(); //global this

name作为一个全局变量,运行结果仍然是“global this”,说明this指向的是window。在方法体中我们尝试更改全局name,再次调用方法输出“rename global this”, 说明全局的name在方法内部被更改。代码如下:

var name = "global this";

  function globalTest() {
    this.name = "rename global this"
    console.log(this.name);
  }
  globalTest(); //rename global this

根据以上三段代码,我们得出结论:对于全局的方法调用,this指向的是全局对象window,即调用方法所在的对象。

2.对象方法的调用

如果函数作为对象的方法调用,this指向的是这个上级对象,即调用方法的对象。 在以下代码中,this指向的是obj对象。

function showName() {
    console.log(this.name);
  }
  var obj = {};
  obj.name = "ooo";
  obj.show = showName;
  obj.show(); //ooo

3.构造函数的调用

构造函数中的this指向新创建的对象本身。

function showName() {
    this.name = "showName function";
  }
  var obj = new showName();
  console.log(obj.name); //showName function

上述代码中,我们通过new关键字创建一个对象的实例,new关键字可以改变this的指向,将这个this指向对象obj。
我们再增加一个全局的name,用以证明this指向的不是global:

var name = "global name";

  function showName() {
    this.name = "showName function";
  }
  var obj = new showName();

  console.log(obj.name); //showName function
  console.log(name); //global name

在构造函数的内部,我们对this.name进行赋值,但并没有改变全局变量name。

4.apply/call调用时的this

apply和call都是为了改变函数体内部的this指向。 其具体的定义如下:

call方法:

语法:call(thisObj,Object)

定义:调用一个对象的一个方法,以另一个对象替换当前对象。

说明:

call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

apply方法:

语法:apply(thisObj,[argArray])

定义:应用某一对象的一个方法,用另一个对象替换当前对象。

说明:

如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。

如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

var value = "Global value";

  function FunA() {
    this.value = "AAA";
  }

  function FunB() {
    console.log(this.value);
  }
  FunB(); //Global value 因为是在全局中调用的FunB(),this.value指向全局的value
  FunB.call(window); //Global value,this指向window对象,因此this.value指向全局的value
  FunB.call(new FunA()); //AAA, this指向参数new FunA(),即FunA对象

  FunB.apply(window); //Global value
  FunB.apply(new FunA()); //AAA

在上述代码中,this的指向在call和apply中是一致的,只不过是调用参数的形式不一样。call是一个一个调用参数,而apply是调用一个数组。具体的会在以后的博文中单独阐述。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用javascript实现改变TEXTAREA滚动条和按钮的颜色,以及怎样让滚动条变得扁平
Apr 20 Javascript
js的逻辑运算符 ||
May 31 Javascript
捕获键盘事件(且兼容各浏览器)
Jul 03 Javascript
JavaScript中奇葩的假值示例应用
Mar 11 Javascript
node-webkit打包成exe文件被360误报木马的解决方法
Mar 11 Javascript
使用javascript实现判断当前浏览器
Apr 14 Javascript
基于jquery实现在线选座订座之影院篇
Aug 24 Javascript
node.js连接mongoDB数据库 快速搭建自己的web服务
Apr 17 Javascript
完美解决js传递参数中加号和&号自动改变的方法
Oct 11 Javascript
Bootstrap table使用方法记录
Aug 23 Javascript
axios取消请求的实践记录分享
Sep 26 Javascript
node 标准输入流和输出流代码实例
Sep 19 Javascript
微信小程序页面上下滚动效果
Nov 18 #Javascript
node.js实现上传文件功能
Jul 15 #Javascript
js canvas实现5张图片合成一张图片
Jul 15 #Javascript
js使用文件流下载csv文件的实现方法
Jul 15 #Javascript
基于Taro的微信小程序模板消息-获取formId功能模块封装实践
Jul 15 #Javascript
微信小程序开发技巧汇总
Jul 15 #Javascript
微信小程序中如何计算距离某个节日还有多少天
Jul 15 #Javascript
You might like
PHP设计模式 注册表模式(多个类的注册)
2012/02/05 PHP
php抓取页面的几种方法详解
2013/06/17 PHP
PHP使用feof()函数读文件的方法
2014/11/07 PHP
php实现以只读方式打开文件的方法
2015/03/16 PHP
yii2.0使用Plupload实现带缩放功能的多图上传
2015/12/22 PHP
实现php删除链表中重复的结点
2018/09/27 PHP
js 动态添加标签(新增一行,其实很简单,就是几个函数的应用)
2009/03/26 Javascript
js实现单一html页面两套css切换代码
2013/04/11 Javascript
Node.js模块加载详解
2014/08/16 Javascript
jQuery提示效果代码分享
2014/11/20 Javascript
js的toLowerCase方法用法实例
2015/01/27 Javascript
JavaScript清空数组元素的两种方法简单比较
2015/07/10 Javascript
原生js封装的一些jquery方法(详解)
2016/09/20 Javascript
jquery ajaxfileupload异步上传插件使用详解
2017/02/08 Javascript
VUE多层路由嵌套实现代码
2017/05/15 Javascript
自己动手封装一个React Native多级联动
2018/09/19 Javascript
mock.js实现模拟生成假数据功能示例
2019/01/15 Javascript
了解前端理论:rscss和rsjs
2019/05/23 Javascript
利用JavaScript将Excel转换为JSON示例代码
2019/06/14 Javascript
vuex+axios+element-ui实现页面请求loading操作示例
2020/02/02 Javascript
JS中类的静态方法,静态变量,实例方法,实例变量区别与用法实例分析
2020/03/14 Javascript
简单了解three.js 着色器材质
2020/08/03 Javascript
python实现在字符串中查找子字符串的方法
2015/07/11 Python
python 如何快速找出两个电子表中数据的差异
2017/05/26 Python
解决phantomjs截图失败,phantom.exit位置的问题
2018/05/17 Python
HTML5 Convas APIs方法详解
2015/04/24 HTML / CSS
Goodee官方商店:迷你投影仪
2021/03/15 全球购物
索引覆盖(Index Covering)查询含义
2012/02/18 面试题
编程用JAVA解析XML的方式
2013/07/07 面试题
幼师求职信
2014/06/23 职场文书
关于美容院的活动方案
2014/08/14 职场文书
2014党员干部四风问题对照检查材料思想汇报
2014/09/24 职场文书
写自招自荐信的绝招!
2019/04/19 职场文书
MySQL 使用索引扫描进行排序
2021/06/20 MySQL
「租借女友」第2季樱泽墨角色PV&新视觉图公开
2022/03/21 日漫
Apache Pulsar结合Hudi构建Lakehouse方案分析
2022/03/31 Servers