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 相关文章推荐
editable.js 基于jquery的表格的编辑插件
Oct 24 Javascript
jQuery之$(document).ready()使用介绍
Apr 05 Javascript
JavaScrip实现PHP print_r的数功能(三种方法)
Nov 12 Javascript
JS获取当前日期和时间的简单实例
Nov 19 Javascript
jQuery实现单击弹出Div层窗口效果(可关闭可拖动)
Sep 19 Javascript
老生常谈JavaScript数组的用法
Jun 10 Javascript
谈谈JS中常遇到的浏览器兼容问题和解决方法
Dec 17 Javascript
浅谈webpack下的AOP式无侵入注入
Nov 12 Javascript
vue-router相关基础知识及工作原理
Mar 16 Javascript
讲解vue-router之什么是编程式路由
May 28 Javascript
vue项目前端微信JSAPI与外部H5支付相关实现过程及常见问题
Apr 14 Javascript
Vant picker 多级联动操作
Nov 02 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
php入门小知识
2008/03/24 PHP
PHP管理依赖(dependency)关系工具 Composer 安装与使用
2014/08/18 PHP
PHP截取指定图片大小的方法
2014/12/10 PHP
PHP结合Mysql数据库实现留言板功能
2016/03/04 PHP
PHP Mysqli 常用代码集合
2016/11/12 PHP
jquery跨域请求示例分享(jquery发送ajax请求)
2014/03/25 Javascript
express的中间件bodyParser详解
2014/12/04 Javascript
JS实现判断滚动条滚到页面底部并执行事件的方法
2014/12/18 Javascript
JavaScript中的比较操作符>、=、
2014/12/31 Javascript
jQuery操作动态生成的内容的方法
2016/05/28 Javascript
JS动态给对象添加事件的简单方法
2016/07/19 Javascript
js复制内容到剪贴板代码,js复制代码的简单实例
2016/10/27 Javascript
JS 实现可停顿的垂直滚动实例代码
2016/11/23 Javascript
微信小程序去除左上角返回键的实现方法
2020/03/06 Javascript
es5 类与es6中class的区别小结
2020/11/09 Javascript
通过vue.extend实现消息提示弹框的方法记录
2021/01/07 Vue.js
[03:23:49]2016.12.17日完美“圣”典全回顾
2016/12/19 DOTA
详解python进行mp3格式判断
2016/12/23 Python
Python在不同目录下导入模块的实现方法
2017/10/27 Python
python爬虫基本知识
2018/03/05 Python
Python进程间通信 multiProcessing Queue队列实现详解
2019/09/23 Python
通过实例解析python描述符原理作用
2020/01/22 Python
Django Form常用功能及代码示例
2020/10/13 Python
HTML5拖放API实现自动生成相框功能
2020/04/07 HTML / CSS
施华洛世奇日本官网:SWAROVSKI日本
2018/05/04 全球购物
全球最大的户外用品零售商之一:The House
2018/06/12 全球购物
即时搜索数百万张门票:SeatsForEveryone.com
2018/08/26 全球购物
拓展策划方案
2014/06/03 职场文书
建筑专业毕业生求职信
2014/09/30 职场文书
2015年学生会干事工作总结
2015/04/09 职场文书
绿里奇迹观后感
2015/06/15 职场文书
2015年大学生暑期实习报告
2015/07/13 职场文书
JavaScript 防篡改对象的用法示例
2021/04/24 Javascript
浅谈Golang 嵌套 interface 的赋值问题
2021/04/29 Golang
eval(cmd)与eval($cmd)的区别与联系
2021/07/07 PHP
react 路由Link配置详解
2021/11/11 Javascript