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: ...
随机推荐
- 缓存 Array.length 是老生常谈的小优化
问题 缓存 Array.length 是老生常谈的小优化. // 不缓存 for (var i = 0; i < arr.length; i++) { ... } // 缓存 var len = ...
- Zepto.js touch模块深入分析 解决手机点击事件
源码: // Zepto.js // (c) 2010-2015 Thomas Fuchs // Zepto.js may be freely distributed under the MIT li ...
- sqlserver数据库三范式的理解
从来都是听过概念,过一段时间就忘记了,根本就没有深入的理解.这次梳理一遍,用自己的方式记录一下. 1nf 原子性,不可拆分性 例如一张表里包含一个class属性(软件系,外语系,经贸系...)字段,这 ...
- 查看当前支持的MySQL字符集的命令
查看不同的MySQL字符集有不同的方法,下面介绍的命令用于查看当前支持的MySQL字符集,希望对您学习MySQL字符集能有所帮助. mysql> show char set; +-------- ...
- 安卓开发之RecyclerView
RecyclerView是一个非常好用的控件,它的效果和ListView很相似,甚至可以说RecyclerView的出现是来取代ListView的 RecyclerView比ListView更加灵活, ...
- Linux 脚本整理
本页主要用来记录一点 Shell 脚本. 1. cd - #切换回上一次的路径 这个命令对 cd 频繁的操作很有用 2. sudo !! #授权给上次录入的命令 比如一般非 root 用户在执行 if ...
- css selection改变文字反选的背景颜色
<style type="text/css"><!--.ai::-moz-selection { background:#cc0000; color:#fff; ...
- Qt5 多显示器获取不同显示器的分辨率和位置的方法
Qt5 多显示器获取不同显示器的分辨率和位置的方法 先放官方文档链接:QDesktopWidget - Qt5 Reference 之前一直在用被我乱搞后的ShadowPlayer作为默认播放器,后来 ...
- AOP-----动态代理(转)
动态代理是实现AOP的绝好底层技术 JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler.其中 InvocationHandler是 ...
- java接口的理解
接口的最主要的作用是达到统一访问,就是在创建对象的时候用接口创建,[接口名] [对象名]=new [实现接口的类],这样你像用哪个类的对象就可以new哪个对象了,不需要改原来的代码,就和你的USB接口 ...