一、前言

1、 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象。Javascript可以通过一定的设计模式来实现面向对象的编程,其中this “指针”就是实现面向对象的一个很重要的特性。但是this也是Javascript中一个非常容易理解错,进而用错的特性。

2、this是Javascript语言的一个关键字。 它代表函数运行时,自动生成的一个内部对象。

二、进入正题

1、全局代码中的——this

  1、 浏览器宿主的全局环境中,this指的是window对象。在全局代码中,this始终是全局对象本身,这样就有可能间接的引用到它了。

  示例:

<script type="text/javascript">
        console.log(this); //window
        console.log(this == window);//true
</script>

  2、 浏览器中在全局环境下,使用var声明变量将会把值赋给thiswindow

  示例:

<script type="text/javascript">
        var  name = "Jack" ;
        console.log(this.name);//Jack
        console.log(window.name);//Jack
</script>

  3、任何情况下,即使创建变量时没有使用var,也是在操作全局this。而在函数里面创建变量时,结果为undefined。

  示例:

<script type="text/javascript">
    name = "Jack";
    function testThis() {
         age = 20;
         console.log(this.age); // 20
    }
    console.log(this.age); // undefined
    console.log(this.name);// Jack
    testThis();
    console.log(this.name);// Jack
</script>

二、函数代码中的——this

1、先来看一个最简单的例子

<script type="text/javascript">
    var name = "Jack";
    function sayHi(){
      console.log("你好,我的名字叫" + name);// "你好,我的名字叫Jack"
      console.log("你好,我的名字叫" + this.name);// "你好,我的名字叫Jack"
    }
    sayHi();
</script>

首先,我们定义了一个全局字符串对象name和函数对象sayHi。运行都会打印出,“你好,我的名字叫Jack”。全局变量name将值赋给this。

2、我们把上面的代码改一改:

<script type="text/javascript">
    name = "Jack";
    function testThis() {
      this.name = "Alice";
    }
    console.log("你好,我的名字叫"+this.name); //  "你好,我的名字叫Jack"
    testThis();
    console.log("你好,我的名字叫"+this.name); //  "你好,我的名字叫Alice"
</script>

运行结果为Jack中的this为函数调用之前的全局变量name=Jack将值赋给this,此时textThis函数未将Alice赋值给this;运行结果为Alice为函数调用之后testThis函数将Alice值赋值给了全局变量name,此时name = "Alice"   this.name = "Alice"。

3、函数也是普通的对象,可以将其当作一个普通变量使用。我们再把上面的代码改一改:

<script type="text/javascript">
    var name = "Jack";
    function sayHi(){
       console.log("你好,我的名字叫" + this.name);// undefined
    }
    var person = {};
    person.sayHello = sayHi;
    person.sayHello();
</script>

//而定义  person = {name:Alice}  ,则:
<script type="text/javascript">
    var name = "Jack";
    function sayHi(){
       console.log("你好,我的名字叫" + this.name);// "你好,我的名字叫Alice"
    }
    var person = {name:Alice};
    person.sayHello = sayHi;
    person.sayHello();
</script>

第一,我们定义了一个全局函数对象sayHi并执行了这个函数,函数内部使用了this关键字,那么执行this这行代码的对象是sayHi(一切皆对象的体现),sayHi是被定义在全局作用域中。其实在Javascript中所谓的全局对象,无非是定义在window这个根对象下的一个属性而已。因此,sayHi的所有者是window对象。也就是说,在全局作用域下,你可以通过直接使用name去引用这个对象,你也可以通过window.name去引用同一个对象。因而this.name就可以翻译为window.name

第二,我们定义了一个person的对象,并定义了它的sayHello属性,使其指向sayHi全局对象。那么这个时候,当我们运行person.sayHello的时候,this所在的代码所属对象就是sayHello了(其实准确来说,sayHi和sayHello是只不过类似两个指针,指向的对象实际上是同一个),而sayHello对象的所有者就是person了。第一次,person里面没有name属性,因此弹出的对话框就是this.name引用的就是undefined对象(Javascript中所有只声明而没有定义的变量全都指向undefined对象);而第二次我们在定义person的时候加了name属性了,那么this.name指向的自然就是我们定义的字符串了。

参考上面解释,我们将上面示例改造成面向对象式的代码:

<script type="text/javascript">
    var name = "Jack";
    function sayHi(){
       console.log("你好,我的名字叫" + this.name);//两次函数调用均成功,打印两次:"你好,我的名字叫Marry"     "你好,我的名字叫Alice"
    }
    function Person(name){
        this.name = name;
    }
    Person.prototype.sayHello = sayHi;
    var marry = new Person("Marry");
    marry.sayHello();
    var alice = new Person("Alice");
    alice.sayHello();
</script>

在上面这段代码中,我们定义了一个Person的“类”(实际上还是一个对象),然后在这个类的原型(类原型相当于C++中的静态成员变量的概念)中定义了sayHello属性,使其指向全局的sayHi对象。运行代码我们可以看到,marry和kevin都成功打印出来。

4、当用调用函数时使用了new关键字,此刻this指代一个新的上下文,不再指向全局this。通常我将这个新的上下文称作实例。

<script type="text/javascript">
    name = "Jack";
    function testThis() {
      this.name = "Alice";
    }
    console.log(this.name); // "Jack"
    new testThis();
    console.log(this.name); // "Jack"
    console.log(new testThis().name); // "Alice"
</script>

三、对象代码中的——this

1、可以在对象的任何方法中使用this来访问该对象的属性。这与用new得到的实例是不一样的。

var obj = {
   name: "Jack",
    func: function () {
        console.log(this.name); //   "Jack"
    }
};

obj.func();

2、可以将函数绑定到对象,就好像这个对象是一个实例一样。

