Javascript学习笔记之 函数篇(二) : this 的工作机制


Posted in Javascript onJune 24, 2014

全局作用域下

this;
当在全局作用域中使用 this,它指向全局对象。
这里详细介绍下全局对象:

全局对象(Global object) 是在进入任何执行上下文之前就已经创建了的对象;
这个对象只存在一份,它的属性在程序中任何地方都可以访问,全局对象的生命周期终止于程序退出那一刻。
全局对象初始创建阶段将 Math、String、Date、parseInt 作为自身属性,等属性初始化,同样也可以有额外创建的其它对象作为属性(其可以指向到全局对象自身)。例如,在 DOM 中,全局对象的 window 属性就可以引用全局对象自身。
所以在 console 内输入 window 和 this.window 是一样的。

调用一个函数时

foo();
在这里,this 同样指向全局对象。

调用一个方法时

test.foo();

在这个例子中,this 将会指向 test 对象。

调用一个构造函数时

new foo();

一个函数在被调用时和关键字 new 一起使用,我们称之为构造函数。此时在函数内,this 指向新建的对象。

显式设置时

function foo(a, b, c) {}//

var bar = {};
foo.apply(bar, [1, 2, 3]); // array will expand to the below
foo.call(bar, 1, 2, 3); // results in a = 1, b = 2, c = 3

当使用 Function.prototype 的 apply 和 call 方法时,this 的值为显式设置为该方法的第一个参数。
因此,不同于调用一个函数时的规则,上例中 this 指向了 bar。

这里介绍下 call 和 apply 方法:

 call 方法:

语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。

 apply 方法

语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
在这里我们要注意一点,在对象的字面声明时,this 不能用来指向对象本身。如下:

var obj = {me: this}

这里,this 不会指向 obj,this 的应用只限于以上五种情形。

总结

尽管上述情形在大多时候是有意义的,但是第二种情形(即调用一个函数时)的 this 实际上是很少有用途的,这被认为是 Javascript 设计上的另一个错误。

Foo.method = function() {
  function test() {
    // this is set to the global object
  }
  test();
}

根据我们上面所述,这里的 this 将会指向全局对象,而不是 Foo 函数。
为了在 test 中获得指向 Foo 的途径,我们需要在 method 内部创建一个局部变量指向 Foo。

Foo.method = function() {
  var that = this;
  function test() {
    // Use that instead of this here
  }
  test();
}

that 只是普通的变量名,但是它经常被用来指向外部的 this。
还有一个比较有意思的地方与函数别名相关,即将一个方法赋值给一个变量时。

var test = someObject.methodTest;
test();

上例中,test 将会被当做一个普通函数看待,所以根据第二种情形(即调用一个函数时),其内部的 this 将会指向全局变量,而不是 someObject。
尽管,this 晚绑定初看上去是个不好的决定,但实际上这是原型式继承工作的基础。

function Foo() {}
Foo.prototype.method = function() {};

function Bar() {}
Bar.prototype = Foo.prototype;

new Bar().method();

此时,当 method 被调用时,它将指向 Bar 的实例对象。

Javascript 相关文章推荐
$()JS小技巧
Jul 21 Javascript
js 替换功能函数,用正则表达式解决,js的全部替换
Dec 08 Javascript
如何确保JavaScript的执行顺序 之实战篇
Mar 03 Javascript
基于JavaScript实现智能右键菜单
Mar 02 Javascript
基于Turn.js 实现翻书效果实例解析
Jun 20 Javascript
angularJS深拷贝详解
Mar 23 Javascript
详谈vue+webpack解决css引用图片打包后找不到资源文件的问题
Mar 06 Javascript
vue 纯js监听滚动条到底部的实例讲解
Sep 03 Javascript
vue-cli3项目展示本地Markdown文件的方法
Jun 07 Javascript
js+canvas实现简单扫雷小游戏
Jan 22 Javascript
ES6新增的数组知识实例小结
May 23 Javascript
vue3弹出层V3Popup实例详解
Jan 04 Vue.js
Javascript学习笔记之 函数篇(一) : 函数声明和函数表达式
Jun 24 #Javascript
Javascript学习笔记之 对象篇(四) : for in 循环
Jun 24 #Javascript
Javascript学习笔记之 对象篇(三) : hasOwnProperty
Jun 24 #Javascript
js实现div闪烁原理及实现代码
Jun 24 #Javascript
Javascript 学习笔记之 对象篇(二) : 原型对象
Jun 24 #Javascript
Javascript学习笔记之 对象篇(一) : 对象的使用和属性
Jun 24 #Javascript
jQuery学习笔记之 Ajax操作篇(三) - 过程处理
Jun 23 #Javascript
You might like
PHP生成唯一的促销/优惠/折扣码(附源码)
2012/12/28 PHP
解析CI即CodeIgniter框架在Nginx下的重写规则
2013/06/03 PHP
php实现httpclient类示例
2014/04/08 PHP
详解js异步文件加载器
2016/01/24 PHP
js 函数的执行环境和作用域链的深入解析
2009/11/01 Javascript
jquery获取自定义属性(attr和prop)实例介绍
2013/04/21 Javascript
js判断IE浏览器版本过低示例代码
2013/11/22 Javascript
JavaScript String 对象常用方法总结
2016/04/28 Javascript
ES6中Proxy与Reflect实现重载(overload)的方法
2017/03/30 Javascript
详解ES6语法之可迭代协议和迭代器协议
2018/01/13 Javascript
详解Bootstrap 学习(一)入门
2019/04/12 Javascript
送你43道JS面试题(收藏)
2019/06/17 Javascript
react MPA 多页配置详解
2019/10/18 Javascript
超简单的微信小程序轮播图
2019/11/22 Javascript
vue实现图片上传预览功能
2019/12/23 Javascript
jQuery实现异步上传一个或多个文件
2020/08/17 jQuery
[01:04:14]OG vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
[01:32]完美世界DOTA2联赛10月29日精彩集锦
2020/10/30 DOTA
浅谈python中截取字符函数strip,lstrip,rstrip
2015/07/17 Python
TensorFLow用Saver保存和恢复变量
2018/03/10 Python
使用pandas对矢量化数据进行替换处理的方法
2018/04/11 Python
python 实现对文件夹内的文件排序编号
2018/04/12 Python
pandas 实现将重复表格去重,并重新转换为表格的方法
2018/04/18 Python
Python3 中作为一等对象的函数解析
2019/12/11 Python
Python 3.8 新功能来一波(大部分人都不知道)
2020/03/11 Python
Python日志打印里logging.getLogger源码分析详解
2021/01/17 Python
夏尔巴人登珠峰品牌:Sherpa Adventure Gear
2018/02/08 全球购物
什么是唯一索引
2015/07/05 面试题
大一期末自我鉴定
2013/12/13 职场文书
结婚邀请函范文
2014/01/14 职场文书
教师远程培训感言
2014/03/06 职场文书
白岩松演讲
2014/05/21 职场文书
2015年妇幼保健工作总结
2015/05/19 职场文书
SpringBoot整合Redis入门之缓存数据的方法
2021/11/17 Redis
Innodb存储引擎中的后台线程详解
2022/04/03 MySQL
使用CSS实现黑白格背景效果
2022/06/01 HTML / CSS