JavaScript面向对象笔试汇总(1)

  • 程序运行后,输出为何?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function 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

  • 如何在函数内部得到函数自身的属性
    1
    2
    3
    4
    function f(){
    //如何在里面获得函数f的属性a
    }
    f.a = 100;

做法就是:

1
2
3
4
5
function f(){
alert(arguments.callee.a);
}
f.a = 100;
f();

也可以这样:

1
2
3
4
5
function f(){
alert(this.a)
}
f.a = 100;
f.call(f);

  • 考察数组枚举调用函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var 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,具体原因不清楚)。因此最终的输出结果使20

  • 程序运行后,输出什么
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var 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的执行时机是什么,就是一个对象定义的时候,如果值时表达式,那么在定义的时候,就已经执行掉了,比如下面的程序,先弹出”你好”,再弹出”么么哒”

1
2
3
4
5
6
var obj = {
a : (function(){
alert("你好")
})()
}
alert("么么哒");

再看我们的题目,程序执行到第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:

  • 以下程序会弹出什么

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function 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实际上是一个类数组。
要想取得预期的效果,可以这样改:

1
2
3
4
5
6
7
8
9
10
function fun1(){
fun2.apply(null,arguments)
}
function fun2(a,b,c,d){
alert("a");
alert("b");
alert("c");
alert("d");
}
fun1(1,2,3,4)

apply的妙处就是能打开数组,比如可以用来求数组的最大值

1
2
var arr = [2,324,32,536,863,456]
Math.max.apply(null,[arr])

  1. 程序运行2000毫秒后,控制台输出什么?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var 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
2
3
4
5
6
7
8
9
10
function fun(fn,arg1,arg2,arg3){
arguments[0](1,2,3)
}
function fun2(m,n){
alert(this.length);
alert(this.callee.length);
alert(arguments.length);
alert(arguments.callee.length)
}
fun(fun2);

分别弹出1,4,3,2
解析:
第一个alert中的this指向arguments类数组的本身,此时arguments的长度为1,就是fun(fun2)的实参fun2
第二个this.callee.length指向的是fun的形参fun(fn,arg1,arg2,arg3)的长度,所以为4。
第三个arguments.lengtharguments[0](1,2,3)实参的长度,所以为3。
第四个arguments.callee.lengthfun2(m,n)的形参的长度,所以为2。

  • 试写出程序的执行结果
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    var 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 。不解释了,看注释

  • 试写出程序执行的结果
1
2
3
4
console.log(Object instanceof Object);
console.log(Function instanceof Function);
console.log(String instanceof String);
console.log(Function instanceof Object);

分析:

  • 任何函数都是Function new出来的。包括Object,Function也是Function new出来的。
  • a instanceof A ,就要看A的prototype是不是在a 的原型链上。

答案为:true ,true ,false,false,true

  • 试写出程序执行的结果
1
2
3
4
5
6
7
8
9
10
function Fun(){
this.a = 5;
function fun(){
this.a = 10;
}
fun.a = 15;
return fun;
}
var o = new(new Fun());
console.log(o.a);

解析:结果为10
首先我们要理解new一个函数实例的过程。第一次new Fun()的时候,并且return的是引用类型值,所以函数返回的就是里面的fun函数,此时再次new就是按照四步走,给返回的对象绑定了a属性值时10,所以输出10。

  • 用尽可能少的代码实现字符串str 重复n次。
    1
    2
    3
    function (str,n){
    return (new Array(n+1).join(str));
    }

解析:利用的就是new Array(5)就是创建一个5项的空数组,此时join.(“☆”),得到”☆☆☆☆”。所以要加1。

分享到