zoukankan      html  css  js  c++  java
  • This in JavaScript

    声明 本文仅为读书笔记并致力于理解Js中的this关键字。如有雷同,纯属巧合。原因有二,其一:有幸看了同一本书,其二:this这玩意已被说烂了~

    1. 为什么要用this?

      this提供了优雅的方式隐式传递对象的引用

      上实例:

      function sayEng(){
          console.log(this.name+":sayEng");
      }
      function sayChi(){
          console.log(this.name+":sayChi");
      }
      function stu(){
          name = "stu";
      }
      function tea(){
          name = "tea";
      }
      sayEng.call(stu);//stu:sayEng
      sayEng.call(tea);//tea:sayEng
      sayChi.call(stu);//stu:sayChi
      sayChi.call(tea);//tea:sayChi
      

      当不使用this时

        function sayEng(ctx){
            console.log(ctx.name+"sayEng");
        }
        function sayChi(ctx){
            console.log(ctx.name+"sayChi");
        }
        function stu(){
            name = "stu";
        }
        function tea(){
            name = "tea";
        }
        sayEng(stu);//stu:sayEng
        sayEng(tea);//tea:sayEng
        sayChi(stu);//stu:sayChi
        sayChi(tea);//stea:sayChi
        ```
        两种对比,可以看出当不使用this时,需**手动显式传递一个上下文对象**。而使用了this可以使得代码很精炼。而且传递上下文的方式会使得代码越来越混乱。
     2. 对this的误解
     1)指向自身(书中代码)
        ```javascript
        function foo(num) {
            console.log( "foo: " + num );
         // count用于记录foo的被调用次数
            this.count++;
        }
        foo.count = 0;
        var i;
        for (i=0; i<10; i++) {
            if (i > 5) {
                foo( i );
            }
        }
        console.log( foo.count ); // 0 -- ??
        ```
        **为什么是0,而不是4?原因在于,此时调用foo函数的是window,this的指向是window。**
        解决办法有两种:
        其一,用foo代替this。也就是foo.count++。
        其二,强制this指向foo,通过call,或者apply。也就是在if里面改为foo.call(foo,i)。
     2)指向函数的作用域
     
        ```javascript
        function foo() {
            var a = 2;
            this.bar();
        }
        function bar() {
            console.log( this.a );
        }
        foo(); //ReferenceError:a is not defined
        ```
        **原因在于:调用foo的对象为window**
     3. 绑定规则
        1)默认绑定
            若函数是直接使用不带任何修饰的函数引用的,它便是应用了默认绑定。this指向window,上面的实例可以佐证。
        p.s *当使用严格模式时,则不能将全局对象用于默认绑定*
        2)隐式绑定
        
        ```javascript
        function foo() {
            console.log( this.a );
        }
        var obj = {
            a: 2,
            foo: foo
        };
        obj.foo(); // 2
        ```
        本例就使用了默认绑定,this绑定在obj上。**另外,对象属性引用链只有上一层或者说最后一层在调用位置中起作用。**也即,obj1.obj2.foo(),this绑定在obj2中。
        但是,隐式绑定经常会有一个问题产生--**隐式丢失**
        ```javascript
        function foo() {
            console.log( this.a );
        }
        var obj = {
            a: 2,
            foo: foo
        };
        var bar = obj.foo; // 函数别名
        var a = "oops,global";
        bar(); // "oops,globa"
        ```
        this的指向不再是obj,而变成了window。丢失了this的指向。同理还有当obj.foo作为参数传递时丢失,原因在于参数传递相当于两个步骤,一赋值,二参数传递。
        3)显示传递
        通过call、apply的方式,将this绑定在对象上。具体call、apply的使用方法见本人博客[Call and Apply in JavaScript](http://www.cnblogs.com/zhaoww/p/5247827.html)
        4)new绑定
        ```javascript
        function foo(a) {
            this.a = a;
        }
        var bar = new foo( 2 );
        console.log( bar.a );// 2
        ```
        使用new调用时,会构造一个对象并将this指向进行绑定。如本例的foo上。
     4. 优先级
        new绑定>显示绑定>隐式绑定>默认绑定
    
    
    ----------
    >*本人较懒,部分代码原封不动摘抄自原著。还请见谅*
  • 相关阅读:
    git 常用命令总结
    Activiti(工作流)如何关联业务表
    常见数据结构复杂度
    linux 启动 oracle数据库
    word2vec 入门(三)模型介绍
    数组中出现次数超过一半的数字 -java
    word2vec 入门(二)使用教程篇
    word2vec 入门基础(一)
    Stackoverflow上人气最旺的10个Java问题(转ImportNew)
    leetcode 326. Power of Three(不用循环或递归)
  • 原文地址:https://www.cnblogs.com/zhaoww/p/5679571.html
Copyright © 2011-2022 走看看