js的函数调用和声明提升的经典面试题解析

此题涉及的知识点:声明提升和提升优先级、构造函数返回值问题、js运算符优先级、实例化对象的属性访问优先级、逻辑运算符运算
题目:

// 方式1:创建了一个有返回值的构造函数,在里面定义了全部变量getName指向一个匿名函数(小心闭包)
    function Foo() {
        getName = function () {
            console.log(1);
        }
        return this;
    }
    // 方式2:构造函数的一个属性getName指向一个匿名函数
    Foo.getName = function () {
        console.log(2);
    }
    // 方式3:构造函数的原型上有个getName方法
    Foo.prototype.getName = function () {
        console.log('baidu' && 'google');
    }
    // 方式4:定义一个变量getName指向一个匿名函数
    var getName = function () {
        console.log(4);
    }
    // 方式5:声明一个叫getName的具名函数
    function getName() {
        console.log(5);
    }

    // 输出结果
    Foo.getName();
    getName();
    Foo().getName();
    getName(); 
    new Foo.getName(); 
    new Foo().getName();
    new new Foo().getName();
    // 2 4 1 1 2 "google" "google"

第1问 - - Foo.getName()
即运行方式2,故得结果2

第2问 - - getName()
直接调用getName函数,关乎方式4和5
由于函数声明提升,在预编译时方式5会提升到上面去,同时方式4是变量的赋值, 所以, 该变量会覆盖函数getName,方式4会覆盖方式5,故得结果4

第3问 - - Foo().getName()
先执行Foo函数,然后调用Foo函数的返回值对象的getName方法
Foo函数中定义了全局变量getName指向一个匿名函数,即改变了window上的getName值;Foo()返回的this指向window对象
即window.getName(),故得结果1

第4问 - - getName()
直接调用getName函数,即window.getName(),亦得结果1

第5问 - - new Foo.getName()
根据js运算符优先级:new ( Foo.getName )()
将Foo.getName作为构造函数,然后执行它,故得结果2

第6问 - - new Foo().getName()
根据js运算符优先级:( new Foo() ).getName()
知识点1:传统意义上,构造函数是没有返回值的,执行后结果为创建出来的实例对象
    js中构造函数既可以有返回值也可无返回值
     1. 无返回值时,执行后结果为实例对象
     2. 有返回值时,若返回值是基本类型,则相当无返回值,执行结果为实例对象
            若返回值是引用类型,执行结果为该引用数据
本问中Foo函数执行后返回this,而this在构造函数中指向实例对象,层层往上找getName方法
属性访问优先级:对象自身 > 构造函数 > 原型 > 父级,故运行方式3
知识点2:逻辑运算符运算 - - 对于"&&“来说,如果前者为真,那么就执行后者,否则只执行前者;
               对于”||“来说,如果前者为真,只执行前者,后者不必执行,否则还得执行后者。因此结果为"google”。

第7问 - - new new Foo().getName()
根据js运算符优先级:new ( ( new Foo() ).getName )()
先执行new Foo(),再得到new Foo().getName作为构造函数,然后执行它,得到结果"google"

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值