先看題目:
第一題:
var name = 'window'
var person1 = {
? ? name: 'person1',
? ? show1: function () {
? ? ? ? console.log(this.name)
? ? },
? ? show2: () => console.log(th
? ? show3: function () {
? ? ? ? return function () {
? ? ? ? ? ? console.log(this.na
? ? ? ? }
? ? },
? ? show4: function () {
? ? ? ? return () => console.lo
? ? }
}
var person2 = { name: 'person2'
person1.show1()
person1.show1.call(person2)
person1.show2()
person1.show2.call(person2)
person1.show3()()
person1.show3().call(person2)
person1.show3.call(person2)()
person1.show4()()
person1.show4().call(person2)
person1.show4.call(person2)()
第二題:
var name = 'window'
function Person(name) {
? ? this.name = name;
? ? this.show1 = function () {
? ? ? ? console.log(this.name)
? ? }
? ? this.show2 = () => console.
? ? this.show3 = function () {
? ? ? ? return function () {
? ? ? ? ? ? console.log(this.na
? ? ? ? }
? ? }
? ? this.show4 = function () {
? ? ? ? return () => console.lo
? ? }
}
var personA = new Person('perso
var personB = new Person('perso
personA.show1()
personA.show1.call(personB)
personA.show2()
personA.show2.call(personB)
personA.show3()()
personA.show3().call(personB)
personA.show3.call(personB)()
personA.show4()()
personA.show4().call(personB)
personA.show4.call(personB)()
普通函數和匿名函數的this指向及特性:
普通函數:this指向調用函數的對象;若為構造函數,那么指向實例對象;箭頭函數都是匿名函數;
匿名函數:this指向外面最近一層函數的this,如果最外層沒有函數,那么在瀏覽器環境下指向windows;匿名函數的this不能使用call()、bind()、apply()改變;
解析過程:(第一個題的第一個小題用1.1表示)
1.1:調用person1中的show1函數,為普通函數,this指向本對象的this,因此打印person1。
1.2:調用person1中的show1函數,并將this指向改成person2,因此打印person2。
1.3:調用person1中的show2函數,為箭頭函數,this指向外面最近一層函數的this,外面最近一層沒函數,所以指向windows,因此打印window。
1.4:調用person1中的show2函數,使用call修改this指向,但是this2為箭頭函數,不可修改,所以依舊打印window。
1.5:調用person1中的show3函數,并再次調用返回函數,show3和返回函數都是普通函數,調用show3之后返回一個匿名函數,之后再調用返回的匿名函數,相當于直接調用匿名函數,因此直接打印window。
1.6:調用person1中的show3函數,使用call修改返回函數的this指向,并再次調用返回函數,所以打印person2。
1.7:調用person1中的show3函數,使用call修改show3的this指向,并再次調用返回函數,而返回函數的this指向和show3的this指向無關,所以依舊打印window。
1.8:調用person1中的show4函數,并再次調用返回函數,show4為普通函數,返回函數為箭頭函數,箭頭函數的this指向為外面最近一層普通函數的this,即show4的this,因此打印person1。
1.9:調用person1中的show4函數,使用call修改返回函數的this指向,并再次調用返回函數,箭頭函數的this不可改變,所以依舊打印person1。
1.10:調用person1中的show4函數,使用call修改show4的this指向,并再次調用返回函數,返回函數的this指向外面最近一層的普通函數,因此打印person2。
2.1:調用構造函數personA中的show1函數,為普通函數,因此打印personA。
2.2:修改調用構造函數personA中的show1的this指向,并調用,show1為普通函數,因此打印personB。
2.3:調用構造函數personA中的show2函數,為箭頭函數,指向外層最近的普通函數的this,在第一題中,person1只是一個對象,所以指向windows,但是在第二題中,personA為構造函數,show2指向的就是personA,所以依舊打印personA。
2.4:改變構造函數personA中的show2函數this指向,并調用,但是show2為箭頭函數,this不可修改,所以依舊打印personA。
2.5:調用構造函數personA中的show3函數,并再次調用返回函數,調用show3之后得到一個匿名函數,再次調用匿名函數this指向windows,所以打印window。
2.6:調用構造函數personA中的show3函數,改變返回函數的this,并調用返回函數,調用show3之后得到一個匿名函數,再次調用匿名函數this指向被修改為personB,所以打印personB。
2.7 :改變構造函數personA中的show3函數的this指向,并再次調用返回函數,返回函數的this指向和show3的指向無關,所以依舊打印window。
2.8:調用構造函數personA中的show4函數,并再次調用返回函數,show4為普通函數,this指向personA,返回函數為箭頭函數,this指向外面最近一層普通函數的this,打印personA。
2.9:調用構造函數personA中的show4函數,改變返回函數的this,并再次調用返回函數,箭頭函數的this不可修改,所以依舊打印personA。
2.10:修改show4的this指向,并調用,再調用返回函數,返回函數的this指向外面一層普通函數的this,因此打印personB。