题目

题目1

  1. function Foo() {
  2. getName = function() {
  3. console.log(1);
  4. };
  5. return this;
  6. }
  7. Foo.getName = function() {
  8. console.log(2);
  9. };
  10. Foo.prototype.getName = function() {
  11. console.log(3);
  12. };
  13. var getName = function() {
  14. console.log(4);
  15. };
  16. function getName() {
  17. console.log(5);
  18. }
  19. //请写出以下输出结果:
  20. Foo.getName();
  21. getName();
  22. Foo().getName();
  23. getName();
  24. new Foo.getName();
  25. new Foo().getName();

  1. //-> 2 Foo 作为对象,优先读取读取它自身的 getName 方法,忽略它原型上的 getName 方法(Function.prototype.getName)
  2. //-> 4 这里涉及到变量提升的问题
  3. // 先执行 var getName
  4. // 再执行 function getName(){console.log(5)}
  5. // 然后执行 getName = function() {console.log(4)}
  6. //-> 1 Foo作为函数,因为在全局环境中调用,返回 this 为全局对象
  7. // 由于 Foo 函数中的 getName 没有携带操作符,所以提升为全局变量,所以会绑定到 this 上
  8. //-> 1 因为第三步 Foo 函数在执行时,把内部的 getName 注册在了全局,覆盖了全局原来的 getName
  9. //-> 2 Foo 作为对象,调用 Foo 对象上的 getName 方法作为构造函数
  10. //-> 3 Foo 作为构造函数,初始化 Foo 实例,调用 Foo 原型上的 getName 方法

题目2

  1. let a = {
  2. b: function() {
  3. console.log(this)
  4. },
  5. c: () => {
  6. console.log(this)
  7. }
  8. }
  9. a.b()
  10. a.c()
  11. let d = a.b
  12. let e = a.c
  13. d()
  14. e()

  1. // a: 普通函数的this是在调用的时候决定的
  2. // window:箭头函数的 this 初始化时就确定,看外层是否有构造函数,如果有,外层函数的 this 就是内部箭头函数的 this,如果没有,则 this 是 window。
  3. // window:普通函数,全局环境调用,指向 window
  4. // window:箭头函数的 this 初始化时就确定,看外层是否有构造函数,如果有,外层函数的 this 就是内部箭头函数的 this,如果没有,则 this 是 window。

题目3

  1. function Fun() {
  2. const fun = () => {
  3. console.log(this)
  4. }
  5. fun()
  6. }
  7. Fun()
  8. new Fun()

  1. // window:Fun 作为普通函数,箭头函数外层没有构造函数
  2. // Fun:Fun 作为构造函数,箭头函数外层有构造函数 Fun,箭头函数 this 指向 Fun

题目4

  1. class FunClass {
  2. static aFun = () => {console.log(this)}
  3. }
  4. const bFun = FunClass.aFun
  5. FunClass.aFun()
  6. bFun()

  1. // FunClass:外层构造函数为 FunClass,this 指向 FunClass
  2. // FunClass:声明时即确定 this 指向,所以依然指向 FunClass

题目5

  1. var name1 = 1;
  2. function test() {
  3. let name1 = 'kin';
  4. let a = {
  5. name1: 'jack',
  6. fn: () => {
  7. var name1 = 'black'
  8. console.log(this.name1)
  9. }
  10. }
  11. return a;
  12. }
  13. test().fn() // ?
  14. class Aclass{
  15. static name1 = 1
  16. static test = function() {
  17. let name1 = 'kin';
  18. let a = {
  19. name1: 'jack',
  20. fn: () => {
  21. var name1 = 'black'
  22. console.log(this)
  23. }
  24. }
  25. return a;
  26. }
  27. }
  28. Aclass.test().fn()

  1. // 1:test 作为普通函数,外层无构造函数 this 指向全局
  2. // class Aclass fn 为箭头函数,外层函数为 test,test 作为普通函数,所以 fn 外层的构造函数为 Aclass

题目6

  1. var point = {
  2. value: 0,
  3. move: function(value) {
  4. // 内部函数
  5. var fun = function(value) {
  6. this.value = value
  7. console.log(this)
  8. };
  9. fun(value);
  10. };
  11. };
  12. point.move(10);
  13. console.log(point.value) // 0
  14. console.log(value) // 10

  1. // Window:指向 window 对象, 函数内部执行,与对象调用执行有区别
  2. // 0
  3. // 10

题目7

  1. var a = 10;
  2. var foo = {
  3. a: 20,
  4. fn: (function(){
  5. console.log(this);
  6. console.log(this.a);
  7. })()
  8. }

  1. // window:window 对象,函数被内部执行,与对象调用执行有区别
  2. // 10

题目8

  1. var a = 10;
  2. var oTimer1 = setInterval(function(){
  3. var a = 20;
  4. consoel.log(this)
  5. console.log(this.a);
  6. clearInterval(oTimer1);
  7. },100);

  1. // window:window 对象,异步函数 this 指向全局
  2. // 10

题目9

  1. (function(){
  2. eval("console.log(this)");
  3. })();
  4. function Foo(){
  5. this.bar = function(){
  6. eval("console.log(this)");
  7. }
  8. }
  9. var foo = new Foo();
  10. foo.bar();

  1. // eval 中指向调用的上下文
  2. // window:上下文为 window
  3. // Foo:使用 new, Foo 作为构造函数,上下文为 Foo

题目10

  1. var a = 10;
  2. var foo = {
  3. a: 20,
  4. fn: function(){
  5. console.log(this.a);
  6. }
  7. };
  8. var bar ={
  9. a: 30
  10. }
  11. foo.fn.apply();
  12. foo.fn.apply(foo);
  13. foo.fn.apply(bar);

  1. // apply和call中的this指向参数中的对象
  2. // 10(若参数为空,默认指向全局对象)
  3. // 20
  4. // 30

参考

《前端工程师面试宝典|this指向》