javascript中this指针探讨

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

  一、方法调用模式:

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


 1 var myObj = {
2 value: 0,
3 increase: function(){
4 this.value++;
5 console.log(this.value);
6 }
7 };
8 // this绑定到myObj对象上
9 myObj.increase(); // 1
10
11 myObj2 = {
12 value: 10
13 };
14 myObj2.increase = myObj.increase;// myObj2与myObj的increase指向同一函数引用地址
15 // this绑定到myObj2对象上
16 myObj2.increase(); // 11

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


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

  二、函数调用模式:

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


 1 var value = -10;
2 var myObj = {
3 value: 0,
4 increase: function(){
5 this.value++;
6 console.log(this.value);
7 }
8 };
9 // this绑定到myObj对象上
10 myObj.increase(); // 1
11
12 var gInc = myObj.increase;
13 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(); // 1

var gInc = myObj.increase;
gInc(); // -8
///////////////
//1
//-9
//-8
//-7

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


 1 var myObj = {
2 value: 0,
3 increase: function(){
4 this.value++;
5 console.log(this.value);
6 var that = this;
7 var other = function(){
8 that.value++;
9 console.log(that.value);
10 };
11 other();// -9, 这时other中的this绑定到window对象上
12 }
13 };
14 // this绑定到myObj对象上
15 myObj.increase(); // 1
16 //////////////
17 //1
18 //2

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

  三、构造器模式调用:

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


1 var P = function(n){
2 this.name = n;
3 }
4 P.prototype.getName = function(){
5 console.log(this.name);
6 }
7 var p = new P(‘woodtree‘); // 这时P中的this对象呗绑定p指向的对象引用上
8 p.getName();// woodtree

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


 1 var P = function(n){
2 this.name = n;
3 }
4 P.prototype.getName = function(){
5 console.log(this.name);
6 }
7 var p = new P(‘woodtree‘);
8 p.getName();
9
10 Object.prototype.create = Object.create || function(proto){
11 var F = function(){};
12 F.prototype = proto;
13 return new F();
14 }
15
16 Function.prototype.create = function(){
17 var that = object.create(this.prototype);
18 var obj = this.apply(that, arguments);
19
20 return obj || that;
21 }
22 var p2 = P.create(‘hello new‘);
23 p2.getName(); // hello new

  四、apply、call模式调用:

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


 1 var P = function(n){
2 this.name = n;
3 }
4 P.prototype.getNameAndAge = function(age){
5 console.log(this.name + age);
6 }
7
8 P.prototype.getNameAndAge.call({
9 name: ‘catboat‘
10 }, 99);
11 P.prototype.getNameAndAge.apply({
12 name: ‘lanuch‘
13 }, [99]);

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


 1 var P = function(n){
2 this.name = n;
3 }
4 P.prototype.getNameAndAge = function(age, age2){
5 console.log(this.name + age + age2);
6 }
7
8 P.prototype.getNameAndAge.call({
9 name: ‘catboat‘
10 }, 99);
11 P.prototype.getNameAndAge.apply({
12 name: ‘lanuch‘
13 }, [99]);
14
15 Function.prototype.bindContext = function(that){
16 var _method = this,
17 slice = Array.prototype.slice,
18 args = slice.call(arguments, 1);
19
20 return function(){
21 _method.apply(that, Array.prototype.concat.apply(args, arguments));
22 }
23 };
24
25 var f1 = P.prototype.getNameAndAge.bindContext({
26 name: ‘barque‘
27 }, 88);
28 f1(9);

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

1 var addEvent = document.addEventListener ? function(el, type, fn, capture){
2 return el.addEventListener(type, fn, capture);
3 } : function(el, type, fn){
4 el.attachEvent(‘on‘ + type, fn.bindContext(el, event));
5 }

javascript中this指针探讨,布布扣,bubuko.com

时间: 2024-11-04 01:57:33

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

JavaScript中的指针

