zoukankan      html  css  js  c++  java
  • 大白话理解this

    日常开发中,我们经常用到this。一开始常会用一种感觉去判断this的指向,当遇到复杂的函数调用时,就分不清this的指向。

    今天我们来由浅入深来学习下。

    function family1(){
        var name = "小白";
        console.log(this); //Window
        console.log(this.name); //undefined
    }
    family1();  // 等同于 window.family()

    this指向的是调用它的对象,family处于全局,等同于 window.family(),此刻this等同于由window调用的, window中不存在name, 故为undefined

    函数作为对象的一个属性

    var family2 = {
        name:"小白",
        fn:function(){
            console.log(this.name);  //小白
        }
    }
    family2.fn();

    this指向的是对象family2,因为fn不仅作为一个对象family2的一个属性,而且是作为对象的一个属性被调用,即通过family2.fn()执行的。结果this就是对象family2。

    var family2 = {
        name:"小白",
        fn:function(){
         console.log(this) //window console.log(
    this.name); //undefined } } var newfn = family2.fn();
    newfn();

    如果fn函数被赋值到了另一个变量newfn中,并没有作为family2的一个属性被调用,那么this的值就是window,this.name为undefined。

    构造函数中this,new实例化

    如果函数作为构造函数用,那么其中的this就代表它即将new出来的对象。

    function Fn(){
        this.name = "小白",  
       console.log(this)
    }
    var family3 = new Fn();
    console.log(family3.name); //小白

    因为new关键字可以改变this的指向,将这个this指向对象family3, 变量family3创建了一个Fn的实例(相当于复制了一份Fn到对象family3里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象family3,那么this指向的自然是对象family3,那么为什么对象family3中会有name,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份。

        function Fn(){
            this.name = "小白",
             console.log(this)  // window
        }
        Fn()

    函数用call或者apply调用

    当一个函数被call和apply调用时,this的值就取传入的对象的值。 

    我们通过几道题来练练手吧。

        var a=11
        function test1(){
            this.a=22;
            console.log(this); //window,此时通过this修改了全局变量a的值,由11为22
            let b = function(){
                console.log(this); //window
                console.log(this.a); // 22
            };
            b();
        }
        test1();
     var a=11
        function test1(){
            console.log(this) //  function test1()
            this.a=22;  // 相当于给test1函数添加了 var a = 22
            let b=function(){
                console.log(this) //window
                console.log(this.a); // 11
            };
            b();
        }
        var t = new test1();

     以下几题进行对比

            var val = 1;
            var obj = {
                val: 3,
                fun: function () {
                    console.log(val);  // 1
                    this.val *= 2;
                    //this指向window,故window里面的window.val = val*2
                    console.log(val);  // 2
                    val *= 2;
                    //指window, window.val = val * 2
                    console.log(val); // 4  在 this.val *= 2的基础上再 val*2
                    console.log(this.val); // 4
                }
            };
            var objFun = obj.fun;
            objFun(); // 1 2 4 4
          var val = 1;
            var obj = {
                val: 3,
                fun: function () {
                    this.val *= 2; //this指向obj,故obj里面的obj.val = val*2
                    console.log(val);  // 1
                    val *= 2;  //指window, window.val = val * 2
                    console.log(val);// 此时val为1; 即 1*2
                    console.log(this.val); // this为obj; 此时val为3;即3*2
                }
            };
            obj.fun(); // 1 2 6
            var val = 1;
            var obj = {
                val: 3,
                fun: function () {
                    this.val *= 2;
                    console.log(val);  // 1
                    val *= 2;
                    console.log(val);//
                    console.log(this.val); // this为obj; 此时val为3;即3*2
                }
            };
            obj.fun(); // 1 2 6 
            var objFun = obj.fun; // 此时初始化window.val = 2; obj.val = 6
            objFun(); // 4 8 8   注: 第一次调用后obj.fun影响第二次调用objFun   

     以下两个例子对比

          var name = "The Window";
           var object = {
               name : "My Object",
               getNameFunc : function(){
                   console.log(this) // obj
                   var that = this;
                   return function(){
                       console.log(that) //obj
                       return that.name;
                   };
               }
           };
           console.log(object.getNameFunc()()); //My Object
        var name = "The Window";
           var object = {
               name : "My Object",
               getNameFunc : function(){
                   console.log(this) // obj
                   return function(){
                       console.log(this) //window
                       return this.name;
                   };
               }
           };
           console.log(object.getNameFunc()()); //The Window
    object.getNameFunc()返回的是一个匿名函数,匿名函数的this是window

    以下是英文原文:

    Anonymous functions are not bound to an object in this context, meaning the this object points to window unless executing in strict mode (where this is undefined).

    翻译:在这个上下文(执行环境)中匿名函数并没有绑定到任何一个对象中,意味着this指向window

    (除非这个上下文(执行环境)是在严格模式‘use strict’下执行的,而严格模式下该this指向undefined)

  • 相关阅读:
    趋势or过渡,量子点屏幕真的优于OLED?
    文件打开方式设置
    学Arduino 需要做哪些准备?(引自"知乎用户:郑兴芳,DhP"的回答)
    Arduino扫盲(持续添加中)
    订购一套Arduino UNO r3入门套件
    第一次接触Arduino
    关于移动端的事件委托问题
    ASDas
    CentOS利用source命令导入sql文件
    CentOS-LAMP
  • 原文地址:https://www.cnblogs.com/renzm0318/p/10342906.html
Copyright © 2011-2022 走看看