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 相关文章推荐
创建一个复制UBB软件信息的链接或按钮的js代码
Jan 06 Javascript
用jQuery打造TabPanel效果代码
May 22 Javascript
原生js实现查找/添加/删除/指定元素的class
Apr 12 Javascript
javascript 实现子父窗体互相传值的简单实例
Feb 17 Javascript
js实现一个链接打开两个链接地址的方法
May 12 Javascript
JavaScript统计网站访问次数的实现代码
Nov 18 Javascript
js判断图片加载完成后获取图片实际宽高的方法
Feb 25 Javascript
如何解决vue在ios微信"复制链接"功能问题
Mar 26 Javascript
jQuery插件simplePagination的使用方法示例
Apr 28 jQuery
ES5 模拟 ES6 的 Symbol 实现私有成员功能示例
May 06 Javascript
JavaScript实现刮刮乐效果
Nov 01 Javascript
分享15个Webpack实用的插件!!!
Mar 31 Javascript
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
什么是调频(FM)、调幅(AM)、短波(SW)、长波(LW)
2021/03/01 无线电
PHP 和 MySQL 基础教程(四)
2006/10/09 PHP
php加密算法之实现可逆加密算法和解密分享
2014/01/21 PHP
JSON+JavaScript处理JSON的简单例子
2013/03/20 Javascript
javascript的内存管理详解
2013/08/07 Javascript
Jquery 的outerHeight方法使用介绍
2013/09/11 Javascript
使用jQuery和PHP实现类似360功能开关效果
2014/02/12 Javascript
Jquery Uploadify上传带进度条的简单实例
2014/02/12 Javascript
使用JavaScript刷新网页的方法
2015/06/04 Javascript
初步使用Node连接Mysql数据库
2016/03/03 Javascript
JS获取一个未知DIV高度的方法
2016/08/09 Javascript
完美解决js传递参数中加号和&号自动改变的方法
2016/10/11 Javascript
微信小程序中form 表单提交和取值实例详解
2017/04/20 Javascript
一个可复用的vue分页组件
2017/05/15 Javascript
深入理解vue.js中的v-if和v-show
2017/06/22 Javascript
node.js中fs文件系统目录操作与文件信息操作
2018/02/24 Javascript
Angular Excel 导入与导出的实现代码
2019/04/17 Javascript
python与php实现分割文件代码
2017/03/06 Python
python僵尸进程产生的原因
2017/07/21 Python
Flask数据库迁移简单介绍
2017/10/24 Python
通过Python模块filecmp 对文件比较的实现方法
2018/06/29 Python
Python使用matplotlib绘制随机漫步图
2018/08/27 Python
使用50行Python代码从零开始实现一个AI平衡小游戏
2018/11/21 Python
详解pycharm连接不上mysql数据库的解决办法
2020/01/10 Python
浅谈python量化 双均线策略(金叉死叉)
2020/06/03 Python
HTML5之多线程(Web Worker)
2019/01/02 HTML / CSS
香港交友网站:be2香港
2018/07/22 全球购物
世界领先的豪华床上用品供应商之一:Bedeck Home
2019/03/18 全球购物
JPA面试常见问题
2016/11/14 面试题
建筑设计学生的自我评价
2014/01/16 职场文书
大学生求职计划书
2014/04/30 职场文书
应聘教师求职信范文
2015/03/20 职场文书
公司人力资源管理制度
2015/08/05 职场文书
幼师自荐信范文(2016推荐篇)
2016/01/28 职场文书
golang中的空slice案例
2021/04/27 Golang
MySQL的join buffer原理
2021/04/29 MySQL