• js中函数作用域,作用域链,变量提升


    先来分析几个容易出错的题目

    第一题:

            var foo = 1
            function bar(){
                if(!foo){
                    var foo = 10;
                }
                console.log(foo)
            }
            bar()

    这道题大家会误认为是1

    其实在内部函数执行时,无论这个判断是否成立,都会对声明变量进行提升,所以var foo = undefined,所以在内部判断,因为undefined是false,取反就是true,执行var foo = 10,所以:

    最后答案就是10

    第二题:

            var n = 0
            function a(){
                var n = 10
                function b(){
                    n++
                    console.log(n)
                }
                b()
                return b
            }
            var c = a()
            c()
            console.log(n)

    我直接叙述解题步骤了:

    先声明变量,函数声明提前,执行a()函数,在a函数里又声明了函数b,调用函数b并且将b返回,n++将函数a里的n的值变为11,打印n,所以第一个n是11,

    这时候将函数b返回,并且执行,因为这时还是在函数a内部执行,n已经是11,再n++,所以n = 12,

    最后一个是n是0,函数的私有作用域无法访问

    所以最终结果是11,12,0

    第三题:

            var a = 4
            function b(x,y,a){
                console.log(a)
                arguments[2] = 10
                console.log(a)
            }
            a = b(1,2,3)
            console.log(a)

    在js的非严格模式下:函数的实参集合与形参变量存在‘映射关系’,不管其中谁改变了,另外一个都会跟着改变

    在js的严格模式下:arguments实参集合和形参变量的映射关系被切断了,相互之间互不干扰

    如果没有返回值则是undefined

    所以结果是3,10,undefined

    就在刚刚我又看到了类似的题目,结果我做错了,真是伤脑筋(还没想起来为啥会是这样)...

    var name = "World";
    (function(){
    if(typeof name==="undefined"){
    var name = "Jack";
    console.log("Goodbye"+name);//GoodbyeJack
    }else{
    console.log("hello"+name)
    }
    })()

    为什么我会潜意识认为这个name找不到要去全局作用域去找啊,我下次一定要给自己提个醒,

    什么隐式变量啊,什么变量直接用啊,都要在前边先声明,先声明,先声明var name = undefined

    假如要是这个样子呢

    var name = "World";
    (function(){
    console.log(name)
    name = "li"
    console.log(name)
    })()
    console.log(name)

    要是按照正规思路这个答案应该是 undefined li li吧,我先去测试下

    卧槽,是world,li,li,后面我可以理解,第一个理解不了,然后我又这样测试了一下

    var name = "World";
    (function(){
    console.log(name)
    if(typeof name==="undefined"){
    var name = "Jack";
    console.log("Goodbye"+name);//GoodbyeJack
    }else{
    console.log("hello"+name)
    }
    })()

    这个答案是undefined  GoodbyeJack??

    后来我看到了底下有个var name = 'Jack',

    这里是要声明提前的。草,我原来题目都没读完,就下结论了,真纸张,心累

    加油了

  • 相关阅读:
    二叉树--转换二叉树(leetcode 108,leetcode 109)
    二叉树--层序遍历(leetcode 102
    二叉树--对称二叉树(leetcode 101
    数据库事务隔离
    二叉树--后序遍历的递归和非递归(leetcode 145
    二叉树--中序遍历的递归和非递归(leetcode 94
    二叉树--先序遍历的递归和非递归(leetcode 144
    链表--排序链表(leetcode 148
    接口的调用
    查锁表以及杀进程
  • 原文地址:https://www.cnblogs.com/xufeng1994/p/10430274.html
Copyright © 2020-2023  润新知