zoukankan      html  css  js  c++  java
  • JS作用域和闭包核心面试题分析

    作用域和闭包-执行上下文:

    变量提升(写代码时千万不要先使用再定义)

        <script>
            console.log(a);//undefined
            var a=10;
    
            fn('cyy',18);
            function fn(name,age){
                age=20;
                console.log(name,age);//cyy 20
                var age;
            }
        </script>

    函数声明存在提升,函数表达式不存在提升

        <script>
            fn1();//函数声明  不会报错
            function fn1(){}
    
            fn2();//函数表达式  报错
            var fn2=function(){}
        </script>
        <script>
            fn('cyy');
            function fn(name){
                console.log(this);
                console.log(arguments);
                console.log(name);
            }
        </script>

    作用域和闭包-this:

    this要在执行时才能确认值,定义时无法确认

        <script>
            var a={
                name:'cyy',
                fn(){
                    console.log(this.name);
                }
            }
            a.fn();//this===a
            a.fn.call({name:'cyy2'});//this==={name:'cyy2'}
            var fn1=a.fn;
            fn1();//this===window
        </script>

    this:

    作为构造函数执行

    作为对象属性执行

    作为普通函数执行

    call  apply  bind

        <script>
            //构造函数
            function Foo(name){
                this.name=name;
            }
            var f=new Foo('cyy');
    
            //作为一个对象的属性
            var obj={
                name:'cyy',
                fn(){
                    console.log(this.name);
                }
            }
            obj.fn();
    
            //普通函数的this
            function fn(){
                console.log(this);
            }
            fn();//this===window
    
            //call  apply  bind
            function fn1(name,age){
                console.log(name);
                console.log(this);
            }
            fn1.call({x:10},'cyy2',18);
            fn1.apply({x:20},['cyy3',19]);
    
            var fn2=function(name,age){
                console.log(name);
                console.log(this);
            }.bind({x:30});
            fn2('cyy4',20);
        </script>

    作用域和闭包-作用域:

    没有块级作用域,只有函数和全局作用域

        <script>
            //无块级作用域
            if(true){
                var name='cyy';
            }
            console.log(name);
    
            //有全局和函数作用域
            var a=10;
            function fn(){
                var a=20;
                console.log('fn:'+a);
            }
            fn();
            console.log('global:'+a);
        </script>

        <script>
            //作用域链
            var a=10;
            function fn(){
                var b=20;
                //当前函数作用域内没有定义的变量,即自由变量
                console.log(a);
                console.log(b);
            }
            fn();
        </script>

    作用域和闭包--闭包:

    闭包的使用场景:

    1、函数作为返回值

    2、函数作为参数传递

        <script>
            //函数作为返回值
            function F1(){
                var a=100;
                return function(){
                    console.log(a);//a是自由变量,向父级作用域去寻找---函数定义时的作用域
                }
            }
            var f1=F1();
            var a=200;
            f1();//100
    
            //函数作为参数传递
            function F2(){
                var b=100;
                return function(){
                    console.log(b);//b是自由变量,向父级作用域去寻找---函数定义时的作用域
                }
            }
            var f2=F2();
            function F3(fn){
                var b=300;
                fn();
            }
            F3(f2);//100
        </script>

    作用域和闭包--解题:

        <script>
            //错误的写法
            //点击结果都是10
            var i;
            for(i=0;i<10;i++){
                var a=document.createElement('a');
                a.innerHTML=i;
                a.addEventListener('click',function(e){
                    e.preventDefault();
                    alert(i);//i是自由变量,要去父作用域寻找值;for循环不是作用域,所以获取到的i是循环结束的全局变量i=10
                })
                document.body.appendChild(a);
            }
    
    
            //正确写法,自执行的匿名函数形成函数作用域
            var i;
            for(i=0;i<10;i++){
                (function(i){
                    //形成函数作用域,i不再是全局变量
                    var a=document.createElement('a');
                    a.innerHTML=i;
                    a.addEventListener('click',function(e){
                        e.preventDefault();
                        alert(i);//i是自由变量,要去父作用域寻找值
                    })
                    document.body.appendChild(a);                
                })(i);
            }
        </script>
        <script>
            //闭包的应用
            function isFirstLoad(){
                var _list=[];//通常_开头的变量表示私有
                return function(id){
                    if(_list.indexOf(id) >= 0){//不是第一次出现
                        return false;
                    }else{
                        _list.push(id);
                        return true;
                    }
                }
            }
            var firstload=isFirstLoad();
            console.log(firstload(10));//true
            console.log(firstload(10));//false
            console.log(firstload(20));//true
        </script>
  • 相关阅读:
    HTML常用元素标签
    属性列表-边框属性
    (5)opencv的基础操作和矩阵的掩模操作
    (4)关于Alpha通道问题
    (3)关于命名空间的问题
    (2)关于opencv解压
    (1)opencv的安装和遇到的问题
    给adobe acrobat reader 添加图片注释
    安装adobe reader阅读器
    apache安装和mysql php配置问题
  • 原文地址:https://www.cnblogs.com/chenyingying0/p/12733764.html
Copyright © 2011-2022 走看看