JS Foo() 经典面试题

// a
function Foo () {
 getName = function () {
   console.log(1);
 }
 return this;
}
// b
Foo.getName = function () {
 console.log(2);
}
// c
Foo.prototype.getName = function () {
 console.log(3);
}
// d
var getName = function () {
 console.log(4);
}
// e
function getName () {
 console.log(5);
}

Foo.getName();           // 2
getName();               // 4
Foo().getName();         // 1
getName();               // 1 
new Foo.getName();       // 2
new Foo().getName();     // 3
new new Foo().getName(); // 3

解析:

  1. **Foo.getName(),**Foo为一个函数对象,对象都可以有属性,b 处定义Foo的getName属性为函数,输出2;
  2. **getName(),**这里看d、e处,d为函数表达式,e为函数声明,两者区别在于变量提升,函数声明的 5 会被后边函数表达式的 4 覆盖;
  3. **Foo().getName(),**这里要看a处,在Foo内部将全局的getName重新赋值为 console.log(1) 的函数,执行Foo()返回 this,这个this指向window,Foo().getName() 即为window.getName(),输出 1;
  4. **getName(),**上面3中,全局的getName已经被重新赋值,所以这里依然输出 1;
  5. **new Foo.getName(),**这里等价于 new (Foo.getName()),先执行 Foo.getName(),输出 2,然后new一个实例;
  6. **new Foo().getName(),**这里等价于 (new Foo()).getName(), 先new一个Foo的实例,再执行这个实例的getName方法,但是这个实例本身没有这个方法,所以去原型链__protot__上边找,实例.protot === Foo.prototype,所以输出 3;
  7. **new new Foo().getName(),**这里等价于new (new Foo().getName()),如上述6,先输出 3,然后new 一个 new Foo().getName() 的实例。

在这里插入图片描述
第一个因为Foo.a的第5行把原来的第2行覆盖了,所以输出3,
第二个输出this.a,就是2,
第三个因为又new了下Foo(),所以第2行的值又回去了,同时,因为又.a()方法,所以第6行触发条件是没有原型指向的a的时候才会触发的,对比上面出的那道题是不一样的,所以输出1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值