引用:http://developer.51cto.com/art/201103/250108.htm 对JavaScript中call和apply的理解 1.相同点: a) 产生的效果或作用完全相同: b) 至少有一个参数: c) 第一个参数必须有且是一个对象(Object),因为就是这个家伙偷懒. 2.不同点: 传递参数的方式. 前提: 1.有两个对象: A和B: 2.B有一个方法(这里用Function代替): 3.B的方法(Function)有两种参数传递的方式,但该方法产生的结果一样.

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

没搞错吧!js写了那么多年,this还是会搞错!没搞错,javascript就是回搞错! ………… 文章来源自——周陆军的个人网站:http://zhoulujun.cn/zhoulujun/html/webfront/ECMAScript/jsBase/2016_0329_7729.html 在写java的时候,this用错了,idea都会直接报错! 比如…… 但是,js,……idea,爱莫能助了…… 在面向对象编程里有两个重要的概念:一个是类,一个是实例化的对象,类是一个抽象的概念,用个形象

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

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象 这一点与函数中自由变量Action-varibal不同 1 var object = { 2 name : 'The Kite Runner', 3 obj : { 4 name : 'childProperty', 5 fn : function(x, y){ 6 var result = x + y; 7 console.log('this-context'

通过挟持 this 指针在 JavaScript 中模拟 private

转帖:http://ucren.com/demos/private/private.html JavaScript 是一种解释型的.基于对象的脚本语言,没有严格意义上的类,在这一点上不同于 C++.Smalltalk 或者 Java,不过作为替代,它支持构造函数(constructors),可通过执行代码创建对象:给对象分配存储,然后通过赋初始值来初始化对象属性的全部或部分.构造函数有个指向其原型对象的属性叫做 prototype,利用 prototype 可模拟出一个基本可用的“类”来. 类有

由javascript中的this指针所想到的

初次结识 this 指针,是在学 <<C++ Primer Plus>>这本书的时候(这本书勉强读了一二遍,之后转学 html+css+js了,不过这是后话). 依稀记得书中举了个例子,就是说两个对象在调用记法进行比较时,怎样来指代对象自身呢?在详细罗列了一系列问题后,引入了 this 指针. 有天晚上,vbs群里突然一哥们发了段代码,说不是太理解 this 指针. 我就发了一大段文字谈了自己的理解,具体咋说的忘记了,只记得这哥们说看来自己也得学下 c++才行. javascrip

(转)详解Javascript 中的this指针

前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的设计模式来实现面向对象的编程,其中this “指针”就是实现面向对象的一个很重要的特性.但是this也是Javascript中一个非常容易理解错,进而用错的特性.特别是对于接触静态语言比较久了的同志来说更是如此. 示例说明 我们先来看一个最简单的示例: <script type="text/javascript"> v

JavaScript中指针和地址理解

个人理解:指针只是指向内存的一个索引:而地址则是内存中确切的位置. 下面是函数中关于指针和地址一个小例子: function sum(num1,num2){ return num1+num2; } alert(sum(10,10)); //20 var anotherSum=sum; alert(anotherSum(10,10)); //20 sum=null; alert(anotherSum(10,10)); //20 注意:使用不带圆括号的函数的名是访问函数指针,而非调用函数,所以 su

javascript中的原始值和复杂值

前面的话 javascript的数据类型可以分为两种:原始类型(基本类型或者简单类型)和引用类型. 原始类型:Undefined,Null,Boolean,Number,String五种: 引用类型:Object,Array,Function: 与此相对应的,它们的值分别被称为原始值和复杂值. 特性 原始值 原始值是表示javascript中可用的数据或信息的最底层的形式或者最简单的形式.原始类型的值被称为原始值,因为它们的值是不可被细化的.也就是说,数字是数字,字符串是字符串,布尔值是true

浅谈JavaScript中继承的实现

  谈到js中的面向对象编程,都有一个共同点,选择原型属性还是构造函数,两者各有利弊,而就片面的从js的对象创建以及继承的实现两个方面来说,官方所推荐的是两个相结合,各尽其责,各取其长,在前面的例子中,我已就在JavaScript中对象创建的方法做了一些总结,下面就其继承来道说一二:   1:原型链继承: 每一个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象内部的指针(默认的原型,所有默认类型都继承了Object,而这个继承也是用过原型链实现) fu