我们知道js中有个全局对象就是window,如果在顶层声明一个变量如

var a=1 //就相当于window.a=1

同时有了node以后,js也可以在服务端运行了,官方解释为Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。通俗说node是一个支持js语法的容器,直接写js就可以在node下运行。这里介绍node主要说一下在node中的全局变量叫global,就像window一样有一些js默认的变量和方法。下面只探讨this在浏览器中的指向,有兴趣的也可以把后面的例子在node中跑一下。

this一般在函数中使用比较多,那就从函数说起吧,我们调用的函数一般分为声明式函数,或者是放在对象中作为方法的函数

一、声明式
function demo1(){
    console.log(this)  
}
function demo2(){
    this.num=2
    function demo3(){
          this.num++
          console.log(num)
    }
    return demo3
}
demo1() // 调用demo1函数,这里this很显然指向window
var a=demo2();
a()  // 这里看到会打印出3,应该也很好理解,a变量将demo2函数执行后的的返回值及demo3函数返回,然后执行,此时this依旧指向window
二、对象中的方法调用
var obj1={
      value:3,
      increment:function(){
           this.value++;
           console.log(this,this.value)
      }
}
obj1.increment() //  obj1{value:4,increment:function(){...}},4 ;打印出obj1对象和4,obj1包含一个value值和一个increment方法,也好理解

在看一个例子

var obj2={
      value:4,
      increment:function(){
           this.value++;
           console.log(this,this.value);
           (function(){
                 console.log('这又是啥',this,this.value)
                 this.value=1
           })() 
      },
      print:function(){
            console.log('print',this.value)
      }
}
obj2.increment() 
obj2.print()
var P=obj2.print
P()
// 打印结果出如下
// {value: 5, increment: ƒ, print: ƒ} 
// 5
// 这又是啥 Window 
// undefined
// print 5
// print 1
依次分析:
第一条先执行obj2中的increment方法,跟上一个例子一样,这里的this是指向我obj2对象,所以this.value再执行+1以后为5,后面是一个自执行函数,这里面的this直接指向了window,window的value一开始不存在所以为undefined,后面增加一个全局变量value值为1;然后是第二条直接执行obj2中的方法print,此时的this还是obj2所以值为5,;然后是第三条声明一个变量P指向obj2中的print方法,执行这个方法这是this指向window,所以输出1
总结来说:
使用声明式函数(后面两个对象中的方法也是使用的声明式函数)会自动绑定this,直接在全局中声明的函数this会直接指向window对象

延伸一下,现在我们都经常会用的es6的箭头函数,箭头函数是不会自动绑定this的,默认从上一级继承下来,那不妨把刚才的例子改下看看

例子1改写
var demo1=()=>{
    console.log(this)  
}
var demo2=()=>{
    this.num=2
    function demo3(){
          this.num++
          console.log(num)
    }
    return demo3
}
demo1() // 调用demo1函数,这里this还是指向window,因为之前说的在全局下声明本身就有个this指向window对象
var a=demo2();
a()  // 3,这里也一样
例子2改写
var obj1={
      value:3,
      increment:()=>{
           this.value++;
           console.log(this,this.value)
      }
}
obj1.increment() // 这时候会看到输出window对象和一个NaN
简单说明下:
如前面所说箭头函数不会自动绑定this,所以执行increment函数中的this依旧会指向window,而window下的value还不存在,所以为undefined再执行+1操作所以value就变成了NaN
例子3改写
var obj2={
      value:4,
      increment:()=>{
           this.value++;
           console.log(this,this.value);
           (function(){
                 console.log('这又是啥',this,this.value)
                 this.value=1
           })() 
      },
      print:()=>{
            console.log('print',this.value)
      }
}
obj2.increment() 
obj2.print()
var P=obj2.print
P()
// 打印结果出如下
// Window 
//  NaN
// 这又是啥 Window
// NaN
// print 1
// print 1
简单说明下:
第一个依旧window对象,后面的value当然又是没声明.....然后自执行函数也没得说,后面才接着给windowvalue赋值为1了,后面就两句自然输出两次1了

RaKL
209 声望10 粉丝