关于this的面试题和详解

183 阅读2分钟

函数执行时才会产生this指向,函数不执行this没有意义

this指向的四种规则:

  1. 默认绑定
  2. 隐式绑定【隐式丢失】
  3. 显示绑定
  4. new 对象绑定

例题一:

var obj = {
    a: 10,
    b: this.a + 10,   // this的默认绑定规则  指向window 
    fn: function() {
        console.log('fn', this)  //  this指向obj
        function test() {
            console.log('test', this);  // this指向window
        }
        test();
        return this.a    // this的隐式绑定规则  指向obj[谁调用指向谁]
    }
}
console.log(obj.b);  // NaN
console.log(obj.fn());  // 10
console.log(obj.fn);  // funtion函数

例题二:

var a = 20;
var obj = {
    a: 10,
    get: function() {
        console.log(this);
        return this.a;
    }
}
// this的隐式绑定规则  指向obj[谁调用指向谁]
console.log(obj.get());  // 10
// this的隐式丢失 指向window
var test = obj.get;
console.log(test()); // 20
this.a = 50;
console.log(a); // 50

例题三

var a = 5;
function fn1() {
    var a = 10;
    console.log(a);   // 10
    console.log(this.a);  // 5, this 指向 window
}
function fn2(fn) {
    var a = 20;
    fn();
}
var obj = {
    a: 8,
    get: fn1,
}
fn2(obj.get);

例题四

function fn() {
    'use strict'  // 严格模式下,函数内this指向undefined
    var a = 1;
    var obj = {
        a: 10,
        c: this.a + 20,
    }
    return obj.c;
}
console.log(fn());  // 报错 Uncaught TypeError
var a = 5;
console.log(this.a);  // 5 严格模式下,全局作用域this = window
console.log(fn());

例题五

function Person(name, age) {
    this.name = name;
    this.age = age;
    console.log(this)  // new 对象绑定,this指向Person
}
Person.prototype.getName = function() {
    console.log(this); // this指向Person
}
var p1 = new Person('Melody', 18)
p1.getname();

例题六

var obj = {
    foo: "test",
    fn: function(){
        var mine = this;
        console.log(this.foo);       //test
        console.log(mine.foo);       //test
        (function(){
            console.log(this);    // this指向window
            console.log(mine.foo);    //test
        })();
        (() => {
            console.log(this);  // this指向obj
        })();
    } 
};
obj.fn();

例题七

function foo(){
    console.log(this.a);
}
var a = 2;
var o = {
    a:3, 
    foo: foo
};
var p = { a:4 };
o.foo();  // 3  this 指向 o
(p.foo = o.foo)();  // 2 this 指向window
            
p.foo = o.foo;
p.foo();  // 4  this指向p

例题八

function foo() {
    console.log(this.a);
}
var obj1 = {
    a: 3,
    foo: foo
};    
var obj2 = {
    a: 5,
    foo: foo
};
obj1.foo();     //3
obj2.foo();     //5
// this的显示绑定规则 
obj1.foo.call(obj2);    //5
obj2.foo.call(obj1);    //3

例题九

function test(arg) {
    this.x = arg;
    return this;
} 
            
var x = test(5);     //此时 x = window, y = undefined

//此时 x = 6,  y = window , 后面申请的x会覆盖掉第一次在this.x 生成的window.x
var y = test(6);

console.log(x.x);     //undefined,   实际上是6.x  是undefined
console.log(y.x);     //6     实际上是window.x 也就是6

例题十

var obj = {
    data: [1],
    data2: [5],
    fn: function () {
        console.log("--test--");
        console.log(this);   // this指向obj
        return this.data.map(function (item) {
            console.log(this);     // this指向window
            return item * 2;
        }); 
    },
    fn2: function () {
        console.log("---test2---");
        console.log(this);   // this指向obj
        return this.data2.map(item=>{
            // this指向obj,指向箭头函数定义时所处的对象,
            // 而不是箭头函数使用时所在的对象,默认使用父级的this
            console.log(this);            return item * 2; 
        });
    }
};  
obj.fn();
obj.fn2();