美文网首页
2017-02-26

2017-02-26

作者: 朱小维 | 来源:发表于2017-02-28 15:49 被阅读24次

    使用构造函数封装TAB

    效果预览

    js中的this

    本篇文章是读阮一峰的《JavaScript标准参考教程》的学习笔记,文中加入了一些自己的想法,如有侵权,私信我删除

    1. 概述
      this关键字,代表当前的对象环境。其中有两个关键字,一个是“当前”,一个是“对象”。

    2. this的指向是动态改变的
      举个例子:

    var A = {
        name:"a",
        sayName:function(){
            return this.name;
        }
    }
    var B= {
        name:"b"
    }
    A.sayName();//a
    B.sayName = a.sayName;
    B.sayName();//b
    

    当把A对象的方法赋值给B对象时,B.sayName()方法的运行环境是B对象,因此this就代表B对象,this.name就等于b了。
    总结:JS中一切皆对象,运行环境也是对象,在浏览器环境中顶层对象是window。函数都是运行在某个对象中的,thi指的就是函数当前所在的环境,但是JS中环境会动态切换,这就使得this的指向也是动态改变的。

    1. this的使用场合

      1. 全局环境
        当在全局环境中使用this时,this代表顶层对象window
      this === window//true
      
      
      1. 构造函数
        构造函数中的this指实例对象
      function car(carName){
          this.name = carName;
      }
      var benz = new car("Benz");
      benz.name;//"Benz"
      

      当使用new命令调用构造函数car时,构造函数会自动穿件一个临时对象,并将函数体内部的this替换为临时对象,并对临时对象的属性进行赋值,最后返回临时对象,该临时对象就成为一个实例。因此构造函数中的this就指代实例对象。

      1. 对象的方法
      var benz = {
          name:"Benz",
          sayName:function(){
              console.log(this.name);
          }
      }
      benz.sayName();//"Benz"
      

      这个例子,介绍对象如何在自己的方法里调用自己的属性,sayName方法里的this此时就指代benz对象,前提条件是 通过benz.sayName() 形式调用该方法(直接在benz对象上调用该方法)。

    2. 使用注意点

      1. 避免多层this
      var o = {
        f1: function () {
          console.log(this);
          var f2 = function () {
            console.log(this);
          }();
        }
      }
      o.f1()
      // Object
      // Window
      

      这个例子,o.f1()是通过对象方法的形式调用的,所以其作用对象就是o,this就代表o;而被赋值给f2的立即执行函数是声明完就执行的,即使它是在对象o的内部执行的,但它没有以对象方法的形式执行,所以他的作用对象就是winddow。
      如果想要立即执行函数也log出object,可以按下面的方法:

      var o = {
        f1: function () {
          console.log(this);
          var that = this;
          var f2 = function () {
            console.log(that);
          }();
        }
      }
      o.f1()
      // Object
      // Object
      

      提前用变量将f1中的this存储起来,然后函数中再引用that变量。

      1. 避免数组处理方法中的this
        数组的map和forEach方法,允许提供一个函数作为参数,这个函数内部的this指向调用方法的数组对象。
      var o = {
        v: 'hello',
        p: [ 'a1', 'a2' ],
        f: function f() {
          this.p.forEach(function (item) {
            console.log(this.v + ' ' + item);
          });
        }
      }
      o.f()
      // undefined a1
      // undefined a2
      

      forEach的回调函数内的this指向的是数组对象["a1","a2"],而数组对象并没有属性v。
      解决办法和上面的解决办法相同,就是提前先把对象o的this存储起来。

      var o = {
        v: 'hello',
        p: [ 'a1', 'a2' ],
        f: function f() {
          var that = this;
          this.p.forEach(function (item) {
            console.log(that.v + ' ' + item);
          });
        }
      }
      o.f()
      // hello a1
      // hello a2
      
      1. 避免回调函数中的this
      var o = new object();
      o.f = function() {
          console.log(this === o)
      }
      o.f();//true
      $("#btn").on('click',o.f);
      //当点击btn时返回的是false,因为回调函数的this指向了$("#btn")
      
       这个例子和2中的例子其实是一个意思,都是回调惹的祸。

    相关文章

      网友评论

          本文标题:2017-02-26

          本文链接:https://www.haomeiwen.com/subject/wrkxgttx.html