Javascript中的this

下面列举一些简单的实例 总结一下this的一些用法:

1.方法中的this会指向当前执行该方法的对象 如:

var name = "window"

var Tom = {

  name:"Tom";

  show:function(){alert(this.name)}

}

Tom.show();   //Tom

2.方法中的this不会指向声明它的对象 如下

var Bob={
  name:"Bob",
  show:function(){alert(this.name);}
  };

var Tom={
  name:"Tom",
  show:Bob.show
  };

Tom.show() ;   //Tom

因为尽管alert(this.name)是在Bob对象环境中声明的

但该方法是由Tom对象调用执行所以this总是会指向当前执行的对象,而不是声明的对象

3.将方法复制给变量时,执行时仍然会以Tom对象区调用该方法

var name="window";
var Tom={
  name:"Tom".
  show:function(){alert(this.name)}
  };

var fun=Tom.show();
fun();              //Tom

可以看出赋值后再调用,并不影响调用其方法的对象

4.将对象赋值给变量后,再调用方法,执行的对象仍然是Tom

var name="window";
var Tom={
  name:"Tom",
  show:function(){alert(this.name)},
  wait:function(){
             var that=this;
             that.show();
         }
  };

Tom.wait();  //Tom

这里that赋值了当前执行的对象,并让它继续调用show,

所以show方法中alert(this.name)自然而然的指向了Tom

可以把上面的 "that赋值对象 然后调用方法" 这个过程看做成执行对象

的延迟,就是让Tom加班的意思

5.另一种 指明调用方法的对象 的办法 如下:

var name = "window";
var Bob= {
    name:"Bob",
    show:function(){alert(this.name);}
    };

 var Tom= {name: "Tom"};
 Bob.show();                   //Bob
 Bob.show.apply();             //window
 Bob.show.apply(Tom);          //Tom

当然call()也差不多类似

6.下面来个特殊的例子

var name="window";
var Tom={
  name:"Tom",
  show:function(){alert(this.name)},
  wait:function(){
             var fun=this.show;
             fun();
         }
  };

Tom.wait();  //window

上面也是赋值方法后,再调用,可是执行的对象却改成了window对象

解释:

在函数体内把方法赋值给变量再调用会导致对象更改为Window对象

执行fun时,可以看做是一种方法调用的延迟行为,延迟调用方法会使得执行的对象

变为全局对象也就是window对象

下面我们来看看其他几种延迟方式,导致对象被更改为window的例子

7.匿名函数的延迟

var name="window";
var Tom={
  name:"Tom",
  show:function(){alert(this.name)},
  wait:function(){!function(call){call();}(this.show)}
  }

Tom.wait();    //Window

8.setTimeout、setInterval函数延迟
这里只以setTimeout为例子

var name="window";
var Tom={
  name:"Tom",
  show:function(){alert(this.name)},
  wait:function(){setTimeout(this.show,1000)}
  }

Tom.wait();    //window

9. 在延迟的环境下 尝试让Tom加班(对象也跟着延迟)

var name="window";
var Tom={  name:"Tom",
show:function(){alert(this.name)},
wait:function(){setTimeout(Tom.show,1000)}  }

Tom.wait();    //window  

上面中this对象改成了Tom,尝试让Tom加班,但是结果仍然为Window对象

因为Tom.show放在第一个参数里,延迟的执行使得执行的对象变为window对象

而不再是Tom对象,如何让执行对象Tom在延迟当不被变更呢?下面给你答案

10.虽然延迟会导致方法的执行对象被更改为Window 但也有办法防止执行对象更改 如下

var name="window"
var  Tom ={
    name : "Tom",
    show : function(){alert(this.name);},
    wait:  function(){
    var that=this;
    setTimeout(function(){that.show()},1000)}
          }

Tom.wait();    //Tom 

如果不能理解上面的代码,你就当做Tom对象也跟着函数一起延迟就好了

而第9个例子没有成功延迟,是因为没有变量保存对象使得执行对象没有跟着延迟

11.eval函数的延迟

对于eval比较特殊

在eval环境下,执行的对象就是当前作用域的对象 如下

var name="window";
var Bob={
  name:"Bob",
  showName: function(){ eval("alert(this.name)"); }
  };

Bob.showName(); //Bob

12.eval函数的环境下,不会受到延迟而影响函数执行的对象

之所以eval特殊是因为eval不受延迟的影响

