zoukankan      html  css  js  c++  java
  • 对js中this的一点点理解

    1 当函数作为对象的方法被调用的时候 this就指向该对象

    var o = {
      prop: 37,
      f: function() {
        return this.prop;
      }
    };
    
    console.log(o.f()); // logs 37

    上面的例子中,当 o.f() 被调用时,函数内的this将绑定到o对象。

    在何处或者如何定义调用函数完全不会影响到this的行为。在上一个例子中,我们在定义o的时候为其成员f定义了一个匿名函数。但是,我们也可以首先定义函数然后再将其附属到o.f。这样做this的行为也一致:

    var o = {prop: 37};
    
    function independent() {
      return this.prop;
    }
    
    o.f = independent;
    
    console.log(o.f()); // logs 37

    这说明this的值只与函数 f 作为 o 的成员被调用有关系。

    类似的,this 的绑定只受最靠近的成员引用的影响。在下面的这个例子中,我们把一个方法g当作对象o.b的函数调用。在这次执行期间,函数中的this将指向o.b。事实上,这与对象本身的成员没有多大关系,最靠近的引用才是最重要的。

    o.b = {
      g: independent,
      prop: 42
    };
    console.log(o.b.g()); // logs 42

    2 作为普通函数调用的时候 thi指向全局对象window

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div id="div1"></div>
    <script>
        window.id = 'window';
        document.getElementById('div1').onclick = function () {
            console.log(this.id); //div1
            var cb = function () {
                console.log(this.id); 
            };
            cb(); //window
        }
    </script>
    </body>
    </html>

    上述代码中的document.getElementById('div1')返回一个dom元素对象,所以该点击监听事件作为该对象的方法调用,this指向id为div1的dom元素对象,this.id为div1;

    而点击事件中的函数cb是普通函数,所以this指向window,this.id为window。

    3 在严格模式下this不会指向全局对象,而是undefined , 如下:

    function func () {
      'use strict';
     console.log(this === undefined);
    }
    func();  // true

    4 丢失的this

    var obj = {
            name: 'peak',
            getName: function () {
                return this.name;
            }
        };
        console.log(obj.getName()); // peak
        var getNm = obj.getName;
        console.log(getNm()); // undefined
    调用obj.getName时 getName方法作为obj对象的方法被调用 此时this指向obj对象
    当obj.getName 赋值给 getNm 时 调用getNm 是作为普通函数的调用 此时this指向全局对象window

    5 构造函数中的this

    如果函数和new关键字一起使用,则这个函数称为构造函数。在函数内部,this会指向新创建的对象。

        function Foo(){
            this.name = "foo"; 
        }
        Foo.prototype.sayHello = function(){
            console.log('hello,'+this.name)
        };
    
        var foo = new Foo();
        foo.sayHello;  // hello,fo

    上述代码中this则指向新创建的对象foo

    注意:构造器可以手动设置返回其他的对象,如果返回值不是一个对象,则返回this,否者,返回该对象。

    function C2(){
      this.a = 37;
      return {a:38};
    }
    
    o = new C2();
    console.log(o.a); /

    6 使用apply、call显示的设置this

    function foo(a, b, c) {}
    var bar = {};
    foo.apply(bar, [1, 2, 3]); // 数组将作为函数的参数被接收,如下所示
    foo.call(bar, 1, 2, 3); // 传递到foo的参数是:a = 1, b = 2, c = 3

    当使用 Function.prototype 上的 call 或者 apply 方法时,函数内的 this 将会被 显式设置为函数调用的第一个参数。

    因此函数调用的规则在上例中已经不适用了,在foo 函数内 this 被设置成了 bar。

    使用 call 和 apply 函数的时候要注意,如果传递的 this 值不是一个对象,JavaScript 将会尝试使用内部 ToObject 操作将其转换为对象。因此,如果传递的值是一个原始值比如 7 'foo' ,那么就会使用相关构造函数将它转换为对象,所以原始值 7 通过new Number(7)被转换为对象,而字符串'foo'使用 new String('foo') 转化为对象,例如:

    function bar() {
      console.log(Object.prototype.toString.call(this));
    }
    
    bar.call(7); // [object Number]

    7 bind 方法

    ECMAScript 5 引入了Function.prototype.bind。调用f.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久地被绑定到了bind的第一个参数,无论这个函数是如何被调用的。

    function f(){
      return this.a;
    }
    
    var g = f.bind({a:"azerty"});
    console.log(g()); // azerty
    
    var o = {a:37, f:f, g:g};
    console.log(o.f(), o.g()); // 37, azerty

    注意: 在对象的字面声明语法中,this 不能用来指向对象本身。 因此 var obj = {me: this} 中的 me 不会指向 obj,因为 this 只可能出现在上述的五种情况中。 这个例子中,如果是在浏览器中运行,obj.me 等于 window 对象。

     

  • 相关阅读:
    Windows下NodeJS环境搭建
    大前端是什么?
    TeamCity+Rancher+Docker实现.Net Core项目DevOps(目前成本最小的DevOps实践)
    2019春运抢票终极攻略,让你躺着也能抢到票回家!
    ASP.NET CORE 2.0 发布到IIS,IIS如何设置环境变量来区分生产环境和测试环境
    使用第三方容器服务,自动化部署.Net Core
    记React+.NetCore API实现动态列导出
    6.前端基于react,后端基于.net core2.0的开发之路(6) 服务端渲染(SSR)
    5.前端基于react,后端基于.net core2.0的开发之路(5) 配置node层,session设置、获取,请求拦截
    4.前端基于react,后端基于.net core2.0的开发之路(4) 前端打包,编译,路由,模型,服务
  • 原文地址:https://www.cnblogs.com/peakleo/p/6086748.html
Copyright © 2011-2022 走看看