- 程序运行后,输出为何?1234567891011function fun(){var a =1;this.a = 2;function fn(){return this.a;}fn.a = 3;return fn;}var result = fn()();console.log(result);
解析:var a = 1
是一个局部变量,此时fun()
是典型的函数直接加圆括号,所以函数的上下文就是window
对象。第3行this.a
就表示给全局增加了一个a
属性,值为2
。
第一次fun()
返回一个内存函数,第二次fun()
也是典型的函数直接加圆括号,所以上下文也是window
对象。此时运行,返回window.a
,因为第一次运行已经给全局设置了a
值为2
,所以result
的结果最终为2
。
- 如何在函数内部得到函数自身的属性1234function f(){//如何在里面获得函数f的属性a}f.a = 100;
做法就是:
也可以这样:
- 考察数组枚举调用函数1234567891011var arr = [fn1,fn2];function fn1(){return this.length;}function fn2() {return this[0]}var a = arr[0]();var b = arr[1]()();console.log(a);console.log(b);
首先看语句arr[0]()
,此时是数组枚举出函数,然后调用,所以函数里面的this
是数组,也就是this.length
要返回的是数组的长度2。
第二条语句arr[1]()()
表示fn2()
运行得到的结果再运行,此时看一下arr[1]()
,表示的是数组枚举出来然后运行,此时函数里面的this
是数组,返回fn1
。第二个圆括号就是fn1
直接加圆括号运行,this
就是window
对象,此时window的length属性值为0
(测试为0,具体原因不清楚)。因此最终的输出结果使2
和0
。
- 程序运行后,输出什么123456789101112131415var a = 1;var obj = {a : 2,fn : (function () {this.a = 3;return function(){return this.a;}})()}var fn = obj.fn;var result1 = obj.fn();var result2 = fn();console.log(result1);console.log(result2);
解析:首先我们得明白IIFE的执行时机是什么,就是一个对象定义的时候,如果值时表达式,那么在定义的时候,就已经执行掉了,比如下面的程序,先弹出”你好”,再弹出”么么哒”
再看我们的题目,程序执行到第5行的IIFE时,this
表示window
对象,此时全局的a
属性就变成了3。第12行,obj.fn()
,this
指向obj
。此时a为2。第13行,var fn = obj.fn()
,再执行fn()
,此时this
就是window
对象,因此结果为2和3。
给页面上的方形盒子添加onmousemove事件监听,请在图中画出表示event.clientY值的线段并标注1,画出document.documentElement.clientHeight的线段并标注2,画出document.body.scrollTop的线段并标注3:
以下程序会弹出什么
12345678910function fun1(){fun2(arguments)}function fun2(a,b,c,d){alert("a");alert("b");alert("c");alert("d");}fun1(1,2,3,4)
依次弹出[object Argument],undefined,undefined,undefined。因为第一行的arguments实际上是一个类数组。
要想取得预期的效果,可以这样改:
apply的妙处就是能打开数组,比如可以用来求数组的最大值
- 程序运行2000毫秒后,控制台输出什么?12345678910var a = 1;function fun(){var a = 2;this.a = 3;}setTimeout(function(){var a = 4;fun();console.log(this.a);},2000)
输出的结果是3,因为第8行执行fun()的时候,this指向的是window,调到第四行改变了a的值,所以this.a为3。
- 试写出程序执行的结果:
|
|
分别弹出1,4,3,2
解析:
第一个alert
中的this
指向arguments
类数组的本身,此时arguments
的长度为1,就是fun(fun2)
的实参fun2
。
第二个this.callee.length
指向的是fun
的形参fun(fn,arg1,arg2,arg3)
的长度,所以为4。
第三个arguments.length
是arguments[0](1,2,3)
实参的长度,所以为3。
第四个arguments.callee.length
是fun2(m,n)
的形参的长度,所以为2。
- 试写出程序的执行结果1234567891011121314151617181920var m = 10;var obj1 = {m : 20,fn : (function(){this.m *= 2;m = 5; //注意这里并没有把window的属性m改为5,因为它的下一行有变量声明提升的作用var m = 6;//,所以第6行改的实际上是闭包里面的m值return function(){this.m *= m;console.log(this.m);}})()};var obj2 = {m : 30};var fn = obj1.fn;fn();obj.fn();obj.fn.call(obj2);
这道题考了闭包,this的指向,变量声明提升,立即执行函数。
输出结果依次为 120 , 120, 180 。不解释了,看注释
- 试写出程序执行的结果
|
|
分析:
- 任何函数都是Function new出来的。包括Object,Function也是Function new出来的。
- a instanceof A ,就要看A的prototype是不是在a 的原型链上。
答案为:true ,true ,false,false,true
- 试写出程序执行的结果
|
|
解析:结果为10
首先我们要理解new一个函数实例的过程。第一次new Fun()的时候,并且return的是引用类型值,所以函数返回的就是里面的fun函数,此时再次new就是按照四步走,给返回的对象绑定了a属性值时10,所以输出10。
- 用尽可能少的代码实现字符串str 重复n次。123function (str,n){return (new Array(n+1).join(str));}
解析:利用的就是new Array(5)就是创建一个5项的空数组,此时join.(“☆”),得到”☆☆☆☆”。所以要加1。