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 相关文章推荐
非html5实现js版弹球游戏示例代码
Sep 22 Javascript
jQuery中prop()方法用法实例
Jan 05 Javascript
JavaScript开发Chrome浏览器扩展程序UI的教程
May 16 Javascript
深入浅析JavaScript中的arguments对象(强力推荐)
Jun 03 Javascript
微信小程序  action-sheet详解及实例代码
Nov 09 Javascript
JavaScript中捕获/阻止捕获、冒泡/阻止冒泡方法
Dec 07 Javascript
详解Node.js开发中的express-session
May 19 Javascript
javascript 开发之百度地图使用到的js函数整理
May 19 Javascript
node跨域请求方法小结
Aug 25 Javascript
vue-cli 打包使用history模式的后端配置实例
Sep 20 Javascript
antd的select下拉框因为数据量太大造成卡顿的解决方式
Oct 31 Javascript
javascript数组includes、reduce的基本使用
Jul 02 Javascript
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
谈谈PHP语法(4)
2006/10/09 PHP
自动把纯文本转换成Web页面的php代码
2009/08/27 PHP
php网站判断用户是否是手机访问的方法
2013/11/01 PHP
php实现压缩多个CSS与JS文件的方法
2014/11/11 PHP
php中memcache 基本操作实例
2015/05/17 PHP
php实现比较两个文件夹异同的方法
2015/06/18 PHP
php中注册器模式类用法实例分析
2015/11/03 PHP
jquery UI 1.72 之datepicker
2009/12/29 Javascript
JavaScript中的关键字"VAR"使用详解 分享
2013/07/31 Javascript
jQuery源码分析之jQuery.fn.each与jQuery.each用法
2015/01/23 Javascript
检测一个函数是否是JavaScript原生函数的小技巧
2015/03/13 Javascript
javascript基本数据类型和转换
2017/03/17 Javascript
layui前段框架日期控件使用方法详解
2017/05/19 Javascript
Vue header组件开发详解
2018/01/26 Javascript
详解用JS添加和删除class类名
2019/03/25 Javascript
教你30秒发布一个TypeScript包到NPM的方法步骤
2019/07/22 Javascript
Vue  webpack 项目自动打包压缩成zip文件的方法
2019/07/24 Javascript
详解vue3.0 diff算法的使用(超详细)
2020/07/01 Javascript
VsCode里的Vue模板的实现
2020/08/12 Javascript
vue单应用在ios系统中实现微信分享功能操作
2020/09/07 Javascript
vue-calendar-component 封装多日期选择组件的实例代码
2020/12/04 Vue.js
Python文件与文件夹常见基本操作总结
2016/09/19 Python
python机器学习案例教程——K最近邻算法的实现
2017/12/28 Python
python-opencv 将连续图片写成视频格式的方法
2019/01/08 Python
详解PyTorch中Tensor的高阶操作
2019/08/18 Python
python里glob模块知识点总结
2021/01/05 Python
css3弹性盒子flex实现三栏布局的实现
2020/11/12 HTML / CSS
html5定位获取当前位置并在百度地图上显示
2014/08/22 HTML / CSS
用HTML5 实现橡皮擦的涂抹效果的教程
2015/05/11 HTML / CSS
【HTML5】3D模型--百行代码实现旋转立体魔方实例
2016/12/16 HTML / CSS
佛罗里达州印第安河新鲜水果:Hale Groves
2017/02/20 全球购物
合理化建议书
2015/02/04 职场文书
幼儿园教师工作总结2015
2015/04/02 职场文书
2015年行政人事工作总结
2015/05/21 职场文书
结婚幸福感言
2015/08/01 职场文书
SpringBoot前端后端分离之Nginx服务器下载安装过程
2022/08/14 Servers