JavaScript this 深入理解


Posted in Javascript onJuly 30, 2009

最近一段时间看了很多JavaScript 的库源码, 如 prototype, Ext core 等。这些库中大量应用到了这一概念。直到昨天翻了一下《JavaScript王者归来》这本书才算对this有一个深刻的理解。
大至归结一下:
1. 函数调用者与所有者
JavaScript 中函数(function) 存在调用者 与 所有者这两个概念,调用者是指调用函数的对象,通常是一个指向调用了当前函数的函数的引用,如果是顶层调用,那么caller=null, 大部分浏览器的JavaScript实现 可以用 caller 这个属性获得(这不是 ECMAScript 规范的一部分,所有还是慎用)。 从以下的代码能够很好的理解这点:

function a(){ 
alert('fun a caller=' + a.caller); 
} 
function b(){ 
a(); 
} 
a(); 
b();

-----------
运行结果可以看到两个对话框:
1.
fun a caller=null;
2.
fun a caller=function b(){
a();
}
--------------------------
而对于所有者,则是指调用函数的对象(一个动态的概念), 在函数体中的this就是指向了函数的所有者。在这里的this 与 Java 以及 C++ 中的 this指针是完全不同的两个概念,很多人忽略了这一点,这也是导致 JavaScript中的this无法很好理解的原因之一。看看以下的例子:
var oa = { 
x:1, 
y:2 
} 
var ob = { 
x:11, 
y:12 
} 
function a(w){ 
alert(w + "=" + this.x + "," + this.y) 
} 
a("?"); 
oa.fun = a; 
oa.fun("a"); 
ob.fun = a; 
ob.fun("b");

---------
一开始的调用 a() 这时未指定所有者,一般这种情况 this 是指向浏览器的顶层元素 window 的, 而window中未定义x 与 y 属性。
所以结果显示为: ?=undefined,undefined
oa.fun = a; oa.fun("a"); 将函数引用赋值给对像a的属性fun, 这时再调用函数的所有者变成了a, 则结果显示为:a=1,2
同理 ob.fun("b")则显示:b=11,12。
在JavaScript中要改变一个函数的所有者(this)的方法就是将函数引用赋值给一个对象的属性。
同是在Function对象中也提供了两个原型函数可以实现这一功能: apply, call, 这两个函数的第一个参数就是要指定的所有者对象,它们间的唯一区别就是apply将其后的要传递给函数的形参封装到数组中,或者直接用 arguments对象。而call则直接将形参跟在其后。
因此上面的 oa.fun=a; oa.fun("a") 可以改写成 a.apply(oa, ["a"]) 或 a.call(oa, "a");
ob.fun=b; ob.fun("b") 可以改写成 a.apply(ob, ["b"]) 或 b.call(ob, "b");
知道了以上这此,对于 this 的作用域及其使用就很好理解了。

下面是一些参考文档
javascript this用法小结
https://3water.com/article/16863.htm

JavaScript this 深入理解
https://3water.com/article/19425.htm

JAVASCRIPT THIS详解 面向对象
https://3water.com/article/17584.htm

Javascript this指针
https://3water.com/article/19434.htm

JavaScript中this关键字使用方法详解
https://3water.com/article/7954.htm

Javascript this关键字使用分析
https://3water.com/article/16235.htm

Javascript 相关文章推荐
jQuery TextBox自动完成条
Jul 22 Javascript
javascript 基础篇4 window对象,DOM
Mar 14 Javascript
jquery的ajax跨域请求原理和示例
May 08 Javascript
JavaScript中如何通过arguments对象实现对象的重载
May 12 Javascript
详谈javascript中DOM的基本属性
Feb 26 Javascript
Javascript节点关系实例分析
May 15 Javascript
JavaScript函数学习总结以及相关的编程习惯指南
Nov 16 Javascript
BOM系列第一篇之定时器setTimeout和setInterval
Aug 17 Javascript
jQuery通过ajax快速批量提交表单数据
Oct 25 Javascript
vue中接口域名配置为全局变量的实现方法
Sep 20 Javascript
JavaScript实现拖动对话框效果的实现代码
Oct 12 Javascript
vue-drawer-layout实现手势滑出菜单栏
Nov 19 Vue.js
Google Map API更新实现用户自定义标注坐标
Jul 29 #Javascript
JavaScript Konami Code 实现代码
Jul 29 #Javascript
JavaScript 获取事件对象的注意点
Jul 29 #Javascript
javascript CSS画图之基础篇
Jul 29 #Javascript
JQuery 表格操作(交替显示、拖动表格行、选择行等)
Jul 29 #Javascript
JavaScript 设计模式学习 Factory
Jul 29 #Javascript
JQuery UI皮肤定制
Jul 27 #Javascript
You might like
在Windows下编译适用于PHP 5.2.12及5.2.13的eAccelerator.dll(附下载)
2010/05/04 PHP
PHP删除数组中空值的方法介绍
2014/04/14 PHP
PHP中auto_prepend_file与auto_append_file用法实例分析
2014/09/22 PHP
PHP缓存集成库phpFastCache用法
2014/12/15 PHP
Javascript注入技巧
2007/06/22 Javascript
帮助避免错误的Javascript陷阱清单
2009/05/31 Javascript
Javascript 检测、添加、移除样式(className)函数代码
2009/09/08 Javascript
javascript面向对象之二 命名空间
2011/02/08 Javascript
JS实现从表格中动态删除指定行的方法
2015/03/31 Javascript
JS实现仿QQ聊天窗口抖动特效
2015/05/10 Javascript
JS 通过系统时间限定动态添加 select option的实例代码
2016/06/09 Javascript
Seajs是什么及sea.js 由来,特点以及优势
2016/10/13 Javascript
详解vue组件化开发-vuex状态管理库
2017/04/10 Javascript
node.js中express中间件body-parser的介绍与用法详解
2017/05/23 Javascript
详解通过JSON数据使用VUE.JS
2017/05/26 Javascript
vue组件 $children,$refs,$parent的使用详解
2017/07/31 Javascript
BACKBONE.JS 简单入门范例
2017/10/17 Javascript
详解NODEJS的http实现
2018/01/04 NodeJs
JavaScript动态加载重复绑定问题
2018/04/01 Javascript
seajs下require书写约定实例分析
2018/05/16 Javascript
vue+element实现打印页面功能
2019/05/20 Javascript
vue学习笔记之slot插槽用法实例分析
2020/02/29 Javascript
JavaScript实现移动端弹窗后禁止滚动
2020/05/25 Javascript
微信小程序实现登录注册功能
2020/12/29 Javascript
python实现百万答题自动百度搜索答案
2018/01/16 Python
python实现教务管理系统
2018/03/12 Python
Flask框架Flask-Principal基本用法实例分析
2018/07/23 Python
Python 限制线程的最大数量的方法(Semaphore)
2019/02/22 Python
利用Python的sympy包求解一元三次方程示例
2019/11/22 Python
对python中return与yield的区别详解
2020/03/12 Python
tensorflow实现将ckpt转pb文件的方法
2020/04/22 Python
CSS Grid布局教程之网格单元格布局
2014/12/30 HTML / CSS
简单掌握CSS3中resize属性的用法
2016/04/01 HTML / CSS
canvas基础之图形验证码的示例
2018/01/02 HTML / CSS
暑期政治学习心得体会
2014/09/02 职场文书
Python爬虫之自动爬取某车之家各车销售数据
2021/06/02 Python