preface

This point is the basis of the js foundation, of course, is also the factory interview often test. The following I this question is ali front-end interview appeared a question, we look at the topic, think about it, see if you can answer it

    var name = 222
    var a = {
        name:111.say:function(){
            console.log(this.name)  
        }
    }
    var fun = a.say 
    fun() 
    a.say() 
    var b = {
        name: 333.say: function(fn) {
             fn()
        }
    }
    b.say(a.say) 
    b.say = a.say 
    b.say() 
Copy the code

Let’s not rush into writing the answer right now. Let’s start with the concept of this

concept

The reference to this is undefined at function definition, and only at function execution can we finally determine who it refers to. This always refers to the object that called it last, depending on who called it when it was executed

Several scenarios executed by this

  • Used directly in a function, pointing to the window
function sayHi(str){
    console.log(str)
}
sayHi('hello')
// sayHi('hello') ===sayHi.call(window,'hello')
Copy the code
  • The function is called as a method of the object (I point to whoever calls me)
var person = {
    name:'Cynthia'.gender:'female'.say:function(str){
        console.log('My English name isThe ${this.name}The Chinese name${str}`)
    }
}
person.say('... Hahaha, not telling you ')
// person.say() equals person.say.call(person,'... Hahaha, not telling you ')
Copy the code
  • Execute as a constructor
function Foo(name){
	this.name = name
  console.log(this) // point to the constructor Foo
}
var f = new Foo('Cynthia')
Copy the code
  • Call, apply, and bind change the direction of this
     function fn(name,age){
            console.log(name)
            console.log(this) // 
        }
        fn.call({x:100},'lily'.20) // this-->{x:100}
        fn.apply({b:1023},'week'.30]) // this-->{y:1023}
        var fn2 = function(name,age){
            console.log(name) / / zhang SAN
            console.log(this) // {y:100}
        }.bind({y:200})
        fn2('Joe'.30)
Copy the code

Knowing the above, let’s begin to explain the topic at the beginning

    var name = 222
    var a = {
        name:111.say:function(){
            console.log(this.name)
        }
    }
    var fun =a.say // Direct calls to fun.call(window) refer to window
    fun() // This refers to window, so 222
    a.say() // a.say.call(a) 111
    var b ={
        name:333.say:function(fn){
            fn()
        }
    }
    b.say(a.say) // This is equivalent to a direct call to a function that would point to the window, so 222
    b.say = a.say =function(){console.log(this.name)} {console.log(this.name)}
    b.say() // b/.say.call(b) output is 333
Copy the code
  • Fun () :a.sayAssigned tofunWhen it comes to just putting thisa.sayThe function is assignedfunFor the time of,funThat’s equivalent to a function, so the delta functionthisAs long as you don’t change its pointing, its default pointing is pointing to window. So fun is written like thisfun.call(window), the output is 222
  • The function is called as a method on an object.acallsayMethod, sothisPoint isa, which is equivalent to a.say.call(a), the output is 111
  • B. Say (a.say) = 222; b. Say (a.say) = 222
  • B. say(a.sayMethod is directly copied tob.say, which is equivalent tob.say=function(){console.log(this.name)}, thenb.sayThe equivalent ofb.say.call(b), the output is 333

The this in the arrow function points to

  • The this in the arrow function is bound when the function is defined, not when the function is executed
  • In the arrow function, the this point is fixed, not because the arrow function has a mechanism to bind this, the actual reason is that the arrow function does not have its own this, so the inner this is the this of the outer code block. Because it does not have this, it cannot be used as a constructor

So let’s do two problems

The first question
   // This in arrow function
    var x = 11
    var obj = {
        x:22.say: () = >{
            console.log(this.x)
        }
    }
    obj.say() / / 11
Copy the code

Description: X in the arrow function. The arrow function say exists as a horizontal key:value with the x in obj. In other words, the object on which the arrow function say itself is located is obj. The parent execution context of obj is window, so this.x actually stands for window.x, so the output is 11

The second problem is
var address = {
        country:'China'.getCity:function(){
            var country = this.country
            var fn = () = > console.log(this.country + 'GZ')
            return fn()
        }
}
    address.getCity()
Copy the code

In this example, the arrow function itself is in the getCity method. The parent execution context of getCity is address, so this refers to address. Note that the arrow function’s this is not modified

var name = 'Cynthia'
var person = {
    name:'Aria'
}
var fn = () = >{
console.log(this.name)
}
fn.call(person) // Cynthia
Copy the code