Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于this的一点感悟 #15

Open
junfeisu opened this issue Oct 9, 2018 · 0 comments
Open

关于this的一点感悟 #15

junfeisu opened this issue Oct 9, 2018 · 0 comments

Comments

@junfeisu
Copy link
Owner

junfeisu commented Oct 9, 2018

在各个编程语言中this都是一个令人头疼的问题,因为this的指向情况实在有点复杂,尤其是在js这种类编程语言中。在js中刚开始不熟的时候都会以为俩种情况。

  1. this指向自身

  2. this指向函数的作用域

第一种是不对的,比如看一下后面的代码:

test.count = 2
function test () {
  this.count = 3 // 指向自身的话这里的this就指向test
}

test()
console.log(test.count)


但是结果还是2,说明test里面的this并未指向test

第二种首先简单说一下什么是作用域,作用域就是函数的可访问区域(变量),而且作用域是嵌套的。

function test () {
  var a = 2
  console.log(this.a)
}
test() // --> undefined

如果this指向当前作用域的话,输出的应该是2,而不是undefined

既然上面的说法都不对,那么this到底指向什么,我自己通过js大红书《JavaScript高级程序设计》和《你不知道的JavaScript上卷》俩本书中对这部分的介绍总结了一下就是。

this指向触发含有this操作的函数的最初对象自身(不包括callapply这俩种情况)

当然这样说肯定都没理解是什么意思,因为我也不好总结,还是用代码说话最直接。

var a = 'window'
function test () {
  console.log(this.a)
}
test() // 相当于window.test()

function test1 () {
  console.log(this.a)
}
var obj = {
  a: 'obj',
  foo: test1
}
obj.foo() // --> 'obj'
  • 最初触发test函数的对象就是window,这个时候test里面的this指向window对象,所以结果就是输出'window'
  • 最初触发test1函数的对象是obj,这个时候test1里面的this指向obj对象,所以结果就是'obj'

当然如果函数体使用的是严格模式而不是调用位置的话,this不会指向window对象, eg:

  var a = 'window'
  function test () {
    'use strict'
    console.log(this.a)
  }
  test() 


上面的严格模式强调使用的地方是函数体,在具体一下:

当然上面的俩个例子是最普通的情况,下面咱们再看一下其他几种特殊的情况

  • this操作相关的别名函数

    var obj = {
      a: 'obj',
      foo: function () {
        console.log(this.a)
      }
    }
    
    var a = 'window'
    var bar = obj.foo
    bar() // --> 'window'  
    

// 最初触发obj.foo函数的是bar()函数,而调用bar的就是window对象

  • 参数为与this操作相关的函数

    function test () {
      console.log(this.a)
    }
    
    var obj = {
      a: 'obj',
      foo: test
    }
    
    var a = 'window'
    
    function executeFn (fn) {
      fn()
    }
    
    executeFn(obj.foo) // --> 'window'
    // 最初触发test函数的就是executeFn函数,而调用它的又是window对象,所以结果还是'window'
    

然后就是call和apply的情况就是强制将this绑定到call和apply的对象上面。

谢谢大家的浏览,如有错误欢迎大家指正。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant