javascript是一门类java语言有很多跟java相类似的特点,但也仅是类似而已,真正使用中还是有很大的差别。this指针常常让很多初学者抓狂,本人也曾为此困惑不解,查找过很多资料,今天在这里总结一下,希望能帮助后来者更快驯服这只拦路虎。网上有很多讲解this指针的文章其中不乏精品,以我看来了解this指针关键在于掌握javascript中函数的四种调用模式。那么什么是调用?调用指的是跟在任何产生一个函数值的表达式之后使用"()",obj.f()这种方式成为调用,obj.f这种方式称为访问。

  一、方法调用模式:

  在该调用模式中函数作为一个对象的方法被调用:obj.fun()。当函数以此种形式被调用时this指针绑定到调用该方法的对象上即obj。

 var myObj = {
value: 0,
increase: function(){
this.value++;
console.log(this.value);
}
};
// this绑定到myObj对象上
myObj.increase(); // myObj2 = {
value: 10
};
myObj2.increase = myObj.increase;// myObj2与myObj的increase指向同一函数引用地址
// this绑定到myObj2对象上
myObj2.increase(); //

  所以在将一个html元素的某一事件绑定某一函数时,若函数中使用this指针,则this指针会被绑定到该元素上。

 var ele1 = document.getElementById('id');
ele1.addEventListener('click', myObj.increase, false);
// 该绑定相当于
ele1.onclick = myObj.increase;
// 事件触发时即相当于调用click方法
ele1.click(); // 与上文中myObj2.increase一个道理,若ele1中没有value属性则会报错

  二、函数调用模式:

  当函数没有当做方法调用即没有被一个对象通过点语法,这时它被当做一个函数来调用。以此模式调用函数时,this被绑定到全局对象。

 var value = -10;
var myObj = {
value: 0,
increase: function(){
this.value++;
console.log(this.value);
}
};
// this绑定到myObj对象上
myObj.increase(); // var gInc = myObj.increase;
gInc(); // -9 this绑定到window对象上

  所以在方法中使用内部函数时要特别注意,下例中other函数中的this并未绑定到myObj对象上

var value = -10;
var myObj = {
value: 0,
increase: function(){
this.value++;
console.log(this.value);
var other = function(){
this.value++;
console.log(this.value);
};
other();// -9, 这时other中的this绑定到window对象上
}
};
// this绑定到myObj对象上
myObj.increase(); // var gInc = myObj.increase;
gInc(); // -8
///////////////
//
//-9
//-8
//-7

  幸运的是我们可以使用以下方式来在other中访问myObj对象:

 var myObj = {
value: 0,
increase: function(){
this.value++;
console.log(this.value);
var that = this;
var other = function(){
that.value++;
console.log(that.value);
};
other();// -9, 这时other中的this绑定到window对象上
}
};
// this绑定到myObj对象上
myObj.increase(); //
//////////////
//
//

  作为浏览器兼容性中很重要的一条:element.attachEvent绑定事件方法,当该事件触发时this指针并未绑定到element对象上,而是绑定到了window对象上,原因在于IE中事件触发时,响应函数是以一个独立函数即函数调用模式来调用的

  三、构造器模式调用:

  如果在一个函数前面加上new调用则成为构造器模式调用。使用new运算符,会产生一个连接到该函数prototype的新对象,this指针则被绑定到这个新对象上。

 var P = function(n){
this.name = n;
}
P.prototype.getName = function(){
console.log(this.name);
}
var p = new P('woodtree'); // 这时P中的this对象呗绑定p指向的对象引用上
p.getName();// woodtree

  同时new运算符还会改变函数的返回值。以函数调用模式调用P即P()返回undefined,而通过new运算符则返回一个新对象。new运算符类似于以下Function.prototype.create函数:

 var P = function(n){
this.name = n;
}
P.prototype.getName = function(){
console.log(this.name);
}
var p = new P('woodtree');
p.getName(); Object.prototype.create = Object.create || function(proto){
var F = function(){};
F.prototype = proto;
return new F();
} Function.prototype.create = function(){
var that = object.create(this.prototype);
var obj = this.apply(that, arguments); return obj || that;
}
var p2 = P.create('hello new');
p2.getName(); // hello new

  四、apply、call模式调用:

  javascript中函数对象继承自Object亦可以拥有方法。call跟apply允许我们选择this的绑定对象。这两个方法的区别在于apply第二个参数必须是一个数组或者类数组对象即拥有length属性(arguments、NodeList、HTMLElementCollection等),而call除了第一个参数为要绑定this的对象外,后可跟无数的参数,参数之间用逗号间隔。

 var P = function(n){
this.name = n;
}
P.prototype.getNameAndAge = function(age){
console.log(this.name + age);
} P.prototype.getNameAndAge.call({
name: 'catboat'
}, 99);
P.prototype.getNameAndAge.apply({
name: 'lanuch'
}, [99]);

  通过使用apply与call方法我们可以自行实现ES5中的bind函数

 var P = function(n){
this.name = n;
}
P.prototype.getNameAndAge = function(age, age2){
console.log(this.name + age + age2);
} P.prototype.getNameAndAge.call({
name: 'catboat'
}, 99);
P.prototype.getNameAndAge.apply({
name: 'lanuch'
}, [99]); Function.prototype.bindContext = function(that){
var _method = this,
slice = Array.prototype.slice,
args = slice.call(arguments, 1); return function(){
_method.apply(that, Array.prototype.concat.apply(args, arguments));
}
}; var f1 = P.prototype.getNameAndAge.bindContext({
name: 'barque'
}, 88);
f1(9);

  同样我们也可以解决IE中事件触发时,this指针问题(以下代码来自《Javascript框架设计》):

 var addEvent = document.addEventListener ? function(el, type, fn, capture){
return el.addEventListener(type, fn, capture);
} : function(el, type, fn){
el.attachEvent('on' + type, fn.bindContext(el, event));
}

