javascript中的this含义非常丰富,它可以是全局对象,当前对象或者是任意对象,这都取决于函数的调用方式。函数有以下几种调用方式:作为对象方法调用、作为函数调用、作为构造函数调用、apply或call调用。

对象方法调用

作为对象方法调用的时候,this会被绑定到该对象。

var point = {
 x : 0,
 y : 0,
 moveTo : function(x, y) {
     this.x = this.x + x;
     this.y = this.y + y;
     }
 }; 

 point.moveTo(1, 1)//this 绑定到当前对象,即 point 对象

这里我想强调一点内容,就是this是在函数执行的时候去获取对应的值,而不是函数定义时。即使是对象方法调用,如果该方法的函数属性以函数名的形式传入别的作用域,也会改变this的指向。我举一个例子:

var a = {
    aa : 0,
    bb : 0,
    fun : function(x,y){
        this.aa = this.aa + x;
        this.bb = this.bb + y;
    }
};
var aa = 1;
var b = {
    aa:0,
    bb:0,
    fun : function(){return this.aa;}
}
a.fun(3,2);
document.write(a.aa);//3,this指向对象本身
document.write(b.fun());//0,this指向对象本身
(function(aa){//注意传入的是函数,而不是函数执行的结果
    var c = aa();
    document.write(c);//1 , 由于fun在该处执行,导致this不再指向对象本身,而是这里的window
})(b.fun);

这样就明白了吧。这是一个容易混淆的地方。

函数调用

函数也可以直接被调用,这个时候this被绑定到了全局对象。

var x = 1;
  function test(){
    this.x = 0;
  }
  test();
  alert(x); 

但这样就会出现一些问题,就是在函数内部定义的函数,其this也会指向全局,而和我们希望的恰恰相反。代码如下:

var point = {
 x : 0,
 y : 0,
 moveTo : function(x, y) {
     // 内部函数
     var moveX = function(x) {
     this.x = x;//this 绑定到了全局
    };
    // 内部函数
    var moveY = function(y) {
    this.y = y;//this 绑定到了全局
    }; 

    moveX(x);
    moveY(y);
    }
 };
 point.moveTo(1, 1);
 point.x; //==>0
 point.y; //==>0
 x; //==>1
 y; //==>1

我们会发现不但我们希望的移动呢效果没有完成,反而会多出两个全局变量。那么如何解决呢?只要要进入函数中的函数时将this保存到一个变量中,再运用该变量即可。代码如下:

var point = {
 x : 0,
 y : 0,
 moveTo : function(x, y) {
      var that = this;
     // 内部函数
     var moveX = function(x) {
     that.x = x;
     };
     // 内部函数
     var moveY = function(y) {
     that.y = y;
     }
     moveX(x);
     moveY(y);
     }
 };
 point.moveTo(1, 1);
 point.x; //==>1
 point.y; //==>1

构造函数调用

在javascript中自己创建构造函数时可以利用this来指向新创建的对象上。这样就可以避免函数中的this指向全局了。

var x = 2;
  function test(){
    this.x = 1;
  }
  var o = new test();
  alert(x); 

apply或call调用

这两个方法可以切换函数执行的上下文环境,也就是改变this绑定的对象。apply和call比较类似,区别在于传入参数时一个要求是数组,一个要求是分开传入。所以我们以apply为例:

<pre name="code" class="html">var name = "window";

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

var other = {
    name: "Tom"
};   

someone.showName();        //Bob
someone.showName.apply();    //window
someone.showName.apply(other);    //Tom

可以看到,正常访问对象中方法时,this指向对象。使用了apply后,apply无参数时,this的当前对象是全局,apply有参数时,this的当前对象就是该参数。

箭头函数调用

这里需要补充一点内容,就是在下一代javascript标准ES6中的箭头函数的 this始终指向函数定义时的 this,而非执行时。我们通过一个例子来理解:

var o = {
    x : 1,
    func : function() { console.log(this.x) },
    test : function() {
        setTimeout(function() {
            this.func();
        }, 100);
    }
};

o.test(); // TypeError : this.func is not a function

上面的代码会出现错误,因为this的指向从o变为了全局。我们需要修改上面的代码如下:

var o = {
    x : 1,
    func : function() { console.log(this.x) },
    test : function() {
        var _this = this;
        setTimeout(function() {
            _this.func();
        }, 100);
    }
};

o.test();

通过使用外部事先保存的this就行了。这里就可以利用到箭头函数了,我们刚才说过,箭头函数的 this始终指向函数定义时的 this,而非执行时。所以我们将上面的代码修改如下:

var o = {
    x : 1,
    func : function() { console.log(this.x) },
    test : function() {
        setTimeout(() => { this.func() }, 100);
    }
};

o.test();

这回this就指向o了,我们还需要注意一点的就是这个this是不会改变指向对象的,我们知道call和apply可以改变this的指向,但是在箭头函数中是无效的。

