经典的JavaScript笔试题

本文通过具体示例解析了JavaScript中的作用域问题,包括函数声明与表达式的区别、变量提升机制以及不同方式调用函数时的this指向。有助于理解JavaScript执行机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

function Foo() {
    getName = function () { alert (1); };
     return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
        
 //请写出以下输出结果:
Foo.getName();  // 2
getName();  // 4
Foo().getName();  // 1
getName();  // 1
new Foo.getName();  // 2
new Foo().getName();  // 3
new new Foo().getName();  // 3

JavaScript 解释器中存在一种变量声明被提升的机制,也就是说函数声明会被提升到作用域的最前面,即使写代码的时候是写在最后面,也还是会被提升至最前面。而用函数表达式创建的函数是在运行时进行赋值,且要等到表达式赋值完成后才能调用。

1、Foo.getName自然是访问Foo函数上存储的静态属性。
2、函数表达式覆盖函数声明。
3、先执行了Foo函数,然后调用Foo函数的返回值对象的getName属性函数。Foo函数的第一句getName = function () { alert (1); };是一句函数赋值语句,注意它没有var声明,所以先向当前Foo函数作用域内寻找getName变量,没有。再向当前函数作用域上层,即外层作用域内寻找是否含有getName变量,找到了,也就是第二问中的alert(4)函数,将此变量的值赋值为function(){alert(1)}。
此处实际上是将外层作用域内的getName函数修改了。
之后Foo函数的返回值是this,此处this指向window对象。
4、直接调用getName函数,相当于window.getName(),因为这个变量已经被Foo函数执行时修改了,所以结果与第三问相同,为1,也就是说Foo执行后把全局的getName函数给重写了一次,所以结果就是Foo()执行重写的那个getName函数。
5、new (Foo.getName)()
6、(new Foo()).getName()
7、new ((new Foo()).getName)();

延伸:

function Foo() {
    this.getName = function() {
        console.log(3);
        return {
          getName: getName//这个就是第六问中涉及的构造函数的返回值问题
        }
    };//这个就是第六问中涉及到的,JS构造函数公有方法和原型链方法的优先级
    getName = function() {
        console.log(1);
    };
    return this
}
Foo.getName = function() {
    console.log(2);
};
Foo.prototype.getName = function() {
    console.log(6);
};
var getName = function() {
    console.log(4);
};

function getName() {
    console.log(5);
} //答案:
Foo.getName(); //2
getName(); //4
console.log(Foo())
Foo().getName(); //1
getName(); //1
new Foo.getName(); //2
new Foo().getName(); //3
                //多了一问
new Foo().getName().getName(); //3 1
new new Foo().getName(); //3

转载自:https://www.jianshu.com/p/e833e554bcf5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值