面试题

变量与函数提升问题例题

2024-01-17  本文已影响0人  你这个锤子

变量提升

在 JavaScript 中,变量的声明会被提升到其所在作用域的顶部。但是,只有声明会被提升,赋值和其他操作仍然在原地执行。这意味着,如果你在代码的后面部分引用一个变量,JavaScript 会把它当作已经在顶部声明过的变量来处理。

函数提升

在 JavaScript 中,函数声明也会被提升。这意味着无论函数在哪里声明,它都好像是在其所在作用域的顶部声明的。与变量提升不同,函数提升包括函数声明和函数表达式。

总结

函数提升优先级高于变量提升,且不会被同名变量声明时覆盖,但是会被同名变量赋值后覆盖

例题

1, 考点:深拷贝与浅拷贝,比较对象(转成字符串或者递归比较)
    var obj1={};
    var num=2;
    var obj2={b:obj1,d:num};
    var obj3={x:5};
    obj1.x=5;
    num=7;
    alert(obj1);  // [object Object], --{x:5}
    alert(obj2);  // [object Object], -- {b: {x:5},d:2};
    alert(obj1==obj3); false
    alert(obj1===obj3); false
    // JSON.stringify(obj1) = JSON.stringify(obj3)
2,考点:变量提升和函数提升问题
alert(a);  // function a(){alert(4);};
var a=1;
alert(a); //1
function a(){alert(a);};
var a=2;
alert(a); //2
var a=3;
alert(a);//3
function a(){alert(4);};
alert(a); // 3
3,声明函数
function fn(bar){
    console.log(bar);
    function bar(){ //相同名称的函数
        return '函数1';
    }
    console.log(bar);
    var bar = 1;
    function bar(){ //相同名称的函数
        return '函数2';
    }
}
fn(5)

// 实际是这样
function fn(bar){
    var bar // 变量提升 , 传参赋值5
    function bar(){  // 函数变量提升,其实也就是变量提升,把bar = 5 覆盖
        return '函数2';
    }
    console.log(bar); // 从上往下执行到这句 直接把bar函数2整个代码打印出来
    console.log(bar); // 从上往下执行到这句 直接把bar函数2整个代码打印出来
    var bar = 1;
}
4,函数声明(式)和函数表达式 区别
function fn(bar){
    var bar = 1;
    var bar = function(){
        return '函数1';
    }
    console.log(bar);
    function bar(){
        return '函数2';
    }
}
fn(5);

// 实际上
function fn(bar){
    var bar // 变量提升 传入参数赋值 bar=5
    function bar(){  // 函数提升 bar = 这个函数
        return '函数2';
    }
    var bar = 1;  // 从上到下执行到这里 bar被重新声明并赋值 bar = 1
    var bar = function(){  // 注意注意! 这里也是变量的赋值声明, bar = 这个函数
        return '函数1';
    }
    console.log(bar);  //  从上到下执行到这里,直接把bar函数1整个代码打印出来
}
5, 考点:原型和原型链,函数提升问题
function Foo() {
    getName = function() {
        console.log(1)
    }
    return this;
}
Foo.getName = function() {
    console.log(2)
}
Foo.prototype.getName = function() {
    console.log(3)
}
var getName = function() {
    console.log(4)
}
function getName() {
    console.log(5)
}
Foo.getName()
getName()
Foo().getName()
getName()
new Foo.getName()
new Foo().getName()
new new Foo().getName()
// 问:执行结果的顺序是怎么样的?

****************步骤解答
function Foo() { // 给window对象绑定一个函数Foo
    getName = function() { 
        console.log(1)
    }
    return this;
}
Foo.getName = function() { // 给函数Foo添加一个属性getName,是个函数
    console.log(2)
}
Foo.prototype.getName = function() {  //给函数Foo的原型添加一个属性getName,是个函数
    console.log(3)
}
var getName = function() { // 给window对象绑定一个对象,是个函数
    console.log(4)
}
function getName() { // 一个有名函数getName,默认提升,然后又被var getName声明覆盖了
    console.log(5)
}

Foo.getName();// 执行Foo上的getName属性 -------2
getName();//执行window对象上的getName --------4
Foo().getName(); //先执行了Foo,把window对象的getName修改了,然后返回this,指向window,也就是window.getName() -------1
getName(); //--------1
new Foo.getName(); //.点的优先级比new运算符高,new (Foo.getName)() --------2
new Foo().getName(); //()执行优先级比.高,所以(new Foo()).getName(),this指向构造函数的实例,所以是执行原型上的getName -------3
new new Foo().getName(); //同理,new [【new Foo()】.getName()] ----------3
6,考点:函数提升问题
var foo = function () {
    console.log("foo1")
}
foo()
var foo = function () {
    console.log("foo2")
}
foo()
function foo() {
    console.log("foo1")
}
foo()
function foo() {
    console.log("foo2")
}
foo()
打印结果 //foo1,foo2,foo2,foo2
7,考点:变量与函数提升
function fn() {
    var b = 1;
    function a() {
        console.log('1', b);
        var b = 2;
        console.log('2', b);
    }
    a();
    console.log('3', b);
}
fn();
// 这题解析一下吧
function fn() {
     var b // 不说了吧
     function a() {
        var b // 在这个函数作用域内变量提升 undefined
        console.log('1', b); // 打印 1 undefined
        var b = 2; // 声明赋值 b = 2
        console.log('2', b); // 打印 2 2
    }
    var b = 1; 
    a(); // 执行a函数,去看看a函数有啥
    console.log('3', b); // 这个b不是函数a内的哦,打印 3 1
}

参考:变量与函数提升问题详解

上一篇下一篇

猜你喜欢

热点阅读