var name="window";
var that;
var Tom={
  name:"Tom",
  show:function(){alert(this.name)},
  wait:function(){that=this;setTimeout("that.show()",1000)}
  }

Tom.wait();    //Tom

也许你会觉得上面的代码没有eval函数的身影

其实setTimeout函数的第一个参数就是eval环境

他会指向当前执行作用域的执行对象,忽略延迟方法延迟调用

如果能把上面12个例子都理解了,那么this将成为你的一把有力的刀,挥舞在你代码中

当然如果不能理解,那么像闭包一样 尽量的少用!

时间: 2024-12-20 18:48:34

Javascript中的this的相关文章

实现一个函数clone,使JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制

实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number.String.Object.Array.Boolean)进行值复制. 1 /** 对象克隆 2 * 支持基本数据类型及对象 3 * 递归方法 */ 4 function clone(obj) { 5 var o; 6 switch (typeof obj) { 7 case "undefined": 8 break; 9 case "string": o = obj + &q

javascript中的原始值和复杂值

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

【JS】JavaScript中的执行环境与作用域

JavaScript中的执行环境定义了变量或函数有权访问的数据(每个函数都有自己的执行环境),全局执行环境是最外围的执行环境,在浏览器中,全局执行环境就是window对象,所以所有的全局变量和函数都是作为window对象的属性和方法创建的.当某一个执行环境中所有代码执行完成后,该环境就被销毁,保存在其中的变量和函数也将被销毁,全局执行环境在关闭网页或浏览器时才被销毁. 当代码在一个环境中执行时,会创建变量对象的一个作用域链(保证对执行环境有权访问的变量和函数的有序访问),如果环境是函数,将其活动

JavaScript中的构造函数

function Accom(){};    //创建一个构造函数 //创建两个对象 var house=new Accom(); var apartment=new Accom(); 通过构造函数创建的对象有一个属性constructor,这个属性指向创建该对象时所用的Javascript构造函数. house.constructor===Accom;  或者   house instanceof Accom;     //true JavaScript中的每个构造函数都有一个prototyp

【转】十个JavaScript中易犯的小错误,你中了几枪?

在今天,JavaScript已经成为了网页编辑的核心.尤其是过去的几年,互联网见证了在SPA开发.图形处理.交互等方面大量JS库的出现. 如果初次打交道,很多人会觉得js很简单.确实,对于很多有经验的工程师,或者甚至是初学者而言,实现基本的js功能几乎毫无障碍.但是JS的真实功能却比很多人想象的要更加多样.复杂.JavaScript的许多细节规定会让你的网页出现很多意想不到的bug,搞懂这些bug,对于成为一位有经验的JS开发者很重要. 常见错误一:对于this关键词的不正确引用 我曾经听一位喜

JavaScript中Function的拓展

Function 是什么东西,就是JavaScript中的顶级类,系统级别的类.我们平时写的函数方法例如下. function Animal() { } Animal就是Function的实例,但是在我们的逻辑中 Animal是类,是自定义类. Function是类,Animal是类也是实例,Animal是Function的实例,Animal是自定义类.这点大家一定要搞清楚. 我们在顶级类上定义一个method的方法,用于进行键值对的方式进行方法链式的设定, Function.prototype

浅谈JavaScript中继承的实现

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

理清javascript中prototype、__proto__、Object、Function的关系,更好地理解原型继承

本文参考了http://www.blogjava.net/heavensay/archive/2013/10/20/405440.html这篇文章,对其内容作了个简单总结,形成了几条简单的结论,让读者更容易记住prototype.__proto__.Object.Function之间的关系. 结论1:Object.prototype只是一个普通对象,它是js原型链的最顶端. (typeof Object.prototype) === object;//true Object.prototype.

javascript中的立即执行函数(function(){…})()

javascript中的立即执行函数(function(){…})() 深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包住业务代码,使用jquery时比较常见. ( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法,最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达到函数定义后立即执行的目的,后来发现加括号的原因并非如此.要

javascript中的栈、队列。

                       javascript中的栈.队列 栈方法     栈是一种LIFO(后进先出)的数据结构,在js中实现只需用到2个函数 push()  接受参数并将其放置数组尾,并返回修改后的数组长度. pop()  移除数组尾的最后一项,并返回移除项的值. 事例: var colors = new Array();var count = colors.push("red","green"); count = colors.push(&