JavaScript 面试题

来源:互联网 发布:淘宝上的正品足球鞋店 编辑:程序博客网 时间:2024/06/05 17:22
  • 闭包和匿名函数
    个人经验: 在做闭包或匿名函数的面试题时,一定谨记函数作用域链的概念
    函数作用域链: 当函数被执行时,函数执行环境会创建一个函数作用域链,保证当前函数内的所有变量和函数的有序访问,函数的活动对象arguments 总在函数作用域链的最前端,而下一个变量对象来自包含环境或者全局环境 这样一直执行下去。
    最后执行的一般是 全局环境。
var name = "window";var ob ={    name:'object',    fn:function () {       let name = "testName";       console.log(name);//输出 testName    },};var name = "window";var ob ={    name:'object',    fn:function () {       console.log(name);//输出name    },};

第一个输出为testName 是因为在函数内部 定义name 又在函数内部输出,在函数作用域链同级就找到name
所以输出 testName,
第二个输出为 window 不输出object ,是因为object是在对象作用域,函数作用域不会去访问object里面的name,fn函数在当前作用域没找到name,则会向上一级的函数作用域查找name,在这里fn函数没有上一级函数 ,所以直接找到全局环境,输出 window,如果将name 改为this.name则相当于将object作用域包裹在fn函数作用域链中,输出object

现在来看一道面试题:

function fun(n,o) {    console.log(o);    console.log(arguments[0]);    console.log(arguments)    return {        fun:function(m){            return fun(m,n);        }    };}var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);var b = fun(0).fun(1).fun(2).fun(3);var c = fun(0).fun(1);  c.fun(2);  c.fun(3);

先说最后三行的第一行
var a= fun(0);
console.log(o);输出的是 undefined 应为 参数数组现在只传了一个值 n,n = 0
然后最外一层的fun函数 return 一个对象 {fun(){}},里面装有一个函数fun
现在a = {fun(m){return fun(m,n)}}

a.fun(1);
很明显执行的是第二个函数fun,传递参数为1,然后return 一个函数fun,
但是这个fun在当前函数作用域中并没有,于是就向上级开始查找,找到了全局环境中的
fun函数,即是最外层的那个fun函数。(为什么不是第二个fun函数的原因是 第二个fun函数所在的
作用域不是函数作用域),所以 return 里面的fun函数是最外层的fun函数,但是这个return语句是在
第二个fun和第一个fun的函数作用域里面的 里面的变量 m和n,m来自第二个fun函数 ,n来自第一个fun函数。
于是 m = 1,n=0。console.log(o);//输出0

a.fun(2),a.fun(3)与a.fun(1)完全相同


最后三行的第二行
var b = fun(0).fun(1).fun(2).fun(3);
仔细去看每一个fun的返回值就会发现
fun(0)执行了第一个return 返回的是一个对象

    {        fun:function(m){            return fun(m,n);//这个fun是调用的全局环境下的fun        }    };

然后 fun(1),执行的上面的第一个fun,即是fun(m)…,所以fun(1)执行了第二个return ,值得注意的是 第二个return
执行的同时,会执行第一个return,所以fun(1)返回的还是上面的这个对象 ,然后fun(2),fun(3)亦是。
所以左后arguments里面的值是{‘0’:m,’1’:n} ==={‘0’:3,’1’:2};


最后三行的第三行
var c = fun(0).fun(1); //还是一样返回的

 {        fun:function(m){            return fun(m,n);//但是此时fun是存在于内存中,分布调用相当于每次调用一个新的函数        }    };

c.fun(2);还是一样执行上面对象中的fun函数 但是 n 是第二次调用的时候的n=1
c.fun(3);n还是第二次调用时候的n=1;

0 0
原创粉丝点击