关于js里的this关键字的理解_javascript技巧

this关键字在c++,java中都提供了这个关键字,在刚开始学习时觉得有难度,但是只要理解了,用起来就方便多了,下面通过本篇文章给大家详解js里this关键字的理解。

关于this,是很多前端面试必考的题目,有时候在网上看到这些题目,自己试了一下,额,还真的错了!在实际开发中,也会遇到 this 的问题(虽然一些类库会帮我们处理),例如在使用一些框架的时候,例如:knockout,有时候不明白为什么不直接使用this,而要把 this 作为参数传入。

   接下来你谈谈我对它的理解,也作为一个笔记,方便以后参阅。有不对的地方,欢迎指出批评。

   1. 不像C#,this一定是指向当前对象。

js的this指向是不确定的,也就是说是可以动态改变的。call/apply 就是用于改变this指向的函数,这样设计可以让代码更加灵活,复用性更高。

   2. this 一般情况下,都是指向函数的拥有者。

这一点很重要!这一点很重要!这一点很重要!

   这也是一道常见的面试题,如下代码:

<script type="text/javascript">
  var number = 1;
  var obj = {
     number: 2,
    showNumber: function(){
      this.number = 3;
      (function(){
        console.log(this.number);
      })();
      console.log(this.number);
    }
  };
  obj.showNumber();
</script>

  由于showNumber方法的拥有者是obj,所以this.number=3; this 指向的就是 obj 的属性 number。

  同理,第二个 console.log 打印的也是属性 number。

   为什么第二点说一般情况下this都是指向函数的拥有者,因为有特殊情况。函数自执行就是特殊情况,在函数自执行里,this 指向的是:window。所以第一个 console.log 打印的是 window 的属性 number。

   所以要加一点:

   3. 在函数自执行里,this 指向的是 window 对象。

   扩展,关于this,还有一个地方比较让人模糊的是在 dom 事件里,通常有如下3种情况:

   如下:

   1. 使用标签属性注册事件,此时this 指向的是 window 对象。

<input id="test" type="button" value="按钮" onClick="test()"/>
  function test(){alert(this)}

   2. 对于1,要让 this 指向 input,可以将 this 作为参数传递。

   3. 使用 addEventListener 等注册。此时this 也是指向 input。

document.getElementById("test").addEventListener("click",test);

   在面向对象编程语言中,对于this关键字我们是非常熟悉的。比如C++、C#和Java等都提供了这个关键字,虽然在开始学习的时候觉得比较难,但只要理解了,用起来是非常方便和意义确定的。JavaScript也提供了这个this关键字,不过用起来就比经典OO语言中要"混乱"的多了。

  下面就来看看,在JavaScript中各种this的使用方法有什么混乱之处?

  1、在HTML元素事件属性中inline方式使用this关键字:

// 可以在里面使用this
">division element
 // 可以在里面使用this
 ">division element

我们一般比较常用的方法是在此使用:javascirpt: EventHandler(this),这样的形式。不过这里其实可以写任何合法的JavaScript语句,要是高兴在此定义个类也可以(不过将会是个内部类)。这里的原理是脚本引擎生成了一个div实例对象的匿名成员方法,而onclick指向这个方法。

   2、用DOM方式在事件处理函数中使用this关键字:

division element

 var div = document.getElementById('elmtDiv');
 div.attachEvent('onclick', EventHandler);  

 function EventHandler()
 {
 // 在此使用this
 }  

// --> 

division element

 var div = document.getElementById('elmtDiv');
 div.attachEvent('onclick', EventHandler);

 function EventHandler()
 {
 // 在此使用this
 }

// --> 

  这时的EventHandler()方法中的this关键字,指示的对象是IE的window对象。这是因为EventHandler只是一个普通的函数,对于attachEvent后,脚本引擎对它的调用和div对象本身没有任何的关系。同时你可以再看看EventHandler的caller属性,它是等于null的。如果我们要在这个方法中获得div对象引用,应该使用:this.event.srcElement。

  3、用DHTML方式在事件处理函数中使用this关键字:

division element

lt;mce:script language="javascript">
var div = document.getElementById('elmtDiv');
div.onclick = function()
{
 // 在此使用this
};  

/ --> 

division element

 var div = document.getElementById('elmtDiv');
 div.onclick = function()
 {
 // 在此使用this
 };