javascript中this指针探讨的更多相关文章

  1. javascript中this指针

    看完此片文章豁然开朗,非常感谢.javascript技术难点(三)之this.new.apply和call详解 下面说一说自己的理解: this指针总是指向调用他的对象,其实我更愿意理解为:this指 ...

  2. 图说js中的this——深入理解javascript中this指针

    没搞错吧!js写了那么多年,this还是会搞错!没搞错,javascript就是回搞错! ………… 文章来源自——周陆军的个人网站:http://zhoulujun.cn/zhoulujun/html ...

  3. javascript中this指针的认识

    javascript中上下文环境就是this指针,即被调用函数所处的环境.这个上下文环境在大多数情况下指的是函数运行时封装这个函数的那个对象:当不通过任何对象单独调用一个函数时,上下文环境指的就是全局 ...

  4. JavaScript中this指针指向的彻底理解

    this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象 这一点与函数中自由变量Action-varibal不同 var ...

  5. 彻底理解javascript中的this指针

    http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/ https://www.benn ...

  6. 由javascript中的this指针所想到的

    初次结识 this 指针,是在学 <<C++ Primer Plus>>这本书的时候(这本书勉强读了一二遍,之后转学 html+css+js了,不过这是后话). 依稀记得书中举 ...

  7. 深入认识JavaScript 中的this指针

    深入认识JavaScript 中的this指针this指针是面向对象程序设计中的一项重要概念,它表示当前运行的对象.在实现对象的方法时,可以使用this指针来获得该对象自身的引用.和传统意义的面向对象 ...

  8. 从函数调用的角度,探讨JavaScript中this的用法

    js函数调用方式大概可分为:函数调用,构造器调用,call或apply,方法调用四种方式.下面结合一些基础概念和实测代码,从函数调用的角度,探讨JavaScript中this的用法. 1. new对函 ...

  9. <javaScript>谈谈JavaScript中的变量、指针和引用

    1.变量我们可能产生这样一个疑问:编程语言中的变量到底是什么意思呢?事实上,当我们定义了一个变量a时,就是在存储器中指定了一组存储单元,并将这组存储单元命名为a.变量a的值实际上描述的是这组存储单元中 ...

随机推荐

  1. android中回调函数机制完全解析

    1.在要调用的业务操作中,创建一个接口,在接口中创建方法,这个方法表示的是我们原先要在业务类中执行的操作 public interface BackUpSmsListener { /** * 设置总进 ...

  2. 使用 hexdump dump 文件内容

    名词解释 [dump] dump 是指把文件的内容,每个字节用2位十六进制数来表示的方式. 缘由 最近看矢泽久雄的<How Program Works>,了解到 dump “exe文件”( ...

  3. intel显卡笔记本恢复屏幕亮度调整功能

    更新Intel显卡驱动后不能修改屏幕亮度,可以在注册表里面搜索featuretestcontrol,将f000修改为ffff,重启后就可以通过Fn+F4/F5调整屏幕亮度了. 注:此方法适用于带有in ...

  4. [php-src]Php扩展的内存泄漏处理思路

    内容均以php5.6.14为例. 一. 封装函数时产生 memory leaks. [weichen@localhost www]$ php .php [,] [Tue Jul :: ] Script ...

  5. PMI列子1

    遍历得到PMI中,是注释类型的,你可以参考一下.int num_text, thetype, thesubtype;tag_t  draft_aid_tag = NULL_TAG;UF_UI_open ...

  6. css定位position认识

    1.绝对定位(position: absolute) 2.相对定位(position: relative) 3.固定定位(position: fixed) 绝对定位 设置position:absolu ...

  7. Win7 64位 VS2013环境cuda_7.5.18的一些坑

    thrust库的sort算法,在x86平台使用就崩溃,x64就没问题,搜了下好像是很早的版本,4开始就有这样的问题了,原因不明. http://stackoverflow.com/questions/ ...

  8. POJ 2096 Collecting Bugs (概率DP)

    题意:给定 n 类bug,和 s 个子系统,每天可以找出一个bug,求找出 n 类型的bug,并且 s 个都至少有一个的期望是多少. 析:应该是一个很简单的概率DP,dp[i][j] 表示已经从 j ...

  9. webapi版本升级管理

    由于近期公司人员流动,本人临时客串webapi开发,针对开发过程中碰到一些问题做一些改进 1.当前做法 项目webapi项目是居于asp.net框架开发的,每个功能模块新建一个api控制器,比如Use ...

  10. How to create Web Deployment Package and install the package

    Create Web Deployment Package To configure settings on the Connection tab In the Publish method drop ...