题目
题目1
题
function Foo() { getName = function() { console.log(1); }; return this;}Foo.getName = function() { console.log(2);};Foo.prototype.getName = function() { console.log(3);};var getName = function() { console.log(4);};function getName() { console.log(5);}//请写出以下输出结果:Foo.getName(); getName(); Foo().getName(); getName(); new Foo.getName(); new Foo().getName();
解
//-> 2 Foo 作为对象,优先读取读取它自身的 getName 方法,忽略它原型上的 getName 方法(Function.prototype.getName)//-> 4 这里涉及到变量提升的问题// 先执行 var getName // 再执行 function getName(){console.log(5)} // 然后执行 getName = function() {console.log(4)}//-> 1 Foo作为函数,因为在全局环境中调用,返回 this 为全局对象// 由于 Foo 函数中的 getName 没有携带操作符,所以提升为全局变量,所以会绑定到 this 上//-> 1 因为第三步 Foo 函数在执行时,把内部的 getName 注册在了全局,覆盖了全局原来的 getName//-> 2 Foo 作为对象,调用 Foo 对象上的 getName 方法作为构造函数//-> 3 Foo 作为构造函数,初始化 Foo 实例,调用 Foo 原型上的 getName 方法
题目2
题
let a = { b: function() { console.log(this) }, c: () => { console.log(this) }}a.b() a.c() let d = a.blet e = a.cd()e()
解
// a: 普通函数的this是在调用的时候决定的// window:箭头函数的 this 初始化时就确定,看外层是否有构造函数,如果有,外层函数的 this 就是内部箭头函数的 this,如果没有,则 this 是 window。// window:普通函数,全局环境调用,指向 window// window:箭头函数的 this 初始化时就确定,看外层是否有构造函数,如果有,外层函数的 this 就是内部箭头函数的 this,如果没有,则 this 是 window。
题目3
题
function Fun() { const fun = () => { console.log(this) } fun()}Fun()new Fun()
解
// window:Fun 作为普通函数,箭头函数外层没有构造函数// Fun:Fun 作为构造函数,箭头函数外层有构造函数 Fun,箭头函数 this 指向 Fun
题目4
题
class FunClass { static aFun = () => {console.log(this)}}const bFun = FunClass.aFunFunClass.aFun()bFun()
解
// FunClass:外层构造函数为 FunClass,this 指向 FunClass// FunClass:声明时即确定 this 指向,所以依然指向 FunClass
题目5
题
var name1 = 1;function test() { let name1 = 'kin'; let a = { name1: 'jack', fn: () => { var name1 = 'black' console.log(this.name1) } } return a;}test().fn() // ?class Aclass{ static name1 = 1 static test = function() { let name1 = 'kin'; let a = { name1: 'jack', fn: () => { var name1 = 'black' console.log(this) } } return a; }}Aclass.test().fn()
解
// 1:test 作为普通函数,外层无构造函数 this 指向全局// class Aclass fn 为箭头函数,外层函数为 test,test 作为普通函数,所以 fn 外层的构造函数为 Aclass
题目6
题
var point = { value: 0, move: function(value) { // 内部函数 var fun = function(value) { this.value = value console.log(this) }; fun(value); }; }; point.move(10); console.log(point.value) // 0console.log(value) // 10
解
// Window:指向 window 对象, 函数内部执行,与对象调用执行有区别// 0// 10
题目7
题
var a = 10;var foo = { a: 20, fn: (function(){ console.log(this); console.log(this.a); })()}
解
// window:window 对象,函数被内部执行,与对象调用执行有区别// 10
题目8
题
var a = 10;var oTimer1 = setInterval(function(){ var a = 20; consoel.log(this) console.log(this.a); clearInterval(oTimer1);},100);
解
// window:window 对象,异步函数 this 指向全局// 10
题目9
题
(function(){ eval("console.log(this)");})();function Foo(){ this.bar = function(){ eval("console.log(this)"); }}var foo = new Foo();foo.bar();
解
// eval 中指向调用的上下文// window:上下文为 window// Foo:使用 new, Foo 作为构造函数,上下文为 Foo
题目10
题
var a = 10;var foo = { a: 20, fn: function(){ console.log(this.a); }};var bar ={ a: 30}foo.fn.apply();foo.fn.apply(foo);foo.fn.apply(bar);
解
// apply和call中的this指向参数中的对象// 10(若参数为空,默认指向全局对象)// 20// 30
参考
《前端工程师面试宝典|this指向》