// --> 

  这里的this关键字指示的内容是div元素对象实例,在脚本中使用DHTML方式直接为div.onclick赋值一个EventHandler的方法,等于为div对象实例添加一个成员方法。这种方式和第一种方法的区别是,第一种方法是使用HTML方式,而这里是DHTML方式,后者脚本解析引擎不会再生成匿名方法。

  4、类定义中使用this关键字:

function JSClass()
{
var myName = 'jsclass';
this.m_Name = 'JSClass';
}  

JSClass.prototype.ToString = function()
{
alert(myName + ', ' + this.m_Name);
};  

var jc = new JSClass();
jc.ToString();
 function JSClass()
 {
 var myName = 'jsclass';
 this.m_Name = 'JSClass';
 }

 JSClass.prototype.ToString = function()
 {
 alert(myName + ', ' + this.m_Name);
 };

 var jc = new JSClass();
 jc.ToString(); 

  这是JavaScript模拟类定义中对this的使用,这个和其它的OO语言中的情况非常的相识。但是这里要求成员属性和方法必须使用this关键字来引用,运行上面的程序会被告知myName未定义。

5、为脚本引擎内部对象添加原形方法中的this关键字:

function.prototype.GetName = function()
{
var fnName = this.toString();
fnName = fnName.substr(0, fnName.indexOf('('));
fnName = fnName.replace(/^function/, '');
return fnName.replace(/(^\s+)|(\s+$)/g, '');
}
function foo(){}
alert(foo.GetName());
 function.prototype.GetName = function()
 {
 var fnName = this.toString();
 fnName = fnName.substr(0, fnName.indexOf('('));
 fnName = fnName.replace(/^function/, '');
 return fnName.replace(/(^\s+)|(\s+$)/g, '');
 }
 function foo(){}
 alert(foo.GetName()); 

  这里的this指代的是被添加原形的类的实例,和4中类定义有些相似,没有什么太特别的地方。

  6、结合2&4,说一个比较迷惑的this关键字使用:

view plaincopy to clipboardprint?
function JSClass()
{
this.m_Text = 'division element';
this.m_Element = document.createElement('DIV');
this.m_Element.innerHTML = this.m_Text;  

this.m_Element.attachEvent('onclick', this.ToString);
}  

JSClass.prototype.Render = function()
{
document.body.appendChild(this.m_Element);
}   

JSClass.prototype.ToString = function()
{
alert(this.m_Text);
};  

var jc = new JSClass();
jc.Render();
jc.ToString();
 function JSClass()
 {
 this.m_Text = 'division element';
 this.m_Element = document.createElement('DIV');
 this.m_Element.innerHTML = this.m_Text;

 this.m_Element.attachEvent('onclick', this.ToString);
 }

 JSClass.prototype.Render = function()
 {
 document.body.appendChild(this.m_Element);
 } 

 JSClass.prototype.ToString = function()
 {
 alert(this.m_Text);
 };

 var jc = new JSClass();
 jc.Render();
 jc.ToString(); 

  我就说说结果,页面运行后会显示:"division element",确定后点击文字"division element",将会显示:"undefined"。

  7、CSS的expression表达式中使用this关键字:

height: expression(this.parentElement.height);">
 division element  

 height: expression(this.parentElement.height);">
 division element

这里的this看作和1中的一样就可以了,它也是指代div元素对象实例本身。

  8、函数中的内部函数中使用this关键字:

view plaincopy to clipboardprint?
function OuterFoo()
{
this.Name = 'Outer Name';  

function InnerFoo()
{
var Name = 'Inner Name';
alert(Name + ', ' + this.Name);
}
return InnerFoo;
}
OuterFoo()();
 function OuterFoo()
 {
 this.Name = 'Outer Name';

 function InnerFoo()
 {
 var Name = 'Inner Name';
 alert(Name + ', ' + this.Name);
 }
 return InnerFoo;
 }
 OuterFoo()(); 

  运行结果显示是:"Inner Name, Outer Name"。按我们在2中的讲解,这里的结果如果是"Inner Name, undefined"似乎更合理些吧?但是正确的结果确实是前者,这是由于JavaScript变量作用域的问题决定的,详细了解推荐参看"原来JScript中的关键字'var'还是有文章的"一文及回复。

    归纳起来,JavaScript中的this用法有以下3种(详细用法参原文):

    1.在HTML元素事件属性 或 CSS的expression表达式 中inline方式使用this关键字——对应原文的1、7

    2.在事件处理函数中使用this关键字——对应原文的2、3

      其中可分为两种方式

      (1)DOM方式——此种方式的结果是this指向窗口(window)对象

      (2)DHTML方式——此种方式的结果是this指向div元素对象实例

    3.在类定义中使用this关键字并在其 内部函数 或 成员函数(主要是prototype产生)中使用——对应原文的4、5、8

      需要说明的是,在函数也是个对象,因此需要区分 变量定义 和 成员变量定义,如下:

view plaincopy to clipboardprint?

var variableName;    //变量定义
//作用域:函数定义范围内
//使用方法:直接使用variableName
this.varName;      //成员变量定义
//作用域:函数对象定义范围内及其成员函数中
//使用方法:this.varName
var variableName;    //变量定义
//作用域:函数定义范围内
//使用方法:直接使用variableName
this.varName;      //成员变量定义
//作用域:函数对象定义范围内及其成员函数中
//使用方法:this.varName

 以上归纳出的三类this的使用方法中,第一种比较容易理解,这里对原文中第6点提到的程序进行了测试和改进如下,以说明上述后两种使用方法:

view plaincopy to clipboardprint?

    function JSClass()
    {
      var varText = "func variable!";                 //函数中的普通变量
      this.m_Text = 'func member!';                    //函数类的成员变量
      this.m_Element = document.createElement('DIV');   //成员变量,创建一个div对象
      this.m_Element.innerHTML = varText;             //使用函数的普通变量
      this.m_Element.attachEvent('onclick', this.ToString);  //给这个对象的事件连上处理函数
      this.newElement = document.createElement('DIV');
      this.newElement.innerHTML = "new element";
      this.newElement.m_Text = "new element text!";      //给创建的对象建个成员
      this.newElement.onclick = function()
      {
        alert(this.m_Text);                       //指向div对象的成员
      };
    }  

    JSClass.prototype.Render = function()
    {
      document.body.appendChild(this.m_Element);       //把div对象挂在窗口上
      document.body.appendChild(this.newElement);
    }    

    JSClass.prototype.ToString = function()
    {
      alert(this.m_Text);                         //指向窗口(window)对象
    };  

    function initialize(){
      var jc = new JSClass();
      jc.Render();
      jc.ToString();                             //里面的this指向JSClass类的实例,里面有m_Text成员
    }  

// -->  

    initialize();  

// -->  

 function JSClass()
  {
   var varText = "func variable!";     //函数中的普通变量
    this.m_Text = 'func member!';     //函数类的成员变量
    this.m_Element = document.createElement('DIV'); //成员变量,创建一个div对象
    this.m_Element.innerHTML = varText;    //使用函数的普通变量
    this.m_Element.attachEvent('onclick', this.ToString); //给这个对象的事件连上处理函数
    this.newElement = document.createElement('DIV');
    this.newElement.innerHTML = "new element";
    this.newElement.m_Text = "new element text!";  //给创建的对象建个成员
    this.newElement.onclick = function()
   {
     alert(this.m_Text);      //指向div对象的成员
   };
  }

  JSClass.prototype.Render = function()
  {
    document.body.appendChild(this.m_Element);  //把div对象挂在窗口上
    document.body.appendChild(this.newElement);
  }   

  JSClass.prototype.ToString = function()
  {
    alert(this.m_Text);       //指向窗口(window)对象
  };

 function initialize(){
   var jc = new JSClass();
   jc.Render();
   jc.ToString();        //里面的this指向JSClass类的实例,里面有m_Text成员
  }

// -->

   initialize();

// -->

上面的代码执行结果是:

页面加载时,弹出对话框,输出func member!

页面上显示

 func variable!
 new element

单击func variable时,弹出对话框,显示undefined

  ——因为这时toString函数里的this指针指向window

单击new element时,弹出对话框显示new element text!

  ——因为这时toString函数里的this指针指向div元素,而该元素已经定义了m_Text成员(this.newElement.m_Text = "new element text!")

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索js里的this
, js里面的this
js里this
javascript关键字、javascript关键字大全、javascript new关键字、javascript let关键字、javascript保留关键字,以便于您获取更多的相关知识。

时间: 2024-09-18 05:46:31

关于js里的this关键字的理解_javascript技巧的相关文章

JS原型、原型链深入理解_javascript技巧

