记两道js题的理解—JS匿名自执行函数(IIFE)

今天看到两道js题,查了资料和自己的理解写下个人的见解

var name = 'World!';
(function () {
   if (typeof name === 'undefined') {
       var name = 'Jack';
       console.log('Goodbye ' + name);
   } else {
       console.log('Hello ' + name);
   }
})(); // Goodbye Jack
    var foo = 1;
    (function foo(){
    foo = 100;
    console.log(foo);
    }())
    console.log(foo);

    // ƒ foo(){
    //     foo = 100;
    //     console.log(foo);
    // }
    //  1

 

在解决问题前先理解一下函数的命名方式:函数声明式、函数表达式

函数声明式

语法形式:

function name(){
    ......
}

函数声明式会使得函数声明提升,意思是在执行代码之前会先读取函数声明,在函数声明前调用也不会出错

sayName(); // my name is bonnie 
function sayName(){
    console.log('my name is bonnie');
}

函数表达式

语法形式:

var fun = function(){
    .......
}

//IIFE立即调用函数表达式
(function(){
    //变量和function的声明作用域只能在这个匿名闭包里
    ......
}())
//同下
(function(){
    ......
})()

函数表达式不会函数声明提升,只有执行到它时才会执行。函数表达式与其他表达式一样,在使用前必须先赋值。否则报错

sayName(); // Uncaught TypeError: sayName is not a function
var sayName = function(){
    console.log('my name is bonnie');
}

函数表达式的函数名不可修改,如修改则在非严格模式下不起效,在严格模式下报错:Uncaught TypeError: Assignment to constant variable.

(function sayHi(){
    sayHi = 'hello';
})(); // Uncaught TypeError: Assignment to constant variable.

接下来分析问题:

var name = 'World!'; //外部声明变量name
//IIFE立即调用函数表达式
(function () {
   if (typeof name === 'undefined') {
       var name = 'Jack'; // var声明变量name,变量提升到IIFE作用域前面
       console.log('Goodbye ' + name);
   } else {
       console.log('Hello ' + name);
   }
})(); 

//等同于
(function () {
   var name;
   if (typeof name === 'undefined') { //因为变量name虽已声明但还未被初始化,所以为'undefined'
       name = 'Jack';
       console.log('Goodbye ' + name);
   } else {
       console.log('Hello ' + name);
   }
})();

这个问题所在是变量提升的原因,如果把IIFE里面的name声明改为let则输出‘Hello World!’

var name = 'World!';
(function () {
   if (typeof name === 'undefined') {
        let name = 'Jack';
        console.log('Goodbye ' + name);
   } else {
       console.log('Hello ' + name);
   }
})(); // Hello World!

另一道题的分析

var foo = 1;
(function foo(){
    foo = 100; // 修改函数表达式的函数名不符合规范,不报错也不起效
    console.log(foo); // 输出函数本身
}())
console.log(foo); //由于IIFE声明的函数或者变量只在那个作用域,所以这里的foo是外部作用域的foo,输出1

总结

以上是个人拙见,如有问题请各位大佬提点

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值