大白话理解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)

posted @ 2019-02-19 11:07  灰姑娘的冰眸  阅读(220)  评论(0编辑  收藏  举报