Alibaba 2015年前端实习生在线笔试题(上篇)

posted @ Oct 28, 2015 • 笔试面试

摘要:「大三生活开始了。每天真是比较忙,选择了前端这个方向,要学的知识比较多,现在算是夜以继日的赶进度。因为我本人并没有考研的打算,所以对我来说,上大三了,意味着实习,工作就要临近了。年底就要准备实习,近些日子,就找到了一些2015年的前端实习生的笔试题,看看自己能不能解答出来,看看自己还差多远。今天早上我起床,第一件事儿就是,列一列自己实习之前还需要学的东西有哪些?整理了大概七八条的样子吧,看来自己还得静下心来扎实的学上半年。」

说说现在的生活

大三生活开始了。每天真是比较忙,选择了前端这个方向,要学的知识比较多,现在算是夜以继日的赶进度。因为我本人并没有考研的打算,所以对我来说,上大三了,意味着实习,工作就要临近了。年底就要准备实习,近些日子,就找到了一些2015年的前端实习生的笔试题,看看自己能不能解答出来,看看自己还差多远。今天早上我起床,第一件事儿就是,列一列自己实习之前还需要学的东西有哪些?整理了大概七八条的样子吧,看来自己还得静下心来扎实的学上半年。

今年互联网公司招聘都有缩水,说实话,还是挺担心的。不过呢,就像有人评论这次阿里招聘缩水问题说的那样,这么大的公司,总得有人干活,耐心的,静下心来,打好基础才是关键!

不说那么多的废话了,该进入进入正题了,看看这22道Alibaba 2015年前端实习生在线笔试题

单选题

一、(单项选择)对于下列程序运行结果,符合预期的是

function f1() {
    console.time('time span');
}

function f2() {
    console.timeEnd('time span');
}
setTimeout(f1, 100);
setTimeout(f2, 200);

function waitForMs(n) {
    var now = Date.now();
    while (Date.now() - now < n) {}
}
waitForMs(500);

A、time apan:700.077ms
B、time apan:0.066ms
C、time apan:500.077ms
D、time apan:100.077ms

解析:

console.time()语句和console.timeEnd()语句是用来对程序的执行进行计时的。因为f1和f2被都setTimeout()事先设置的定时器装到一个事件队列里面。本来f1应该在100ms后就要执行了,但是因为waitForMs()占用了线程,而执行JavaScript是单线程的,所以就没办法在100ms后执行那个f1,所以需要等500ms等waitForMs()执行完,然后再执行f1和f2,这时候f1和f2就几乎同时执行了。所以应该选时间最短的一项,所以答案应该选B (楷豪师兄提供的解答)

二、(单项选择)请选择结果为真的表达式

A、null instanceof Object
B、null == undefined
C、NaN == NaN
D、false == undefined

解析:

A、未定义的值和定义未赋值的为undefined,null是一种特殊的object,所以typeof null 返回的应该是object,但是为什么null instanceof Object返回的是false呢?原因就是null是个特殊的Object类型的值 ,表示空引用的意思 。instanceof 表示某个变量是否是某个对象的实例 ,所以为false 。

B、undefined == null是正确的,尽管如此,和其他相似之处,但null和undefined并不是等价的。每个作为其独特的类型的唯一成员,undefined是Undefined类型和null是Null类型。所以undefined === null是不正确的,因为他们虽然值相等,但是类型不相等。区分这两个值,可以认为undefined代表一个意想不到的没有值而null作为预期没有值的代表。 Null是一个对象,但是为空。因为是对象,所以typeof null返回object 。null是JavaScript保留关键字。 null参与数值运算时其值会自动转换为0,下列表达式计算后会得到正确的数值 表达式:123 + null 结果是:123 ; 表达式:123 * null 结果是:0 Undefined是全局对象(window)的一个特殊属性,其值是未定义的。但typeof undefined返回undefined。

C、NaN是一个值类型,同是也是一个数值.意思是Not A Number,这个都知道是什么意思.值比较特殊,特殊在于NaN是一个数字,是一个与任何数值都不相等的数字。所以NaN == NaN返回false。

D、undefined被转换为布尔值为false,Boolean(undefined)返回的是false,但是undefined不等于false。所以false == undefined返回false。 所以最终答案应该为B。这里考察的数据类型的基础知识。

三、(单项选择)下面程序的执行结果是