var obj = {
    name: "Jack"
};

function logName() {
    console.log(this.name); //logs "Jack"
}

logName.apply(obj);

3、也可以不通过this,直接访问对象的属性。

var obj = {
   name: "Jack",
    deeper: {
        logName: function () {
            console.log(obj.name);//    "Jack"
        }
    }
};

obj.deeper.logName(); 

四、jQuery代码中的——this

1、jQuery库中大多地方的this也是指代的DOM元素。页面上的事件回调和一些便利的静态方法比如$.each 都是这样的。

<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script src="../05-JQuery/JS/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
$(function(){

       $(".foo").each(function () {
            console.log(this); //  <div class="foo bar1"></div>   <div class="foo bar2"></div>
        });
        $(".foo").on("click", function () {
            console.log(this); //  <div class="foo bar1">   <div class="foo bar2"></div>
        });

   })

</script>

结束:

  上面,就是博主自己在实践的过程中,总结的一点经验,希望对大家能否有所帮助,欢迎大家能够提出高贵意见,博主定当补充改正。

 

 

  

  

详细解读-this-关键字在全局、函数、对象、jQuery中的基础用法!的更多相关文章

  1. 详细解读-this-关键字在全局、函数、对象、jQuery等中的基础用法!

    一.前言 1. Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的设计模式来实现面向对象的编程,其 ...

  2. JavaScript封装Ajax工具函数及jQuery中的ajax,xhr在IE的兼容

    封装ajax工具函数 首先要思考:1.为什么要封装它?提高开发效率2.把一些不确定的情况考虑在其中 a. 请求方式 b. 请求地址 c. 是否异步 d. 发送参数 e. 成功处理 f. 失败处理3.确 ...

  3. 重写__eq__函数——对象list中使用in index()——获得list中不同属性对象个数

    https://blog.csdn.net/anlian523/article/details/80868961

  4. 基准对象object中的基础类型----字典 (六)

    object有如下子类: CLASSES object basestring str unicode buffer bytearray classmethod complex dict enumera ...

  5. 基准对象object中的基础类型----字符串 (三)

    object有如下子类: CLASSES object basestring str unicode buffer bytearray classmethod complex dict enumera ...

  6. body中的onload()函数和jQuery中的document.ready()有什么区别?

    1.我们可以在页面中使用多个document.ready(),但只能使用一次onload(). 2.document.ready()函数在页面DOM元素加载完以后就会被调用,而onload()函数则要 ...

  7. 基准对象object中的基础类型----集合 (七)

    object有如下子类: CLASSES object basestring str unicode buffer bytearray classmethod complex dict enumera ...

  8. 基准对象object中的基础类型----元组 (五)

    object有如下子类: CLASSES object basestring str unicode buffer bytearray classmethod complex dict enumera ...

  9. 基准对象object中的基础类型----列表 (四)

    object有如下子类: CLASSES object basestring str unicode buffer bytearray classmethod complex dict enumera ...

随机推荐

  1. 8.20.1 图形化:弹窗JOptionPane

    最近在做swing程序中遇到使用消息提示框的,JOptionPane类其中封装了很多的方法. 很方便的,于是就简单的整理了一下. 1.1 showMessageDialog 显示一个带有OK 按钮的模 ...

  2. .NET Core 在程序集中集成Razor视图

    前言 有时候,我们在开发一个程序集供其他项目引用的时候,可能需要对外输出一些HTML的结构数据. 还有一些情况我们可能开发的是一个中间件,这个中间件需要提供一些界面来对外展示数据或者是内部的一些程序的 ...

  3. java中 this 的三种用法

    Java中this的三种用法 调用属性 (1)this可以调用本类中的任何成员变量 调用方法(可省略) (2)this调用本类中的成员方法(在main方法里面没有办法通过this调用) 调用构造方法 ...

  4. Jmeter之解决烦人的中文乱码问题

    Jmeter是一款国外开源工具,所以就跟LR一样,对中文的支持不是很好,经常会有同学录制脚本后回放或者是发送HTTP请求,看到响应报文里面有乱码! 那如何才能解决这个问题呢?我们分2个情况来分析: 一 ...

  5. node.js学习系列(一)

     node.js 百度百科简介 Node.js 是一个 Javascript 运行环境(runtime).实际上它是对 Google V8 引擎进行了封装.V8 引 擎执行 Javascript 的速 ...

  6. HashMap和ConcurrentHashMap流程图

    本文表达HashMap和ConcurrentHashMap中的put()方法的执行流程图,基于JDK1.8的源码执行过程. HashMap的put()方法: ConcurrentHashMap的put ...

  7. Spring详解(四)------注解配置IOC、DI

    Annotation(注解)是JDK1.5及以后版本引入的.它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查.注解是以‘@注解名’在代码中存在的. 前面讲解 IOC 和 DI 都是通过 ...

  8. SVN 通过IIS设置反向代理访问

    原因 一个字,穷,没办法,只有一台机器 要当测试服务器还要做源码管理. 解决办法 通过IIS配置反向代理访问SVN,给SVN访问的HTTPS绑定上域名,就可以正常访问了. 1.修改SVN配置 把SVN ...

  9. Spring-MVC开发步骤(入门配置)

    Spring-MVC开发步骤(入门配置) Step1.导包 spring-webmvc Step2.添加spring配置文件 Step3.配置DispatcherServlet 在web.xml中: ...

  10. 向GitHub 提交你的源代码

    之前的这篇文章「Git入门篇」相信大家都已经对 Git 的基本操作熟悉了,但是这篇文章只介绍了对本地 Git 仓库的基本操作,今天我就来介绍下如何跟远程仓库一起协作,教你们向 GitHub 上提交你们 ...