原型链经典面试题getName()

这篇文章为大家理一下原型链的经典面试题getName()

题目

先放上完整的题目

   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().__proto__.getName();
        new Foo.getName();
        new new Foo().getName();

答案

这里由于某些小伙伴基础较好这里先放上答案,需要在看后面的解析啦
在这里插入图片描述

分析

首先先整个题目

创建GO
先提升 var声明的 getName 到最前面并且赋值为underfined ,然后提升 function Foo()赋值函数体,将 function getName() {
console.log(5); }覆盖上面声明的getName,然后从上看到下,我们发现有getName = function() { console.log(4); }赋值语句,这时我们的getName重新赋值
此时,我们的题目变成了

  getName = function() {
            console.log(4);

        }

        function Foo() {
            getName = function() {
                console.log(1);

            }
            return this;
        }
        Foo.getName = function() {
            console.log(2);

        };
        Foo.prototype.getName = function() {
            console.log(3);

        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

第一问 Foo.getName(); //2

这里相当于调用了Foo这个构造函数里面的getName的静态方法,所以这里输出2

第二问 getName(); //4

这里显然我们找的是全局的getName方法,从上面的分析中,我们可以看出全局的getName执行输出4,所以这里打印4

第三问 Foo().getName(); //1

这一题分为两个步骤

  • 首先我们从左到右执行Foo()执行时,由于foo内部的getName不是var声明的,也没有形参来声明他,所以这里将全局的getName = function() { console.log(1); },而且这里返回了this指向window,所以这里下面相当于window.getName()
  • 由上一步,我们可以得知全局中的getName已经改变,并且Foo执行指向了全局,所以这里我们在全局中找到getName,指向1,所以这里输出1

第四问 getName();//1

这里基于第三问,第三问已经将全局的getName改变,所以这里输出1,不在多说

第五问 new Foo().getName();//3

这题 从左往右 先new了一个Foo(),当new的时候this指向我们new出来的新对象,而且由于Foo()本身并没有带有this.getName的方法,于是向原型链上寻找,因此找到了 Foo.prototype.getName = function() {console.log(3); },所以这里输出3

第六问 new Foo().proto.getName();//3

这一题我们可以看这个图
在这里插入图片描述

上面相当于Foo.prototype.getName();所以这里直接拿到3;

第七问 new Foo.getName(); //2

这里去头去尾,先看中间,拿到的是 Foo.getName = function() { console.log(2); };,所以这里打印2,我们这里可以看控制台打印
在这里插入图片描述
一个普通函数new出来打印结果还是原本的输出,所以这里上面打印结果为2

最后一问 new new Foo().getName();//3

从内向外,去头去尾,我们 发现这一题等价于new Foo().getName,等同于第五问,在应用上一题的方法,这里new出来结果还是为3

总结

在做原型链的题目时,可以画一个简单的原型图,再涉及到this时,牢记new指向new出来的新对象,

猜你喜欢

转载自blog.csdn.net/L_Z_jay/article/details/111401329