this综合篇

var name = 'window'
var person1 = {
  name: 'person1',
  foo1: function () {
    console.log(this.name)
  },
  foo2: () => console.log(this.name),
  foo3: function () {
    return function () {
      console.log(this.name)
    }
  },
  foo4: function () {
    return () => {
      console.log(this.name)
    }
  }
}
var person2 = { name: 'person2' }

person1.foo1() 
person1.foo1.call(person2) 

person1.foo2() 
person1.foo2.call(person2) 

person1.foo3()() 
person1.foo3.call(person2)() 
person1.foo3().call(person2) 

person1.foo4()() 
person1.foo4.call(person2)() 
person1.foo4().call(person2)




答案:
// 'person1'
// 'person2'


// 'window'
// 'window'

// 'window'
// 'window'
// 'person2'



// 'person1'
// 'person2'
 // 'person1'

var name = 'window'
function Person (name) {
  this.name = name
  this.foo1 = function () {
    console.log(this.name)
  },
  this.foo2 = () => console.log(this.name),
  this.foo3 = function () {
    return function () {
      console.log(this.name)
    }
  },
  this.foo4 = function () {
    return () => {
      console.log(this.name)
    }
  }
}
var person1 = new Person('person1')
var person2 = new Person('person2')

person1.foo1() 
person1.foo1.call(person2) 

person1.foo2() 
person1.foo2.call(person2) 

person1.foo3()() 
person1.foo3.call(person2)() 
person1.foo3().call(person2) 

person1.foo4()() 
person1.foo4.call(person2)() 
person1.foo4().call(person2) 


答案:
// 'person1'
// 'person2'

// 'person1'
// 'person1'

// 'window'
// 'window'
// 'person2'


// 'person1'
// 'person2'
// 'person1'
var name = 'window'
function Person (name) {
  this.name = name
  this.obj = {
    name: 'obj',
    foo1: function () {
      return function () {
        console.log(this.name)
      }
    },
    foo2: function () {
      return () => {
        console.log(this.name)
      }
    }
  }
}
var person1 = new Person('person1')
var person2 = new Person('person2')

person1.obj.foo1()()
person1.obj.foo1.call(person2)()
person1.obj.foo1().call(person2)

person1.obj.foo2()()
person1.obj.foo2.call(person2)()
person1.obj.foo2().call(person2)


答案是:


window
window
person2


obj
person2
obj

person1.obj.foo1()()返回的是一个普通的匿名函数,调用它的是window,所以打印出window。
person1.obj.foo1.call(person2)()中是使用.call(person2)改变第一层函数中的this,匿名函数和它没关系,依旧是window调用的,所以打印出window。
person1.obj.foo1().call(person2)是通过.call(person2)改变匿名函数内的this,所以绑定有效,因此打印出person2。
person1.obj.foo2()()第一层为普通函数,第二层为匿名箭头函数。首先让我们明确匿名箭头函数内的this是由第一层普通函数决定的,所以我们只要知道第一层函数内的this是谁就可以了。而这里,第一层函数最后是由谁调用的呢 🤔️?是由obj这个对象,所以打印出obj。
person1.obj.foo2.call(person2)()中使用.call(person2)改变了第一层函数中的this指向,所以第二层的箭头函数会打印出person2。
person1.obj.foo2().call(person2)中使用.call(person2)想要改变内层箭头函数的this指向,但是失败了,所以还是为外层作用域里的this,打印出obj。





function foo() {
  console.log( this.a );
}
var a = 2;
(function(){
  "use strict";
  foo();
})();


答案并不是undefined,也不会报错,而是打印出了2。
其实这里是有一个迷惑点的,那就是"use strict"。
我们知道,使用了"use strict"开启严格模式会使得"use strict"以下代码的this为undefined,也就是这里的立即执行函数中的this是undefined。
但是调用foo()函数的依然是window,所以foo()中的this依旧是window,所以会打印出2。
如果你是使用this.foo()调用的话,就会报错了,因为现在立即执行函数中的this是undefined。
或者将"use strict"放到foo()函数里面,也会报错。


这几个题前面this详解的时候有详细描述,不懂的可以翻阅之前this的内容。也可留言。

欢迎加群一起进步

 

 

posted on 2020-03-22 13:14  前端架构师  阅读(108)  评论(0编辑  收藏  举报

导航

  • !