zoukankan      html  css  js  c++  java
  • JS中的this

    本文从两方面讨论this常规函数箭头函数

    首先明确:this指向JavaScript实例,因此只有在函数调用时才可以确定下来,而在函数声明时是无法确定的!

    一、全局中的this

    无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象。

    // 在浏览器中, window 对象同时也是全局对象:console.log(this === window); // true

    二、常规函数中的this

    1.纯粹的函数调用

     1 //----------------------------example1-------------------------------
     2 // 非严格模式下
     3 function f1(){
     4     return this;
     5 }
     6 //在浏览器中:
     7 f1() === window;   //在浏览器中,全局对象是window
     8 
     9 //在Node中:
    10 f1() === global; // true
    11 
    12 //----------------------------example2-------------------------------
    13 // 严格模式下
    14 function f2(){
    15     "use strict"; // 这里是严格模式
    16     return this;
    17 }
    18 
    19 f2() === undefined; // true 此处的this为undefined是因为f2是直接被调用的,而不是作为某个对象的方法(如 window.f2())被调用。
    20 
    21 //----------------------------example3-------------------------------
    22 // 将一个对象作为call和apply的第一个参数,this会被绑定到这个对象。
    23 var obj = {a: 'Custom'};
    24 
    25 // 这个属性是在global对象定义的。
    26 var a = 'Global';
    27 
    28 function whatsThis(arg) {
    29     return this.a;  // this的值取决于函数的调用方式
    30 }
    31 
    32 whatsThis();          // 写法1,严格模式为undefined,非严格模式为'Global'
    33 whatsThis.call(undefined); // 写法2,严格模式为undefined,非严格模式为'Global'
    34 whatsThis.call(obj);  // 可指定this,'Custom'
    35 whatsThis.apply(obj); // 可指定this,'Custom'
    36 whatsThis.bind(obj)(); // 可绑定this,'Custom'
    37 whatsThis.bind(obj).bind({a: 'aHhha'})(); // this只可绑定一次,'Custom'

    上面的写法1写法2是等价的,写法1写法2 的语法糖。

    写法2中call方法接收的第一个参数就是this,这里传了一个undefined,此时有如下定义:

    如果你传的 context 是 null 或者 undefined,那么非严格模式下, window 对象(浏览器)或global(Node)就是默认的 context,严格模式下默认 context是 undefined。

    2.对象中的函数的this

    当函数作为对象里的方法被调用时,它们的 this 是调用该函数的对象。最靠近的引用优先级最高。

     1 var o = {prop: 37};
     2 
     3 function independent() {
     4   return this.prop;
     5 }
     6 
     7 o.f = independent;
     8 
     9 console.log(o.f()); // logs 37, 函数调用关系为从o的f成员调用
    10 
    11 o.b = {g: independent, prop: 42};
    12 console.log(o.b.g()); // 42 最靠近的引用优先级最高
    13 console.log(o.f.call({prop: 53}));  // 使用call可改变this

    3.构造函数中的this

    当函数作为构造函数被new返回一个对象时,该对象即为this。

     1 function C(){
     2   this.a = 37;
     3 }
     4 
     5 var o = new C();
     6 console.log(o.a); // logs 37
     7 
     8 
     9 function C2(){
    10   this.a = 37;
    11   return {a:38};
    12 }
    13 
    14 o = new C2();
    15 console.log(o.a); // logs 38

    4.作为DOM元素的监听处理函数的this

    当函数被作为DOM元素的监听处理函数时,它的this指向监听器所在的DOM元素,但只有最外层代码中的this是这样的:

    1 <button onclick="alert(this.tagName.toLowerCase());">  <!-- button -->
    2   Show this
    3 </button>
    4 <button onclick="alert((function(){return this})());">  <!-- 非严格模式下指向global/window -->
    5   Show inner this
    6 </button>

    5.window.setTimeout()和window.setInterval()的this

    window.setTimeout()和window.setInterval()的函数中的this默认是window对象。

    总结:常规函数中,有以下总结:

    this只有在函数被调用时才能确定下来,this指向调用函数的对象;this最靠近的引用优先级最高;可以用call()或bind()指定this;构造函数的this指向new返回的对象;DOM元素的监听处理函数的this指向监听器所在的DOM元素;window.setTimeout()和window.setInterval()的函数中的this默认是window对象。

    三、箭头函数的this

    1.箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。

     1 function Person() {
     2   // Person() 构造函数定义 `this`作为它自己的实例.
     3   this.age = 0;
     4 
     5   setInterval(function growUp() {
     6     // 在非严格模式, growUp()函数定义 `this`作为全局对象, 
     7     // 与在 Person()构造函数中定义的 `this`并不相同.
     8     this.age++;
     9     console.log(this.age) //NAN
    10   }, 1000);
    11 }
    12 
    13 var p = new Person();
    1 function Person(){
    2   this.age = 0;
    3 
    4   setInterval(() => {
    5     this.age++; // |this| 正确地指向 p 实例,继承作用域链 箭头函数=>Person
    6   }, 1000);
    7 }
    8 
    9 var p = new Person();

    2.箭头函数不能用call()指定this

    1 const obj = {
    2     a: () => {
    3         console.log(this)
    4     }
    5 }
    6 obj.a.call('123')  //window,继承作用域链 箭头函数=>window

      

    3.箭头函数不能用bind()指定this

    1 var globalObject = this;
    2 var foo = (() => this);
    3 var obj = {foo: foo};
    4 foo = foo.bind(obj);
    5 console.log(foo() === globalObject); // true

    总结:箭头函数中,有以下总结:

    箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this;箭头函数不能用call()或bind()指定this

    欢迎留言交流。 

    本文参考:

    https://juejin.im/post/5aa1eb056fb9a028b77a66fd

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/this

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arrow_functions

    2019.9.12

    yangqianqian

  • 相关阅读:
    动物-昆虫:蠼螋
    动物-昆虫:蚰蜒
    动物-软体动物:蜒蚰
    动物-昆虫:蝼蛄
    动物-昆虫:地鳖
    动物:水蛭、蚂蟥
    动物:刺猬
    cmd 下命令
    storm-安装
    python学习之--安装IDE(eclipse+pydev)
  • 原文地址:https://www.cnblogs.com/halao/p/11512791.html
Copyright © 2011-2022 走看看