JS this 4(完) 学习 + 面试题

84 阅读4分钟

面试题 1

var name = 'window'

var person = {
    name: 'person',
    sayName: function () {
        console.log(this.name)
    }
}

function sayName() {
    var sss = person.sayName;
    sss();  //window
    person.sayName(); //person
    (person.sayName)(); //person
    (b = person.sayName)() //window 赋值表达式
}

sayName()

面试题 2

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() //1
person1.foo1.call(person2) //2

person1.foo2() //3
person1.foo2.call(person2) //4

person1.foo3()() //5
person1.foo3.call(person2)()//6
person1.foo3().call(person2)//7

person1.foo4()()//8
person1.foo4.call(person2)()//9
person1.foo4().call(person2)//10
解答

1: person1隐式绑定//person1

2: person2 同时有显示绑定(foo1.call(person2))和隐式绑定(person1.foo1),显示绑定优先隐式绑定//person2

3:箭头函数向上层找this(var person1 = {}, 大括号中不是作用域),上层是全局,找到了 name = 'window'//window

4:当call绑定的是箭头函数时没有用,当作没有。指向全局window//window

5:独立函数调用,foo3返回值是个函数,且没有指定绑定,默认指向全局//window

6:call的作用是使foo3的this指向person2,和return的函数无关,默认指向全局//window

7:因为表达式从左向右,可以看成:function(){}.call(person2),在return后的新函数绑定call//person2

8:箭头函数不绑定this,找上层作用域,是foo4的this的指向(这时foo4的this指向就是箭头函数的,且也会跟着this的改变),因为有person1.foo4显示绑定将foo4的this指向了person1//person1

9:foo4同时有隐式和显示绑定,显示绑定优先(显示绑定对箭头函数没有作用,但是对foo4有作用),foo4的this指向person2,箭头函数向上层找this,指向person2//person2

10:相当于() => {console.log(this.name)}.call(person2),call绑定对箭头函数不起作用,箭头函数找上层this的指向,foo4的this,又因为foo4的this显示的绑定了person1,所有箭头函数this指向person1//person1

面试题 3

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
person2.foo1.call(person2)//person2

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

person1.foo3()()//window
person1.foo3.call(person2)()//window
person1.foo3().call(person2)//person2

person1.foo4()()//person1
person1.foo4.call(person2)()//person2
person1.foo4().call(person2)//person1
解答

1. 隐式调用,this指向person1

2. 隐式和显示共存,显示大于隐式,this指向person2

3. 箭头函数的this指向上层作用域,上层是个函数作用域(对象没有作用域,函数有),且参数为person1

4. call对箭头函数没有作用(bind,和apply也没有用),找上层作用域,且参数为person1

5. 独立函数调用为window

**6. call使foo3显示绑定person2,但没有绑定return的新函数,所以为window

7. 可以看成(次函数是return返回的):function(){consloe.log(this.name)}.call(person2)。将return的新函数显示的绑定person2,this指向person2

8. retrun出的箭头函数,向上层找作用域,为person1

9. foo4同时有显示绑定和隐式绑定,所以foo4的this显示绑定person2,return新的箭头函数向上层找this,上层为foo4,所以foo4的this指向为箭头函数的指向为person2

10.可以看作为:() => {console.log(this.name)}.call(person2),但是call显示绑定对箭头函数没有用,找上层this的指向,foo4的指向为person1

面试题 4

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()()//window
person1.obj.foo1.call(person2)()//window
person1.obj.foo1().call(person2)//person1

person1.obj.foo2()()//obj
person1.obj.foo2.call(person2)()//person2
person1.obj.foo2().call(person2)//obj
解答

1. return的新函数,没有绑定没有任何this,默认指向window

2. foo1同时有显示和隐式绑定,显示绑定优先,但对return的新函数没有任何绑定,默认this到全局

3. 可以看作:function(){consloe.log(this.name)}.call(persons),return后新函数通过call显示绑定到person2

4. foo2的return新的箭头函数,箭头函数找上层this,foo2显示绑定obj,箭头函数this也是obj

5. foo2同时有显示和隐式绑定,显示优先绑定到person2,return的箭头函数找上层作用域,箭头函数和foo2指向person2

6. 可以看作:() => {conslog.log(this.name)}.call(person2),call对箭头函数没有用,箭头函数找上层this