一道经典的函数面试题

一道经典的函数面试题

先来看题目:

function Foo() {
    getName = function() {
        console.log(1)
    }
    console.log(this)
    return this;
}
Foo.getName = function() {
    console.log(2)
    // console.log(this)
}
Foo.prototype.getName = function() {
    console.log(3)
}
var getName = function() {
    console.log(4)
}
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

这道题综合了函数的执行、构造函数、原型和原型链、new、变量提升、运算符优先级等知识点,所以答案看上去令人疑惑不解。

下面就用图解的方式向大家解释这道题目:

在这里插入图片描述

  1. 首先就是变量提升,构造函数Foo和函数声明getName都会变量提升,GO中的getName此时打印5
  2. 全局执行,在构造函数Foo(自身作为对象,可以存储属性)上添加了getName2的静态属性,在其原型上添加了getName2的属性,供其实例查找,全局GOgetName5被函数表达式重新覆盖成getName4
  3. Foo.getName(); 执行,是构造函数静态属性上的getName2,所以打印结果为2
  4. getName()执行,全局的getName4执行,所以打印结果为4
  5. Foo().getName()执行,Foo执行返回thiswindow, Foo执行时,当前上下文中并没有getName,向上级上下文中查找,最终找到全局的getName4,并将其修改为getName1, 返回结果为window,所以调用window.getName,也就是全局的getName1,打印1
  6. 全局的getName1执行,打印1
  7. new Foo.getName(); 执行,点运算符优先级比new高,所以先找到Foo身上的静态属性,也就是普通函数getName2, new一个普通函数执行没有意义,只会打印2
  8. new Foo().getName(); 执行,()优先级比new高,先执行new Foo(),创建一个foo实例,找到实例上的getName,也就是原型链上的getName3,最终打印3
  9. new new Foo().getName();执行,同样的,先执行new Foo(),然后问题演变为new foo.getName(),也就是new getName3, new一个普通函数执行没有意义,只会打印3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值