一道面试题引发的惨案

先把面试题贴出来:
//请回答下面函数依次执行出什么;
function Foo () {
    bar = function () {
        console.log(1)
    }
    return this;
}
Foo.bar = function () {
    console.log(2)
}
Foo.prototype.bar = function () {
    console.log(3)
}
var bar = function () {
    console.log(4)
}
function bar () {
    console.log(5)
}
Foo.bar();//2
bar();//4
Foo().bar();//1
bar();//1
new Foo.bar();//3
new Foo().bar();//3
new new Foo().bar();//3
刚看到这个问题,着实有点晕;不过细细分析下来,还是有点门道的。

首先我们来看一下这道题考察的是什么
  • js的三种调用模式
  • 构造函数 原型
这里涉及到js的三种调用模式;1.方法调用 2.函数调用 3.构造函数调用
接下来,我们一一分析问题;
1. Foo.bar();//2

由于浏览器在执行js时是同步去执行的,这里可以将Foo.bar看做 a ;这时就相当于:

a = function () {
    console.log(2)
}//由于不是严格模式,这里省略了声明函数的关键字 var;
a();//2
2. bar();// 4

这个执行相应的函数体:

var bar = function () {
    console.log(4)
}
3. Foo().bar();// 1

Foo() 会去执行function Foo(){};同时会返回出一个全局的this;
Foo().bar() 执行函数Foo体内的bar函数

4. bar();// 1

第一个问题bar()执行的是函数:

var bar = function () {
    console.log(4);
}//打印出来的是4

而在执行Foo().bar()时,Foo()会返回出来全局this,this内部的bar函数为:

bar = function () {
    console.log(1)
}

此时会覆盖其余的bar函数

5. new Foo.bar();// 2

构造函数调用模式;

Foo.bar = function () {
    console.log(2)
}
var foo =new Foo.bar();  //把Foo.bar看做为整体如newFoo(){},newFoo就变成了构造函数
var foo = new newFoo();// foo => 2
6. new Foo().bar();// 3
使用new关键字,便会创建一个对象, 根据prototype属性创建原型链,并以该对象为this执行指定的(构造)函数。

我们把需要的函数拿出来,看起来会爽的多;

function Foo () {
    bar = function () {
        console.log(1)
    }
    return this;
}
Foo.prototype.bar = function () {
    console.log(3)
}
var foo = new Foo();
foo.bar() //3

看到这里是不是就很清晰了;简单的构造函数加原型的继承;

7. new new Foo().bar();// 3

结合上面两问;该问题可以这样写;

new new Foo().bar() => new foo.bar() =>new newFoo()//回到了用构造函数调用的模式;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值