js面试题

<script>

        /*  // 练习题1

            // var a

            console.log(a);  // undefined

            var a = 12   // 存在变量提升定义


            function fn() {

                // var a

                console.log(a);

                var a = 13  // 注意;这里的a,只会提升到方法作用域的顶部定义  

                // 方法中的var定义的变量也会提升,

                // 且与全局变量同名时,将会提升到局部(方法)作用域的顶端

            }

            fn()  // undefined

            console.log(a);  // 12

            // 所以此处的a是全局变量a  : var a = 12

        */

        // 只有var定义的变量存在提升

        /*  

            // 练习题2

            // var a

            console.log(a);   // undefined

            var a = 12    // 存在变量提升  


            function fn() {

                // var a = 12

                console.log(a);

                a = 13  

            }

            fn()   // 12

            console.log(a);  // 13

        */

        // 注意:当前作用域里面没有a,就回到上一层作用域里面去寻找a

        /*

            // 练习题3

            console.log(a);  // 报错:Uncaught ReferenceError(未捕获引用错误):Cannot access 'a' before initialization

            let a = 12

            function fn() {

                console.log(a);

                let a = 13

            }

            fn()  // 报错:Uncaught ReferenceError:Cannot access 'a' before initialization


            console.log(a);  // 12

        */


        // let 定义的变量不存在提升

        // 注意:只要是在当前作用域里面存在的变量,就不会去上层作用域寻找了。


        /*

            // 练习题4

            console.log(a);  // Uncaught ReferenceError: a is not defined

            a = 12  // 没有用var定义的变量不存在提升

            function fn() {

                console.log(a);  // 报错,因为当前作用域里面有a,就不会调用外层的a

                let a = 13       // 注意:这里的a的作用域是方法,并且不存在提升

            }

            fn()  // Uncaught ReferenceError: Cannot access 'a' before initialization

            console.log(a);  // 12

        */


        // 注意:变量定义时不使用任何关键字,该变量也不存在提升  


        // 定义变量可以不使用任何关键字,但是在定义该变量之前,不能使用该变量,否则报错

        // 这是一种不规范的写法,错误:未捕获引用错误(未定义就进行使用)

        /*

            // 练习题5

            console.log(a);  // Uncaught ReferenceError:Cannot access 'a' before initialization

            let a = 12   // 该变量不会提升

            function fn() {

                console.log(a);  // 报错,因为当前作用域里面有a,就不会调用外层的a了

                let a = 13  // 注意:这里的a的作用域是方法

            }

            fn()  // Uncaught ReferenceError: Cannot access 'a' before initialization

            console.log(a);  // 12

        */

        // 注意:作用域是以方法为单位的

        // 总结:

        // 先看变量是否有关键字定义

        // 无关键字定义则不会提升且无作用域,(对代码块无任何影响)

        // 再看定义变量的关键字为何,

        // 为var则为全局变量,存在提升,作用域是全局

        // 全局变量同名时,将会分别提升到局部(方法)作用域的顶端

        // 为let则为局部变量,不存在提升,作用域是方法内部

        // 提升就是代码块的执行顺序,提升将会提升至全局顶端或是方法定义顶端

        // 即将会先行执行,再执行其他代码

        /*

            // 练习题1

            var foo = 1

            function bar() {

                if(!foo){

                    var foo = 10   // 注意:该变量会提升到方法作用域的顶部定义

                }

                console.log(foo);

            }

            bar()  // 10

            // 相当于

            var foo = 1

            function bar() {

                var foo    // 此时foo的值为undefined

                if(!foo){  // 所以此处 !foo = true

                    foo = 10   // foo = 10

                }

                console.log(foo);  // 输出了10

            }

            bar()  // 10

        */

        // 注意:只要在作用域使用var定义的变量,一定会提升到当前作用域顶端定义。

        /* // 练习题2

        var foo = 1

        function bar() {

            if(!foo){

                foo = 10   // 注意:这里的foo是全局的foo

            }

            console.log(foo);

        }

        bar()  // 1 */

        /* // 练习题3

        var n = 0  // 这里定义的是全局变量n

        function a() {

            var n = 10  // 这里是a方法中定义的n

            function b() {

                n++

                console.log(n);

            }

            b()

            return b

        }

        var c = a()  // 11  // a()方法return了b函数,再将其赋值给全局变量c

        // 但是调用a()方法时,将会执行a()方法,所以b()方法此时已经被执行了一次,打印输出了n (n++ => n = 11)

        c()  // 12   // 此处再次调用c(),即是b()方法再次被调用了,输出了n (n++ => n = 11 + 1 = 12)

        console.log(n);  // 0   // 这里打印的是全局变量n */

        // 注意:使用var定义的变量可以同名,但是需要通过位置来判断是否是全局变量。

        /* // 练习题4

        var a=10

        var b=11

        var c=12

        function test(a){

            a = 1   // 这里的a是方法的形参

            var b = 2  // 这里的b是test方法里面的b  

            c = 3  // 但是这里的c与全局变量同名,所以这里的c是全局变量c

        }

        test(10)


        console.log(a)  // 10

        console.log(b)  // 11

        console.log(c)  // 3 */

        // 注意:作用域看方法

        /* // 练习题5

        // var a

        // console.log('a' in window);  // true  // in关键字,用于检查是否在指定对象中存在,返回值Boolean型

        if(!('a' in window)){

            var a = 10  // 注意:这里的a会提升为全局变量,提升至全局顶端定义

        }

        console.log(a)  // undefined */

        /* // 练习题6

        var a = 4

        function b(x, y, a) {  

            console.log(a)  // 打印的是形参a (a = 3), 输出3

            arguments[2] = 10  // 1,2,3,...  => 1,2,10,...

            // console.log(arguments);  // Arguments(3) [1, 2, 10, callee: ƒ, Symbol(Symbol.iterator): ƒ]

            console.log(a)  // 再次打印形参a (a = 10), 输出10

        }

        a = b(1,2,3)  // 注意:b方法没有返回值,返回值就默认为undefined

        // 3

        // 10

        console.log(a)  // undefined */

        /* // 练习题7

        var a = 9

        function fn() {

            a = 0     // 1  2  1  2

            return function(b){

                return b + a++  // 5 + 0   5 + 1   5 + 0   5 + 1

            }

        }

        var f=fn()

        console.log(f(5))     // 5

        console.log(f(5))     // 6

        console.log(fn()(5))  // 5

        console.log(f(5))     // 6

        console.log(a)        // 2 */

        /* // 练习题8

        var ary = [1,2,3,4]

        function fn(ary){

            ary[0] = 0   // 0,2,3,4

            ary = [0]  // 0

            ary[0] = 100 // 100

            return ary  // 100

        }

        var res = fn(ary)

        console.log(ary)   // [0,2,3,4]

        console.log(res)   // [100]

        // 整个运算(执行)过程如下:

        // 先在栈中创建一个全局变量ary,其内部存放的堆内存地址指向堆中新创建的数组1[1,2,3,4]

        // 然后将fn(ary)的值传给变量res,这时候致命的重点就悄然而至了:

        // 传的实参是全局变量ary赋值给形参ary,所以会在栈中创建一个新变量ary(形参),其内存地址也指向堆中的数组1[1,2,3,4]

        // 由于 ary[0] = 0 导致 堆中的数组1变为[0,2,3,4],同时全局变量ary也是指向数组1,所以全局变量ary = [0,1,2,3]

        // ary = [0] 导致 形参ary中存放的堆内存地址指向了新数组2[0],所以此时形参ary与全局变量ary不再指向同一个堆内存地址

        // ary[0] = 100  致使 新数组2变为[100],即形参ary指向数组2[100],

        // return ary 致使 返回的形参ary 赋值给了变量res,(本质上:将结果存放的内存地址拷贝一份给了res)

        // 所以,res 指向 数组2[100],输出res时将输出[100]

        // 全局变量ary 指向 数组1[1,2,3,4],当输出全局变量ary时将输出[0,2,3,4]

        */

        /* // 练习题9

        function fn(i){ // i => 10 => 20 => 30

            return function(n){  // n => 20 => 40 => 50

                console.log(n + (i++))  // 30  60  80  41

                // console.log(n + i)  // 30  60  80  41

                // i++   //  11  12

                // 注意:n + (i++) 中的 i++,无论是否有括号,都是先返回++前面的值,再进行自加1的操作。

            }

        }

        var f = fn(10)  // 所以此处i的值仍为10

        f(20)  //i = 10 , n = 20 => 20 + 10 => 30 , i = 11   // 30

        fn(20)(40)  // 40 + 20 => 60       // 60

        fn(30)(50)  // 50 + 30 => 80       // 80

        f(30)  //i = 11 => 30 + 11 => 41   // 41 */

        // 注意:f()与fn()的方法区内存空间是彼此独立的

        /* // 练习题10

        var num = 10   // window.num = 10  => 65

        var obj = { num: 20 }  // obj.num = 20

        obj.fn = (function (num) { // num = 20

            this.num = num * 3  // window.num = obj.num * 3 = 20 * 3 = 60

            num++  // num = 20 + 1 = 21

            return function (n) {

                this.num += n

                num++

                console.log(num)

            }

        })(obj.num)  // 传参obj.num = num = 20

        var fn = obj.fn   // window.fn = obj.fn

        console.log(fn)   // window.fn = function (n){this.num += n;...}

        fn(5)   // window.fn(20)(5) => window.num + 5 = 65 , num = 21+1 = 22 // 22

        obj.fn(10)  // obj.fn(20)(10) => obj.num + 10 => obj.num = 30, num = 22+1 = 23   // 23

        console.log(num, obj.num)  // 65 30 */

        /* // 练习题11

        var fullName = 'language'   // window.fullName = 'language'

        var obj = {

            fullName: 'javascript',  // obj.fullName = 'javascript'

            prop: {                  // prop{getFullName()}

                getFullName: function() {

                    return this.fullName

                }

            }

        }

        console.log(obj.prop.getFullName())  // return this.fullName => prop.fullName = undefined => undefined

        var test = obj.prop.getFullName  //test = getFullName(){return this.fullName}

        console.log(test())    //window.test() => this.fullName => window.fullName = 'language' => language */


        /* // 练习题11-2

        var fullName = 'language'   // window.fullName = 'language'

        var obj = {

            fullName: 'javascript',  // obj.fullName = 'javascript'

            prop: {                   // prop{getFullName()}

                getFullName: () => {  

                    return this.fullName

                }

            }

        }

        console.log(obj.prop.getFullName())  // return this.fullName => window.fullName = 'language' => language

        var test = obj.prop.getFullName  //test = getFullName

        console.log(test())    //window.test() => this.fullName => window.fullName = 'language' => language */


        // 注意:箭头函数里面的this指向它外层方法的this,如果外层函数没有this或者没有外层函数,将会指向window对象


        /* // 练习题12

        var name = 'window'  // window.name = 'window'

        var Tom = {

            name: "tom",    // Tom.name = "tom"

            show: function() {

                console.log(this.name)

            },

            wait: function() {

                var fun = this.show  // fun = tom.show

                fun()

            }

        }

        Tom.wait()  // var fun = console.log(this.name) => console.log(window.name) => window */

</script>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容