原型是JavaScript中一个比较难理解的概念,原型相关的属性也比较多,对象有"prototype"属性,函数对象有"prototype"属性,原型对象有"constructor"属性. 一.初识原型在JavaScript中,原型也是一个对象,通过原型可以实现对象的属性继承,JavaScript的对象中都包含了一个"[[Prototype]]"内部属性,这个属性所对应的就是该对象的原型. "[[Prototype]

js中的this关键字详解_javascript技巧

this是Javascript语言的一个关键字. 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.比如, 复制代码 代码如下: function test(){ this.x = 1; } 随着函数使用场合的不同,this的值会发生变化.但是有一个总的原则,那就是this指的是,调用函数的那个对象. 下面分四种情况,详细讨论this的用法. 情况一:纯粹的函数调用 这是函数的最通常用法,属于全局性调用,因此this就代表全局对象Global. 请看下面这段代码,它的运行结果是1.

谈一谈JS消息机制和事件机制的理解_javascript技巧

消息/事件机制是几乎所有开发语言都有的机制,并不是deviceone的独创,在某些语言称之为消息(Event),有些地方称之为(Message). 其实原理是类似的,只不过有些实现的方式要复杂一点.我们deviceone统一就叫消息. 消息基础概念 还有一些初学者不太熟悉这个机制,我们先简单介绍一些基础概念,如果熟悉的人可以跳过这个部分. 一个/条消息可以理解为是一个数据结构,包含以下几个基本部分: 1.消息源:就是消息的来源,发出这个消息的对象 2.消息名:就是消息的唯一标示 3.消息数据:消

在js里怎么实现Xcode里的callFuncN方法(详解)_javascript技巧

本人使用的WebStorm编辑器,里面没有callFuncN, 不记得Lua是否支持callFuncN,如果不支持相信应该能用同样的方法做到. 废话不多说,贴代码: loadDown : function () { var dis = this.left_move.getPositionY() - this.left.getPositionY(); // 得到一个距离 var act1 = new cc.moveBy(0.5,cc.p(0,-dis)); var act2 = cc.callFu

JS函数this的用法实例分析_javascript技巧

本文实例讲述了JS函数this的用法.分享给大家供大家参考.具体如下: 在js中写函数时,很多用到this. this究竟是什么,this是个关键字,是个指针,指向执行环境作用域,也称之为上下文. 先说下函数吧,个人理解是函数是在语言中重复调用的代码块. 在JS里,把函数赋值给对象的属性时,称之为方法 如: var m={}; m.title='title'; m.show=function(){ alert(this.title) } m.show() 就是把函数作为对象m的方法来调用 这样的

Javascript this关键字使用分析_javascript技巧

关于js中的this关键字的文章已经不少了,我看过几篇,我写这篇文章的目的是从实例中分析出this的工作原理,希望对大家有所帮助. 一.基本的: 复制代码 代码如下: function doSomething(){ alert(this.id); } alert(window.doSomething);//证明了doSomething是属于window的 doSomething();//undefined window.onload = function(){ document.getEleme

这段js代码得节约你多少时间_javascript技巧

1.应用案例: 复制代码 代码如下: var Mouse = function () { // Look! no that = this! this.position = [0, 0]; if (document.addEventListener) { document.addEventListener('mousemove', ?); //this.move? } else if (document.attachEvent) { document.attachEvent("onmousemov

javascript中this关键字详解_javascript技巧

不管学习什么知识,习惯于把自己所学习的知识列成一个list,会有助于我们理清思路,是一个很好的学习方法.强烈推荐. 以下篇幅有点长,希望读者耐心阅读. 以下内容会分为如下部分: 1.涵义 1.1:this涵义 1.2:this指向的可变性 2.使用场合 2.1:全局环境 2.2:构造函数 2.3:对象的方法 3.使用注意点 3.1:避免多层嵌套this 3.2:避免数组处理方法中的this 3.3:避免回调函数中的this 1.涵义 1.1:this涵义 在我写的一篇关于 构造函数与new关键字

js运动动画的八个知识点_javascript技巧

今天简单的学了一下js运动动画,记录一下自己的心得体会,分享给大家.       下面是我整理出来的结果. 知识点一:速度动画.       1.首先第一步实现速度运动动画,封装一个函数,用到的知识是setInterval(function(){ 复制代码 代码如下: oDiv.style.left=oDiv.offsetLeft+10+"px"; },30). 对于这里为什么要用到offsetLeft,我特意百度了一下,我得到的有用信息是: a.offsetLeft和left的相同之