var name = 'World!';
(function() {
    if (typeof name === 'undefined') {
        var name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})();

A、Goodbye Jack
B、Hello Jack
C、Hello undefined
D、Hello World

解析:

因为JavaScript中的变量的查找是就近原则去寻找var定义的变量,当就近没有找到的话就会找外层。题目中因为if判段语句(typeof name === ‘undefined’)就近定义的name就在其执行完的下一行,所以name就被预解析了,实际上可以理解成在if判段语句(typeof name === ‘undefined’)上面var name这样定义了name,但是尚未被赋值。而在它执行完后面再去为name赋值name = ‘Jack’;,所以name的值是undefined。所以typeof name === ‘undefined’成立,所以判断语句会走if成立部分。

所以最终答案应该为A。

不定项选择

四、(不定项选择)以下关于DOM事件流的表述哪些是正确的

A、事件流包括两个阶段:事件捕获阶段、事件冒泡阶段
B、IE跟标准浏览器对于DOM事件流实现不一样
C、假设parentEle是childEle的父节点,绑定事件:parentEle.addEventListener(“click”, fn1, false)和childEle.addEventListener(“click”, fn2,false),当点击childEle的时候fn1将先于fn2触发
D、addEventListener第三个参数true代表支持捕获,false代表不支持捕获

解析:

在W3C事件模型中,任何事件会首先被捕获直至到达目标元素然后再冒泡回去。事件流包括3个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。所以A选项是错的。Web开发者可以选择将事件处理程序注册在捕获或者冒泡阶段。这可以通过addEventListener()方法来实现。如果该方法传入的最后一个参数值为true,表示事件处理程序被注册在捕获阶段,如果为false表示件处理程序被注册在冒泡阶段。所以D选项也是错的。

假设有如下程序(childEle是parentEle的子元素):

1.parentEle.addEventListener(“click”, parentDoSomething, true);

2.childEle.addEventListener(“click”, childEleDoSomething, false); 如果用户点击子元素childEle会发生如下事情:

  • a、点击事件开始于捕获阶段。它会先查询是否有childEle的任何祖先元素在捕获阶段绑定了onclick事件。
  • b、它发现祖先元素1在捕获阶段绑定了onclick事件,于是parentEle.parentDoSomething()首先被执行。
  • c、事件一直查询到目标元素childEle都没有再发现别的在捕获阶段绑定的onclick事件,事件转到它的冒泡阶段并执行childEleDoSomething()(注册在childEle上的在冒泡阶段执行的事件处理程序)。
  • d、事件再次向上查询并检查是否有任何祖先元素在冒泡阶段绑定了onclick事件,并没有查询到,所以什么都没有发生。

再看相反的例子:

1.parentEle.addEventListener(“click”, parentDoSomething, false); 2.childEle.addEventListener(“click”, childEleDoSomething, false); 现在如果用户点击childEle,下面的事情会按顺序发生:

  • a、点击事件发生于捕获阶段。事件查询childEle是否有任何祖先元素在捕获阶段绑定了onclick事件并且没有查找到这样的元素。
  • b、事件查询到目标元素childEle自己。事件转为冒泡阶段并执行childEleDoSomething()。
  • c、事件再次向上查询并检查目标元素是否有任何祖先元素在冒泡阶段绑定了onclick事件。
  • d、它找到了满足条件的parentEle,然后执行parentDoSomething()
    所以选项C是错的,应该是fn2先触发。

因为IE没有提供对事件捕获阶段的支持,所以IE跟标准浏览器对于DOM事件流实现不一样。 所以最终答案应该为B。

五、(不定项选择)通过下面的哪些方法可以获取页面的html元素

A、document.getElementById
B、document.getElementsByClassName
C、document.querySelector
D、document.querySelectorAll

解析:

A、页面的html元素可以通过id获取,具有唯一性,如:var divObjId = document.getElementsById(“test”);。所以A是正确的。

B、页面的html元素可以通过class获取,会选择页面上所有class名为test的DOM标签,如:var divObjClass = document.getElementsByClassName(“test”);。所以B是正确的。

C、D 、document.querySelector只返回匹配的第一个元素,如果没有匹配项,返回null。document.querySelectorAll返回匹配的元素集合,如果没有匹配项,返回空的nodelist(节点数组)。

这两个方法都可以接受三种类型的参数:id(#),class(.),标签,很像jquery的选择器。如:

var obj = document.querySelector("#id");
var obj = document.querySelector(".classname");
var obj = document.querySelector("div");
var el = document.body.querySelector("style[type='text/css'], style:not([type])");
var elements = document.querySelectorAll("#score>tbody>tr>td:nth-of-type(2)");
var elements = document.querySelectorAll("#id1, #id2, .class1, class2, div a, #list li img");

所以C和D都是正确的。

所以最终的答案是A,B,C,D。

六、(不定项选择)下面选项中,对javascript事件的描述不正确的是

A、IE使用attachEvent/detachEvent方法来添加和删除事件监听器;w3c使用addEventListener/removeEventListener方法
B、IE是将event对象作为参数传递给监听器,
w3c事件监听器内使用的是一个全局的Event对象 C、IE提供了对事件捕获阶段的支持
D、要停止事件的传递,IE的做法是设置event对象的cancelBubble为true,而w3c的做法是设置执行stopPropagation方法

解析:

A、IE使用attachEvent/detachEvent方法来添加和删除事件监听器;w3c使用addEventListener/removeEventListener方法。这是正确的。

B、IE事件监听器内使用的是一个全局的Event对象,而w3c是将event对象作为参数传递给监听器。所以B是错误的。

C、IE没有提供对事件捕获阶段的支持。所以C也是错误的。

D、要想阻止冒泡,在Microsoft模型中,需要将事件的cancelBubble属性设置为true。在W3C模型中,需要调用事件的stopPropagation()方法。

这两种方法阻止了事件的所有冒泡。如果想解决浏览器兼容问题,可以像下面这样写:

function doSomething(e) {
    e = window.event || e;
    e.cancelBubble = true;
    if (e.stopPropagation) {
        e.stopPropagation();
    }
}

在不支持cancelBubble属性的浏览器中设置它的值并不会报错。浏览器会忽略它并创建这个属性。当然,它并不能真正地阻止冒泡,但是给它分配值的操作本身是安全的。 所以最终的答案是B,C。

七、(单项选择)执行上面的代码array1和array2的值分别是什么?

var array1 = [1, 2];
var array2 = array1;
array1[0] = array2[1];
array2.push(3);
console.log(array1);
console.log(array2);

A、Array1的值为[2,2];Array2的值为[1,2,3]
B、Array1的值为[2,2,3];Array2的值为[1,2,3]
C、Array1的值为[2,2,3];Array2的值为[2,2,3]
D、Array1的值为[1,2,3];Array2的值为[1,2,3]

解析:

数组对象是引用的关系,array2改变,array1也会改变。array1改变,array2也会改变。 所以最终的答案是C。

八、(不定项选择)有如下代码

function Test(name, age) {
    this.name = name;
    this.age = age;
};
Test.prototype = {
    name: 'aliyun',
    hasOwnproperty: function() {
        return false;
    }
};
var instance = new Test('alibaba', 102);

以下关于原型链的说法正确的是:

A、JavaScript对象有两种不同的属性,一种是对象自身的属性,另一种是继承于原型链上的属性
B、instance.name == ‘aliyun’为true
C、instance.hasOwnproperty(‘age’)结果将是false
D、所有对象都继承自Object.prototype

解析:

A、javascript对象有两种不同的属性来源,一个是对象自身属性,另一是继承于原型链上的属性,所以A是正确的。
B、因为instance是Test对象的一个实例,如果我们在该实例中创建了name这个属性,这个属性的值将会屏蔽原型中的那个属性。所以instance.name == ‘aliyun’为false,instance.name的值应为alibaba,所以B是错误的。
C、因为instance是Test对象的一个实例,所以同样拥有hasOwnproperty这个方法,所以返回的结果是false.
D、每个JavaScript对象都继承一个原型链,而所有原型都终止于Object.prototype。注意,这种继承是活动对象之间的继承。它不同于继承的常见概念,后者是指在声明类时类之间的发生的继承。因此,JavaScript继承动态性更强。它使用简单算法实现这一点,如下所示:当您尝试访问对象的属性/方法时,JavaScript将检查该属性/方法是否是在该对象中定义的。如果不是,则检查对象的原型。如果还不是,则检查该对象的原型的原型,如此继续,一直检查到Object.prototype。下图说明了此解析过程

Alt text

所以D是正确的。 所以最终的答案是A、C、D。


今天就整理一半,剩下的明天补上!剩下的都是一些实现某一个功能的题目