参考文章:《深入浅出 JavaScript 中的 this》 http://www.ibm.com/developerworks/cn/web/1207_wangqf_jsthis/

JavaScript的this指针为何如此让人琢磨不透、难于理解?这个问题研究了很久,总算有些眉目了。这个问题源于JavaScript是顺序执行的,是解释执行的,运行时才能动态绑定this指针。这区别于Java、C#等语言,它他们都编译后执行的,this指向当前的对象。

1.function类型变量

javascript中的function也可理解为一种数据类型,通过function来定义函数(方法)。

function hello() { }
alert(typeof(hello)); //输出function

this引用的对象究竟是什么?this指针指向一个对象,并且与function变量密不可分。要了解this指针的指向,需要先了解function变量是如何定义的。

2.function中的成员定义

function中可以定义三类:私有成员(var变量)、公有成员(this)和window对象成员。

   function Person() {
var age = 30;
this.name = "Bass";
income = 0;
}
//age //私有成员,不能在Person之外调用
//name //公有成员,需要通过Person类对象调用
var p = new Person();
alert(p.name);
//income //window对象成员,可以直接或通过window对象调用
income = 10000000;
window.income = window.income * 10;
alert(income);

3.this指针的指向

1) function变量作为对象方法被调用,此时this指针指向对象本身。

   var obj = {
hello: function (param) {
return (this == param)
}
}
alert(obj.hello(obj)); //输出true

2) function变量作为普通函数被调用,此时this指针指向window对象。

    function hello(param) {
return (this == param);
}
alert(hello(window)); //输出true
//window.hello(window); //2)可以理解为1)的特情况,2)定义的函数默认是定义在window对象的作用域内的,默认是window对象的方法。

3) function变量作为构造函数被调用,此时this指针指向新创建的类对象。

    function HelloWorld() { //为区别JavaScript类和普通JavaScript方法,HelloWorld首字母大写
this.hello = function (param) { //hello方法是定义在HelloWorld类中的,只能定义类实现,才能调用该方法
return (this == param);
}
} var obj = new HelloWorld();
alert(obj.hello(obj)); //输出true

4) function变量作为prototype方法被调用,此时this指针指向调用function的对象(新创建的类对象或prototype对象)。

prototype对象方法,是对拥有prototype对象的类的方法扩展,方法可视为是类的公有成员方法。

    function HelloWorld() { }
HelloWorld.prototype.hello = function (param) {
return (this == param);
}
alert(HelloWorld.prototype.hello(HelloWorld.prototype)); //输出true
var obj = new HelloWorld();
alert(obj.hello(obj)); //输出true
alert(obj == HelloWorld.prototype); //输出false

5) function变量调用call或apply方法来执行,此时this指针指向被改变,并指向call或apply方法的第一个参数所引用的对象。

    function HelloWorld() {
this.hello = function (param) {
alert(this == param);
}
}
var t1 = new HelloWorld();
var t2 = new Object();
t1.hello(t1); //输出true //直接调用方法,this指向不改变
t1.hello.call(t2, t1); //输出false //通过call方法调用,this指向改变,并指对象t2
t1.hello.call(t2, t2); //true

6) function变量作为html元素的事件处理方法被调用,此时this指针指向触法事件的元素本身 ,并可作为实参传入事件处理方法。

不太明白以下的测试结果,谁知道告诉我一下。

    <div onclick="hello(this)">
HelloWorld
</div>
    function hello(param) {
alert(this == param); //true
alert(this.innerText); //undefined
alert(this == window); //true
alert(param == window); //false
alert(param.innerText); //HelloWorld
alert(this.innerText); //undefined
}

以上就是我的测试验证结果,6)的结果不太明白为什么,我觉得this指向window还能理解,为什么this又等于param是为什么呢。麻烦知道的同鞋告诉我一下为什么?

