zoukankan      html  css  js  c++  java
  • 面向对象之---this的用法

    在绝大多数情况下,函数的调用方式决定了this的值

    全局环境

    无论是否在严格模式下,在全局执行环境中,this都指向全局对象·

    在全局作用域中调用一个函数时,this总是指向Global对象(在浏览器中指向window)

    函数(运行内)环境

    在函数内部,this的值取决于函数被调用的方式

    1.简单调用

    非严格模式
    function f1() {
      console.log(this);
    }
    // 在浏览器环境
    f1();//window
    
    // 在Node环境
    f1();//global

    严格模式

    在严格模式下,如果this没有被执行环境(execution context)或者称为上下文,this会保持它进入执行环境时的值,所以下面this会被默认为undefined

    function f2() {
      'use strict';
      console.log(this);
    }
    f2(); //undefined

    使用call()或者apply()方法,改变this的指向

    // 如果想把this的值从一个环境传到另一个,就可以调用call()或者apply()方法
    var o = {
      a: 'Customs'
    };
    var o1 = {
      a: 'Customs1'
    };
    var o2 = {
      a: 'Customs2'
    };
    var a = 'Global';
    function whatThis(arg) {
      console.log(this.a);
    }
    
    whatThis(); //Global
    whatThis.call(o); //Customs
    whatThis.apply(o); //Customs
    whatThis.call(o1); //Customs1
    whatThis.apply(o1); //Customs1
    whatThis.call(o2); //Customs2
    whatThis.apply(o2); //Customs2
    强制指向,即改变函数的调用对象
    两者有何异同?
    apply(thisObj,[argsArray])
    call(thisObj,arg1,arg2,arg3)
    call()与apply()方法类似,区别就是接受的参数形式不一样
    apply()接受的是数组;call()接受的是以逗号分隔的参数
     
    使用 call 和 apply 函数的时候要注意,如果传递给 this 的值不是一个对象,JavaScript 会尝试使用内部 ToObject 操作将其转换为对象。
    因此,如果传递的值是一个原始值比如 7 或 'foo',那么就会使用相关构造函数将它转换为对象,所以原始值 7 会被转换为对象,像 new Number(7) 这样,而字符串 'foo' 转化成 new String('foo') 这样,
    function bar() {
      console.log(Object.prototype.toString.call(this));
    }
    
    //原始值 7 被隐式转换为对象
    bar.call(7); // [object Number]

    2.作为对象的方法调用

    当函数作为对象的方法调用,他们的this是调用该函数的对象

    var x4 = 44;
    function f4() {
      console.log(this.x4); //{x:55,say:f4} this指向o4
    }
    var o4 = {};
    o4.x4 = 55;
    o4.say = f4;
    o4.say(); // 55
    var x5 = 56;
    var o5 = {
      x5: 66,
      f5: function() {
    console.log(this)
    // {x5:66,f5:f} this指向o5

    // console.log(this.x5);//66
        return this.x5;
      }
    };
    
    console.log(o5.f5()); //66
    原型链中的this

    对于原型链上某处定义的方法,同样也适用, 如果该方法存在于对象的原型链上,那么this的指向的是调用该方法的对象

    var oo = {
      f: function() {
        return this.a + this.b;
      }
    };
    
    var p = Object.create(oo);
    p.a = 1;
    p.b = 2;
    console.log(p.f()); // 3
    // 解析:对象p没有自己的f属性,该属性继承自原型,
    // 对于f的查找过程中,最终在对象oo中找到f属性,查找的过程是p.f的引用开始的,所以this指向p
    // 也就是说,因为f是作为p的方法调用的,所以this指向p
    getter和setter中的this
    当一个函数在一个setter或者getter中被调用
    用作getter或者setter的函数都会把this绑定到设置或者获取属性的对象
    function sum() {
      console.log(this); //{a: 1,average: 2,b: 2, c: 3,sum: 6}
      return this.a + this.b + this.c;
    }
    var oo1 = {
      a: 1,
      b: 2,
      c: 3,
      get average() {
        console.log(this);//{a: 1,average: 2,b: 2, c: 3,sum: 6}
        return (this.a + this.b + this.c) / 3;
      }
    };
    
    Object.defineProperty(oo1, 'sum', {
      get: sum,
      enumerable: true,
      configurable: true
    });
    
    console.log(oo1.average, oo1.sum); // 2,6

    3.作为构造函数

    当一个函数作为构造函数时(使用new关键字),他的this指向用构造函数创建的对象

    function Test() {
      this.x = 3;
    }
    var obj1 = new Test();
    console.log(obj1.x); // 3
    // 解析:this指向Test的实例,即obj1
    obj1.x = 5;
    console.log(obj1.x); // 5

    4.bind()方法

    ES5引入Function.prototype.bind()

    调用 f.bind()方法会创建一个与 f具有相同的函数体和作用域的函数

    但是在这个函数中,this将永久性的被绑定到了bind的第一个参数,无论函数是怎么样调用的

    var a3 = 'Global';
    function f3() {
      console.log(this.a3); //zhangsan
      return this.a3;
    }
    
    var g = f3.bind({ a3: 'zhangsan' });
    console.log(g()); // zhangsan
    
    var h = g.bind({ a3: 'haha' }); // bind只生效一次,再次修改也不会生效
    console.log(h()); // zhangsan
    
    var o3 = {
      a3: 37,
      f3: f3,
      g: g,
      h: h
    };
    console.log(o3.f3(), o3.g(), o3.h()); // 37,"zhangsan","zhangsan"

    5.作为一个DOM时间处理函数

    当函数被用作事件处理函数时,它的this指向触发事件的元素

    6.作为一个内联事件处理函数

    当代码被内联on-event 处理函数调用时,它的this指向监听器所在的DOM元素

     
     
    参考:
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/this
    http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html
     
  • 相关阅读:
    NHibernate版本不一致问题
    .NET中AOP的几种实现方案
    转播
    看来不得不来谈谈这个首页精华区了
    事件与委托
    关于字符集和字符编码以及代码页的前前后后(续)
    让电脑像人脑一样思考,谁养鱼问题断言推理解法
    关于那个脑袋的很漂漂的图形的C#版本
    大家都有头像,我来测试下我的新头像。
    浅谈JavaScript中的对象和类型(上)
  • 原文地址:https://www.cnblogs.com/shengnan-2017/p/10407013.html
Copyright © 2011-2022 走看看