zoukankan      html  css  js  c++  java
  • 详细解读-this-关键字在全局、函数、对象、jQuery等中的基础用法!

    一、前言

    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>

     五、DOM事件中的——this

    在DOM事件的处理函数中,this指代的是被绑定该事件的DOM元素。

    function Listener() {
        document.getElementById("foo").addEventListener("click",
           this.handleClick);
    }
    Listener.prototype.handleClick = function (event) {
        console.log(this); //logs "<div id="foo"></div>"
    }
    
    var listener = new Listener();
    document.getElementById("foo").click();

    六、使用with时的——this

    使用with可以将this人为添加到当前执行环境中而不需要显示地引用this

    function Thing () {
    }
    Thing.prototype.foo = "bar";
    Thing.prototype.logFoo = function () {
        with (this) {
            console.log(foo);
            foo = "foo";
        }
    }
    
    var thing = new Thing();
    thing.logFoo(); // logs "bar"
    console.log(thing.foo); // logs "foo"

    结束:

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

     

     

      

      

          

  • 相关阅读:
    Excel 货币中文大写汉字转化
    Python Tools for Visual Studio
    我的jQuery动态表格插件
    Wpf消息循环之消息传递
    混合模式程序集是针对“V2.050727”版本生成的,在没有配置信息情况下,无发在4.0运行时架子程序集。
    【IBM Tivoli Identity Manager 学习文档】15 用户管理
    【短语学习】什么是TPS
    【协议学习】H.323协议中的网守发现和网守注册过程
    【IBM Tivoli Identity Manager 学习文档】17 账户分配
    【IBM Tivoli Identity Manager 学习文档】14 TIM组织结构设计
  • 原文地址:https://www.cnblogs.com/xyq1107/p/7789915.html
Copyright © 2011-2022 走看看