参考文章:《深入浅出 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. nodejs实现本地上传图片并预览功能(express4.0+)

    Express为:4.13.1  multyparty: 4.1.2 代码主要实现本地图片上传到nodejs服务器的文件下,通过取图片路径进行图片预览 写在前面:计划实现图片上传预览功能,但是本地图片 ...

  2. css3实现图片遮罩效果鼠标hover以后出现文字

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  3. 使用ADO.net中的链接字符串

    需要引用:System.Configuration命名空间 ConfigurationManager.ConnectionStrings["sqlConnStr"].Connect ...

  4. Oracle如何禁止并行

    PURPOSE -------   To explain how to disable Parallel Execution on Session/System level     SCOPE &am ...

  5. Hibernate学习之注解学习

    转自:http://blog.sina.com.cn/s/blog_935ebb670101dnre.html 1.类级别注解 @Entity   映射实体类 @Table    映射数句库表 @En ...

  6. php变量的引用及函数的引用

    Php变量的引用及函数的引用放回 变量的引用    $a="ABC";    $b =&$a;    echo $a;//这里输出:ABC    echo $b;//这里输 ...

  7. php 迭代器与和生成器

    php有很多功能强大的接口,其中ArrayAccess 与 Iterator 的配合使用可以让对象与数组一样有着灵活的访问性. 当然,用ArrayAccess 与 Iterator 配合可以用来对付数 ...

  8. DTU软硬件方案

        经过周末的思考以及已有的经验,准备将DTU研发项目命名为QN100,确定了初步的软硬件方案,产品名称大家如果有好的名字欢迎提供.     硬件:     采用STM32F101RD为主处理器, ...

  9. android:TextAppearance.Material.Widget.Button.Inverse问题

    如果在刚够构建Android Studio项目的时候,运行发现,出现没找到资源的错误!找不到com.android.support/appcompat-v7/23.0.1/res/values-v23 ...

  10. C/C++ 用libcurl库进行http通讯网络编程

    C/C++ 用libcurl库进行http通讯网络编程 目录索引: 一.LibCurl基本编程框架 二.一些基本的函数 三.curl_easy_setopt函数部分选项介绍 四.curl_easy_p ...