var x = 1,
    o = {
        x : 10,
        test : () => this.x
    };

o.test();
o.test.call(o); // 依然是1

这样就可以明白各种情况下this绑定对象的区别了。

JavaScript之this指针深入详解的更多相关文章

  1. javascript常用经典算法实例详解

    javascript常用经典算法实例详解 这篇文章主要介绍了javascript常用算法,结合实例形式较为详细的分析总结了JavaScript中常见的各种排序算法以及堆.栈.链表等数据结构的相关实现与 ...

  2. javascript中=、==、===区别详解

    javascript中=.==.===区别详解今天在项目开发过中发现在一个小问题.在判断n==""结果当n=0时 n==""结果也返回了true.虽然是个小问题 ...

  3. Javascript 调试利器 Firebug使用详解

    Javascript 调试利器 Firebug使用详解 有时候,为了更清楚方便的查看输出信息,我们可能需要将一些调试信息进行分组输出,那么可以使用console.group来对信息进行分组,在组信息输 ...

  4. JavaScript中return的用法详解

    JavaScript中return的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 t ...

  5. javascript 中合并排序算法 详解

    javascript 中合并排序算法 详解 我会通过程序的执行过程来给大家合并排序是如何排序的...  合并排序代码如下: <script type="text/javascript& ...

  6. javascript中的this作用域详解

    javascript中的this作用域详解 Javascript中this的指向一直是困扰我很久的问题,在使用中出错的机率也非常大.在面向对象语言中,它代表了当前对象的一个引用,而在js中却经常让我觉 ...

  7. JavaScript中this的用法详解

    JavaScript中this的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 thi ...

  8. 高性能JavaScript模板引擎实现原理详解

    这篇文章主要介绍了JavaScript模板引擎实现原理详解,本文着重讲解artTemplate模板的实现原理,它采用预编译方式让性能有了质的飞跃,是其它知名模板引擎的25.32 倍,需要的朋友可以参考 ...

  9. JavaScript对象的property属性详解

    JavaScript对象的property属性详解:https://www.jb51.net/article/48594.htm JS原型与原型链终极详解_proto_.prototype及const ...

随机推荐

  1. prmopt 提示框接收字符串,输入后按确定弹出警告框,警告内容为逆序的字符串

    虽然已经找到offer,但因为公司还没安排实习,所以在学校的时间多了很多.好吧,这段时间我用来备考四级啦(好悲催,还没过),然后这一天,闲着无聊,就帮妹妹看了这样子一道题目啦. 题目内容: 编制一个从 ...

  2. 《转》前端性能优化----yahoo前端性能团队总结的35条黄金定律

    除了自己总结:1. 减少http请求,2.压缩并优化js/css/image 3.尽量静态页面,从简原则 4.代码规范(详见:个人知识体系思维导图) 从yahoo 新学到的: 网页内容 减少http请 ...

  3. list集合练习一

    package com.java.c.domain; public class Person { private String name; private int age; public Person ...

  4. PHP中的设计模式:单例模式(译)

    原文链接:http://coderoncode.com/2014/01/27/design-patterns-php-singletons.html 单例模式用于限制类实例化到单个对象,当整个系统只需 ...

  5. Chrome退出全屏问题

    最近做了一个号称很炫的B/S展示软件,展示所用浏览器为Google Chrome. 要求展示时全屏,但是页面要有退出全屏按钮(液晶屏没有键盘). 搜索实现方式几乎前篇一律,即两个JS函数一个实现全屏一 ...

  6. trac的安装和配置

    trac是一个很好用的基于python的任务管理系统. 这个软件主要有如下特点: 1)tickit管理,可以设定各种各样的ticket,然后进行修改和完成. 2)wiki管理,可以编写各种文档. 3) ...

  7. Linux 安装配置 JDK 8

    所需软件包, 可以到Oracle官网去下载,  放到/usr/local/src文件夹下: jdk-8u45-linux-x64.tar.gz 安装: cd /usr/local/srctar -zx ...

  8. WAMP(Windows+Apache+Mysql+PHP)环境搭建

    学习PHP已经有一段时间,一直没有写过关于开发环境搭建的笔记,现在补上吧,因为安装配置的步骤记得不是很清楚,借鉴了一些别人的经验,总结如下: 首先去官方网站下载各个软件,下载需要的版本: Apache ...

  9. WebApi学习总结系列第四篇(路由系统)

    由于工作的原因,断断续续终于看完了<ASP.NET Web API 2 框架揭秘>第二章关于WebApi的路由系统的知识. 路由系统是请求消息进入Asp.net WebApi的第一道屏障, ...

  10. div+css知识点(2)

    文字溢出 显示省略号的 关键的三句代码text-overflow:ellipsis; -o-text-overflow:ellipsis; overflow:hidden;文字缩进的代码是什么text ...