this指针与function变量--this究竟指向哪里?
参考文章:《深入浅出 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究竟指向哪里?的更多相关文章
- 指向函数的指针 ------ 函数指针(function pointer)
函数指针: 指向函数的指针, 首先是一个指针, 这个指针指向一个函数. 函数具有可赋值给指针的物理内存地址,一个函数的函数名就是一个指针,它指向函数的代码.一个函数的地址是该函数的进入点,也是调用函数 ...
- c语言常量指针赋值给变量指针导致警告
常量指针定义:常量是形容词,指针是名词,以指针为中心的一个偏正结构短语.这样看,常量指针本质是指针,常量修饰它,表示这个指针乃是一个指向常量的指针.指针指向的对象是常量,那么这个对象不能被更改.常量指 ...
- C 函数与指针(function & pointer)
C 函数与指针(function & pointer) /* * function.c * 函数在C中的使用 * */ #include <stdio.h> int noswap( ...
- 嵌入式-C语言基础:指针是存放变量的地址,那为什么要区分类型?
指针是存放变量的地址,那为什么要区分类型?不能所有类型的变量都用一个类型吗?下面用一个例子来说明这个问题. #include<stdio.h> int main() { int a=0x1 ...
- 问题:C++ 删除数组指针实用 delete []变量 汇编怎么实现的?
问题:C++ 删除数组指针实用 delete []变量 汇编怎么实现的?
- golang中值类型/指针类型的变量区别总结
转自:https://segmentfault.com/a/1190000012329213 值类型的变量和指针类型的变量 先声明一个结构体: type T struct { Name string ...
- android studio2.3.3 模拟器 Jni函数调用C++对象,lldb调试this指针和相关变量显示无效的原因
android studio2.3.3 的版本中 Jni函数调用C++对象,对象调用相关的成员函数, lldb调试,变量跟踪窗口,this指针和相关变量显示无效的原因,但这些参数实际是有效的,只是de ...
- function变量困惑
var name = "The Window"; var object = { name : "My Object", getNameFunc : functi ...
- C++ 虚指针、成员变量与类对象的偏移地址
先给出一段代码实现 #include <iostream> using namespace std; class animal { protected: int age; public: ...
随机推荐
- C#核编之字符串类型介绍与操作
一.关于字符串操作的方法 System.String类提供了很多工具方法,包括返回字符数据长度,查找当前字符串中的子字符串和转换大小写等方法. 在String类中常用的比较字符串的方法主要有Compa ...
- 附加导航(Affix)行为
用法 通过 data 属性:如需向元素添加附加导航(Affix)行为,只需要向需要监听的元素添加 data-spy="affix" 即可.请使用偏移来定义何时切换元素的锁定和移动. ...
- 【JS】导出table到excel,同时兼容FF和IE
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- C#读取txt文件返回DATATABLE
//1.打开资源管理器 OpenFileDialog open = new OpenFileDialog(); if (open.ShowDialog() == DialogResult.OK) { ...
- 《高性能JavaScript》的新征程
已经学了<JavaScript语言精粹>,现在学高性能. JS的出现是为了改善网页用户体验的,随着互联网通信速度的改善.计算机性能的提升,web越发丰富:但一段时间内,JS的引擎变化不大. ...
- JVM ClassLoader加载过程
虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是Java虚拟机的类加载机制. 1)三个类加载器: bootstra ...
- 如何在linux中设置tab键长度
1. 创建文件名为 .vimrc 的系统文件 首先切换到用户根目录,然后创建文件. $ cd ~ $ vim .vimrc 2. 在文件中输入下面的内容并保存 set tabstop=4 set sh ...
- javascript中this,call,apply详解
javascript是一门解释型的语言,与很多面向对象语言相比有着不同特性,所以不能用面向对象的原理来理解this这个关键字. 在JS中,要真正理解this倒底指向哪个对象,必须先了解JS的作用域和原 ...
- Centos查看端口占用情况和开启端口命令
Centos查看端口占用情况命令,比如查看80端口占用情况使用如下命令: lsof -i tcp:80 列出所有端口 netstat -ntlp 1.开启端口(以80端口为例)方法一: /sbin/i ...
- js/jquery获取当前页面URL地址并判断URL字符串中是否包含某个具体值
js/jquery获取当前页面URL地址并判断URL字符串中是否包含某个具体值本文介绍jquery/js获取当前页面url地址的方法,在jquery与js中获取当前页面url方法是一样的,因为jque ...