js中除了声明定义的形参之外,每个函数还可以接收两个附加参数(this、arguments)。这里我们就来仔细学习一下this吧。

在javascript中明确this指向大致有四种情况

函数调用的模式this指向window
function aa()
{
    console.log(this);
}
aa(); // window
方法调用模式, this指向方法所在的对象
var a = {};
a.name = 'zjj';
a.getName = function(){
    console.log(this.name);
}
a.getName();   // 'zjj',这里this指向的是调用的那个对象
构造函数模式, this指向新生成的实例
function aaa(name){
    this.name = name;
    this.getName = function(){
        console.log(this.name);   // 这里的this指向实例化的对象
    }
}

var a = new aaa('meils');
a.getName(); // 'meils'

var b = new aaa('bobo');
b.getName()        //  'bobo'
apply/call调用模式
var list1 = {name: 'zjj'};
var list2 = {name: 'lll'};

function a(){
    console.log(this.name);
}

a.call(list1);  // 'zjj'
a.call(list2);  // 'lll'

先来一个面试题吧

obj = {

    name: 'a',

    getName : function () {

        console.log(this.name);console.log(this);

    }

}


var fn = obj.getName

obj.getName() // 这里this指向的是调用getName的那个对象

var fn2 = obj.getName() // 同上执行一次 ,返回的fn2已经不是一个函数了

fn()        // 这里的this指向的是window,由于window下并没有name变量,所以没有输出

fn2()        // 由于fn2不是一个函数,因此会报错
// 输出如下

a
{name: "a", getName: ƒ}
a
{name: "a", getName: ƒ}getName: ƒ ()name: "a"__proto__: Object

Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
Uncaught TypeError: fn2 is not a function
下面我们依旧通过例子来学习this哦

实例一

function demo1(){
    console.log(this)  
}
function demo2(){
    this.num=2
    function demo3(){
          this.num++
          console.log(num)
    }
    return demo3; 
}


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()

// {value: 4, increment: ƒ}  4

实例二

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() // this是obj2
obj2.print()
var P=obj2.print
P() // this是window

// 
{value: 5, increment: ƒ, print: ƒ} 5
这又是啥 Window  undefined
print 5
print 1
obj2.increment() this是obj2,执行了value++,此时的value为5,而后是一个自我执行的函数,这里的this是window,由于window下的value还没有申明,因此返回的是undefined。之后执行obj2.print()这里的this是obj2,输出value是5,而后变量P执行了obj2的print方法,这里的this指向了window,所以输出的是1
ES6的箭头函数

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

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了
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对象(this没绑定的嘛),后面的value当然又是没声明.....然后自执行函数也没得说,后面才接着给window的value赋值为1了,后面就两句自然输出两次1了

相信看了上面的例子,大家一定对this的使用有了一定的了解了吧。加油,多看几遍,影像会更深的呢


Meils
1.6k 声望157 粉丝

前端开发实践者