this指针与function变量--this究竟指向哪里?的更多相关文章

  1. 指向函数的指针 ------ 函数指针(function pointer)

    函数指针: 指向函数的指针, 首先是一个指针, 这个指针指向一个函数. 函数具有可赋值给指针的物理内存地址,一个函数的函数名就是一个指针,它指向函数的代码.一个函数的地址是该函数的进入点,也是调用函数 ...

  2. c语言常量指针赋值给变量指针导致警告

    常量指针定义:常量是形容词,指针是名词,以指针为中心的一个偏正结构短语.这样看,常量指针本质是指针,常量修饰它,表示这个指针乃是一个指向常量的指针.指针指向的对象是常量,那么这个对象不能被更改.常量指 ...

  3. C 函数与指针(function & pointer)

    C 函数与指针(function & pointer) /* * function.c * 函数在C中的使用 * */ #include <stdio.h> int noswap( ...

  4. 嵌入式-C语言基础:指针是存放变量的地址,那为什么要区分类型?

    指针是存放变量的地址,那为什么要区分类型?不能所有类型的变量都用一个类型吗?下面用一个例子来说明这个问题. #include<stdio.h> int main() { int a=0x1 ...

  5. 问题:C++ 删除数组指针实用 delete []变量 汇编怎么实现的?

    问题:C++ 删除数组指针实用  delete []变量    汇编怎么实现的?

  6. golang中值类型/指针类型的变量区别总结

    转自:https://segmentfault.com/a/1190000012329213 值类型的变量和指针类型的变量 先声明一个结构体: type T struct { Name string ...

  7. android studio2.3.3 模拟器 Jni函数调用C++对象,lldb调试this指针和相关变量显示无效的原因

    android studio2.3.3 的版本中 Jni函数调用C++对象,对象调用相关的成员函数, lldb调试,变量跟踪窗口,this指针和相关变量显示无效的原因,但这些参数实际是有效的,只是de ...

  8. function变量困惑

    var name = "The Window"; var object = { name : "My Object", getNameFunc : functi ...

  9. C++ 虚指针、成员变量与类对象的偏移地址

    先给出一段代码实现 #include <iostream> using namespace std; class animal { protected: int age; public: ...

随机推荐

  1. 缓存 Array.length 是老生常谈的小优化

    问题 缓存 Array.length 是老生常谈的小优化. // 不缓存 for (var i = 0; i < arr.length; i++) { ... } // 缓存 var len = ...

  2. Zepto.js touch模块深入分析 解决手机点击事件

    源码: // Zepto.js // (c) 2010-2015 Thomas Fuchs // Zepto.js may be freely distributed under the MIT li ...

  3. sqlserver数据库三范式的理解

    从来都是听过概念,过一段时间就忘记了,根本就没有深入的理解.这次梳理一遍,用自己的方式记录一下. 1nf 原子性,不可拆分性 例如一张表里包含一个class属性(软件系,外语系,经贸系...)字段,这 ...

  4. 查看当前支持的MySQL字符集的命令

    查看不同的MySQL字符集有不同的方法,下面介绍的命令用于查看当前支持的MySQL字符集,希望对您学习MySQL字符集能有所帮助. mysql> show char set; +-------- ...

  5. 安卓开发之RecyclerView

    RecyclerView是一个非常好用的控件,它的效果和ListView很相似,甚至可以说RecyclerView的出现是来取代ListView的 RecyclerView比ListView更加灵活, ...

  6. Linux 脚本整理

    本页主要用来记录一点 Shell 脚本. 1. cd - #切换回上一次的路径 这个命令对 cd 频繁的操作很有用 2. sudo !! #授权给上次录入的命令 比如一般非 root 用户在执行 if ...

  7. css selection改变文字反选的背景颜色

    <style type="text/css"><!--.ai::-moz-selection { background:#cc0000; color:#fff; ...

  8. Qt5 多显示器获取不同显示器的分辨率和位置的方法

    Qt5 多显示器获取不同显示器的分辨率和位置的方法 先放官方文档链接:QDesktopWidget - Qt5 Reference 之前一直在用被我乱搞后的ShadowPlayer作为默认播放器,后来 ...

  9. AOP-----动态代理(转)

    动态代理是实现AOP的绝好底层技术 JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler.其中 InvocationHandler是 ...

  10. java接口的理解

    接口的最主要的作用是达到统一访问,就是在创建对象的时候用接口创建,[接口名] [对象名]=new [实现接口的类],这样你像用哪个类的对象就可以new哪个对象了,不需要改原来的代码,就和你的USB接口 ...