跳转至

This

为什么要使用this#

this提供了一种更为优雅的方式来隐式的传递一个对象引用,因此可以将一个API设计的更为简洁
随着你使用的模式越来越复杂,显示的传递上下文对象会让代码变得越来越复杂。
在对象和原型中,你就会明白函数可以自动引入合适的上下文对象多么重要。

this的两个误解#

this指向函数自身#

javascript中所有函数都是对象
所以函数中是可以存放属性值(即状态),但是除了函数对象本身,还有其他更合适的地方。

this.没办法调用函数本身的属性

function foo(sum){
    console.log{"foo:"+sum}
    //记录this下边的count
    this.count++
}
foo.count=0

var i;
for(i=0,i<10;i++){
    if(i>5){
        foo(i)
    }
}

-----output------
//foo:6
//foo:7
//foo:8
//foo:9

console.log(foo.count)
//0

输出foo:5...等4次,证明调用了foo()四次,(windows调用的)
但是foo对象上的属性count还是0,
其实这里的操作是this指向了window,
所以是在window上默认添加了一个count属性,换句话说创建了一个全局变量

证明:this并不是指向函数本身,而是指向的调用函数的,这里是window,我称为执剑人

⭐ 回到词法作用域
一种逃避this的解决方法是回到词法作用域
1.在函数内部调用自身属性,用一个指向函数对象的词法标识符(变量)来引用它
题外话:为什么要在函数内部调用他自己呢,递归

function foo(sum){
    console.log{"foo:"+sum}
    foo.count++ //将this替换成foo
}
foo.count=0

var i;
for(i=0,i<10;i++){
    if(i>5){
        foo(i)
    }
}

-----output------
//foo:6
//foo:7
//foo:8
//foo:9

console.log(foo.count)
//4

2.创建另一个带有count属性的对象,另起炉灶,不用函数对象属性

function foo(sum){
    console.log{"foo:"+sum}
    data.count++ //将this替换成foo
}
var data={
  count=0
}
var i;
for(i=0,i<10;i++){
    if(i>5){
        foo(i)
    }
}

-----output------
//foo:6
//foo:7
//foo:8
//foo:9

console.log(data.count)
//4

⭐ 强制this指向

function foo(sum){
    console.log{"foo:"+sum}
   //记录foo被调用次数
   //注意:在当前方式下,this确实指向了foo
    this.count++ 
}
foo.count=0

var i;
for(i=0,i<10;i++){
    if(i>5){
        //使用call(..)可以确保this指向函数本身
        foo.call(foo,i)
    }
}

-----output------
//foo:6
//foo:7
//foo:8
//foo:9

console.log(foo.count)
//4