JavaScript this 深入理解

 更新时间:2009年07月30日 17:03:37   作者:  
一直以来,对于JavaScript 中的this的理解都是很模糊的, 特别是对函数进行apply 与 call 调用。这两个操作如果没有很好的理解 JavaScript中this的概念,会越搞越迷糊。

最近一段时间看了很多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://www.jb51.net/article/16863.htm

JavaScript this 深入理解
https://www.jb51.net/article/19425.htm

JAVASCRIPT THIS详解 面向对象
https://www.jb51.net/article/17584.htm

Javascript this指针
https://www.jb51.net/article/19434.htm

JavaScript中this关键字使用方法详解
https://www.jb51.net/article/7954.htm

Javascript this关键字使用分析
https://www.jb51.net/article/16235.htm

相关文章

  • js写一个弹出层并锁屏效果实现代码

    js写一个弹出层并锁屏效果实现代码

    js实现一个弹出层并锁屏效果是每一网友所期望的效果,于是搜集整理一番,把代码晒出来和大家分享
    2012-12-12
  • JavaScript基于扩展String实现替换字符串中index处字符的方法

    JavaScript基于扩展String实现替换字符串中index处字符的方法

    这篇文章主要介绍了JavaScript基于扩展String实现替换字符串中index处字符的方法,涉及javascript使用substr方法针对字符串进行替换操作的相关实现技巧,需要的朋友可以参考下
    2017-06-06
  • NodeJS的模块写法入门(实例代码)

    NodeJS的模块写法入门(实例代码)

    前面提到了NodeJS的命令行和Web版之“Hello,World”。命令行是直接执行hello.js文件,Web版的需要require http模块。http模块是NodeJS自身提供的
    2012-03-03
  • 下载文件个别浏览器文件名乱码解决办法

    下载文件个别浏览器文件名乱码解决办法

    下载文件个别浏览器文件名乱码解决办法,需要的朋友可以参考一下
    2013-03-03
  • echarts横向柱状图简单实现方法

    echarts横向柱状图简单实现方法

    这篇文章主要给大家介绍了关于echarts横向柱状图简单实现的相关资料,ECharts是百度前端开发部开发的一个开源可视化库,它可以帮助开发者轻松的实现各种数据可视化,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • Javascript类型判断相关例题及解析

    Javascript类型判断相关例题及解析

    这篇文章主要介绍了Javascript类型判断相关例题及解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • JS操作Cookies包括(读取添加与删除)

    JS操作Cookies包括(读取添加与删除)

    一直都是简单去js实现cookie的一些操作,今天把js对cookie操作系统的整理了一遍,包括:js读取cookie,js添加cookie,js删除cookie
    2012-12-12
  • javascript中的if语句使用介绍

    javascript中的if语句使用介绍

    在javascript中的一些选择语句,其实jf语句就是一种,下面举几个不错的示例为大家介绍下,希望对大家学习有所帮助
    2013-11-11
  • 浅谈js多维数组和hash数组定义和使用

    浅谈js多维数组和hash数组定义和使用

    下面小编就为大家带来一篇浅谈js多维数组和hash数组定义和使用。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • 老生常谈Bootstrap媒体对象

    老生常谈Bootstrap媒体对象

    下面小编就为大家带来一篇老生常谈Bootstrap媒体对象。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07

最新评论