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

posted @ Nov 5, 2015 • 前端笔记

摘要:「今早起床后补习了一点CSS3的知识,然后就来把昨天剩下的面试题补上,剩下的基本都是一些主观性比较强的题目,个人有个人的做法,在这里补充了一些个人的见解,不知道是不是考官心里所想的答案!」

简单介绍一下

2015-09-13

今早起床后补习了一点CSS3的知识,然后就来把昨天剩下的面试题补上,剩下的基本都是一些主观性比较强的题目,个人有个人的做法,在这里补充了一些个人的见解,不知道是不是考官心里所想的答案!

实现一些功能

九、实现函数range([start,]stop[,step])返回一个数组(step大于1)

  • range(1,11); => [1,2,3,4,5,6,7,8,9,10]
  • range(0); => []
  • range(10); => [0,1,2,3,4,5,6,7,8,9]
  • range(0,30,5); => [0,5,10,15,20,25]

解析: 实现代码如下:

function range() {
    var argLength = arguments.length,
        newArray = [],
        i = 0,
        start = arguments[0],
        stop = arguments[1],
        step = arguments[2];
    switch (argLength) {
        case 0:
            throw Error('至少输入一个参数,限止数组在哪里结束');
        case 1:
            {
                stop = arguments[0];
                for (i = 0; i < stop; i++) {
                    newArray.push(i);
                }
                return newArray;
            }
        case 2:
            {
                for (i = start; i < stop; i++) {
                    newArray.push(i);
                }
                return newArray;
            }
        case 3:
            {
                if (step < 1) {
                    throw Error('step > 1');
                } else {
                    for (i = start; i < stop; i += step) {
                        newArray.push(i);
                    }
                    return newArray;
                }
            }
        default:
            throw Error('最多传入三个参数');
    }
}

十、背景:

1、对象A直接调用对象B的某个方法,实现交互逻辑。但是导致的问题是A和B紧密耦合,修改B可能导致A调用B的方法失效。 2、为了解决耦合导致的问题,我们可以设计成: 对象A生成消息 -> 将消息通知给一个消息处理器(Observable)-> 消息处理器将消息传递给B 具体的调用过程变成: A.emit(‘message’,data); B.on(‘message’,function(data){});

请实现这一事件消息代理功能 //请将事件消息功能补充完整 function EventEmitter(){}

解析:

实现代码如下:

function EventEmitter() {
    this.eventFunctionMap = {};
}
EventEmitter.prototype.emit = function(eventName, data) {
    this.eventFunctionMap[eventName].call(this, data);
}
EventEmitter.prototype.on = function(eventName, callback) {
    this.eventFunctionMap[eventName] = callback;
}

十一、实现下图的布局

<main>
    <div> A </div>
    <div> B </div>
    <div> C </div>
</main>

Alt text

解析:

实现代码如下:

div {
    height: 50px;
    width: 50px;
    background - color: black;
    display: inline - block;
    margin - left: 10px;
    color: white;
    font - size: 20px;
    text - align: center;
    line - height: 50px;
}

下面是另一种答案:

/**base style**/
div {
    background: #000;
    color: #fff;
    height: 50px;
    width: 50px;
    text-align: center;
    line-height: 50px;
}

/**start here**/
main {
    text-align: center;
}

div {
    display: inline-block;
    _display: inline;/*hank IE*/
    _zoom: 0;/*hank IE*/
}

十二、有一个包含数据列表的页面,数据行数不确定。每一行数据都有一个删除按钮,单击删除按钮删除该列数据,请用JavaScript实现该功能。

解析:

实现代码如下:

window.onload = function() {
    //这个个人觉得比较麻烦
    /*var oUl = document.getElementsByTagName('ul')[0];
    oUl.onclick = function(ev) {
        var ev = ev || window.event;
        var target = ev.target || ev.srcElement;
        if (target.tagName.toLowerCase() == 'button') {
            var tr = target.parentNode;
            tr.parentNode.removeChild(tr);
        }
    }*/

    // 隐藏节点
    /*var oButton = document.getElementsByTagName('button');
    for (var i = 0; i < oButton.length; i++) {
        oButton[i].onclick=function  () {
            this.parentNode.style.display="none";
        };
    }*/


    // 移除节点
    var oButton = document.getElementsByTagName('button');
    for (var i = 0; i < oButton.length; i++) {
        oButton[i].onclick=function  () {
            this.parentNode.parentNode.removeChild(this.parentNode)
        };
    }
}

HTML页面

<ul>
    <li>一
        <button>删除一</button>
    </li>
    <li>二
        <button>删除二</button>
    </li>
    <li>三
        <button>删除三</button>
    </li>
    <li>四
        <button>删除四</button>
    </li>
    <li>五
        <button>删除五</button>
    </li>
    <li>六
        <button>删除六</button>
    </li>
</ul>

十三、编写CSS让一个已知宽高的DIV,在PC/手机端水平垂直居中。

解析:

实现代码如下(常见的水平垂直居中显示问题):

div {
    width: 300px;
    height: 300px;
    border: 1px solid red;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -150px;
    margin-left: -150px;
} 效果图如下:

Alt text

十四、使用语义化的 HTML 标签及CSS完成以下布局

Alt text

要求:容器默认宽度320px,图片100*100 • hover 时容器宽度变为400px • 右侧文字宽度自适应,考虑模块化和扩展性

解析:

实现代码如下:

div{
width : 320px;
}
div:hover{
width : 400px;
}
img{
    float : left;
    width : 100px;
    height : 100px;
}
h1{
    color : #333;
    margin-bottom : 8px;
    font-size : 20px;
}
p{
    color : #666;
    font-size : 12px;
    line-height: 1.2em;
}

HTML代码:

<div> <img src="http://littlewhitechen.github.io/img/artical/m4.png">
        <h1>(最多两行20px #333,顶部对齐图片,底部间距8px)</h1>
        <p>(12px #666 行高1.2)使用语义化的HTML标签完成以下布局,考虑模块化和扩展性。容器默认为320px,右侧文字宽度自适应</p>
</div> 效果图:

Alt text

十五、写一个可以暂停执行的JavaScript函数

解析:

1、使用函数闭包来实现

<input type="button" value="继续" onclick='test();'/>


/*需要执行的函数*/
function test(x){
alert(x++);
    alert(x++);
    return function(){
        alert(x++);
    }}
var st = test(10);

2、使用setTimeOut来实现

Javascript中暂停功能的实现 Javascript本身没有暂停功能(sleep不能使用)同时 vbscript也不能使用doEvents,故编写此函数实现此功能。 javascript作为弱对象语言,一个函数也可以作为一个对象使用。 比如:

function Test(){
    alert("hello world");
    this.NextStep=function(){
       alert("NextStep");
    }
 }

我们可以这样调用 var myTest=new Test();myTest.NextStep();我们做暂停的时候可以吧一个函数分为两部分,暂停操作前的不变,把要在暂停后执行的代码放在this.NextStep中。 为了控制暂停和继续,我们需要编写两个函数来分别实现暂停和继续功能。 暂停函数如下:

function Pause(obj, iMinSecond) {
    if (window.eventList == null) window.eventList = new Array();
    var ind = -1;
    for (var i = 0; i < window.eventList.length; i++) {
        if (window.eventList[i] == null) {
            window.eventList[i] = obj;
            ind = i;
            break;
        }
    }
    if (ind == -1) {
        ind = window.eventList.length;
        window.eventList[ind] = obj;
    }
    setTimeout("GoOn(" + ind + ")", iMinSecond);
}

该函数把要暂停的函数放到数组window.eventList里,同时通过setTimeout来调用继续函数。 继续函数如下:

function GoOn(ind) {
    var obj = window.eventList[ind];
    window.eventList[ind] = null;
    if (obj.NextStep) obj.NextStep();
    else obj();
}

该函数调用被暂停的函数的NextStep方法,如果没有这个方法则重新调用该函数。 函数编写完毕,我们可以作如下测试:

function Test() {
    alert("hellow");
    Pause(this, 1000);
    //调用暂停函数
    this.NextStep = function() {
        alert("NextStep");
    }
}

十六、用JavaScript写一个Ajax的get请求

解析:

创建 XMLHttpRequest 对象

var xmlHttp = null;
function GetXmlHttpObject() {
    if (window.XMLHttpRequest) {
        Xmlhttp = new XMLHttpRequest();
    } else {
        Xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    return xmlhttp;
}

ajax方法

function getLabelsGet() {
    xmlHttp = GetXmlHttpObject();
    if (xmlHttp == null) {
        alert('您的浏览器不支持AJAX!');
        return;
    }
    var id = document.getElementById('id').value;
    var url = "http://LittlewhiteChen.github.io?id=" + id + "&t/" + Math.random();
    xmlHttp.open("GET", url, true);

    xmlHttp.onreadystatechange = getOkGet; //发送事件后,收到信息了调用函数    xmlHttp.send(null);}

    function getOkGet() {
        if (xmlHttp.readyState == 1 || xmlHttp.readyState == 2 || xmlHttp.readyState == 3) {

        } else if (xmlHttp.readyState == 4) {
            if ((xmlHttp.status >= 200 && xmlHttp.status < 300) || xmlHttp.status == 304) {
                var data = xmlHttp.responseText;
            } else {
                alert("Request was unsuccessful:" + xmlHttp.status);
            }
        }
    }
}

简洁版的

 function() {
        //创建Ajax对象(三步)
        var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');

        xhr.open('get', 'getNews.php', true);

        xhr.send();

        xhr.onreadystatechange = function() {
            if (xhr.readyState == 1 || xhr.readyState == 2 || xhr.readyState == 3) {
                // 本地提示:加载中...
            } else if (xhr.readyState == 4) {
                if (xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
                    var data = JSON.parse(xhr.responseText);
               //……处理返回的结果
                } else {
                    alert("Request was unsuccessful:" + xhr.status);
                }
            }

        }

    }

封装了一个Ajax的方法:

function ajax(method, url, data, success) {
    var xhr = null;
    try {
        xhr = new XMLHttpRequest();
    } catch (e) {
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }
    //data即使没有也有有一个空字符串作为占位符
    if (method == 'get' && data) {
        url += '?' + data;
    }

    xhr.open(method, url, true);
    if (method == 'get') {
        xhr.send();
    } else {
        xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
        xhr.send(data);
    }

    xhr.onreadystatechange = function() {

        if (xhr.readyState == 4) {
            if (xhr.status == 200) {
                // 这个函数如果存在就执行
                success && success(xhr.responseText);
            } else {
                alert('出错了,Err:' + xhr.status);
            }
        }

    }
}

ajax(method, url, data, function(data){
    //处理获取的data
})

十七、使用html+css实现以下图形(不能用图片)

Alt text

解析:

这道题感觉是做的最蛋疼的一道题,因为我之前根本就不理解题目到底要我实现哪个图形,狂刷新了N多遍网页,也没看到什么图形,后来经过闻东师兄提醒之后才恍然大悟,原来真的是要我实现右边那个插入图片的小图标。不过就算当初知道这要实现这个小图标,我也做不出来,因为我根本不知道那两个三角形要怎么实现。

CSS代码:

#rectangle {
    background: #FFF;
    border: 10px solid #999999;
    padding: 10px;
    height: 120px;
    width: 200px;
}

#circle {
    position: absolute;
    margin-left: 140px;
    margin-top: 10px;
    width: 40px;
    height: 40px;
    background: #999999;
    -moz-border-radius: 20px;
    -webkit-border-radius: 20px;
    border-radius: 20px;
}

#triangle {
    width: 0;
    height: 0;
    position: absolute;
    margin-top: 40px;
    border-bottom: 80px solid #999999;
    border-left: 50px solid transparent;
    border-right: 70px solid transparent;
}

#triangle2 {
    width: 0;
    height: 0;
    position: absolute;
    margin-top: 60px;
    margin-left: 80px;
    border-bottom: 60px solid #999999;
    border-left: 30px solid transparent;
    border-right: 70px solid transparent;
}

HTML代码:

<div id="rectangle">
    <span id="circle"></span>
    <span id="triangle"></span>
    <span id="triangle2"></span>
</div>

效果图如下:

Alt text

十八、数组去重,然后使数组元素按降序排序

解析:

在排序的算法中,快速排序是相对比较高效的:

Array.prototype.quickSort = function() {
    if (this.length <= 1) {
        return this;
    } else {
        var leftArray = [],
            rightArray = [],
            num = Math.floor((this.length) / 2),
            middleValue = this.splice(num, 1);
        for (var i = 0; i < this.length; i++) {
            if (this[i] > middleValue) {
                leftArray.push(this[i]);
            } else {
                rightArray.push(this[i]);
            }
        }
        return leftArray.quickSort().concat(middleValue, rightArray.quickSort());
    }
} 对于数组去重,有以下三种方法: 第一种:

Array.prototype.unique1 = function() {
    var newArray = [this[0]];//结果数组
    for (var i = 1; i < this.length; i++) {
        if (newArray.indexOf(this[i]) == -1) {
            newArray.push(this[i]);
        }
    }
    return newArray;
}

第二种:

Array.prototype.unique2 = function() {
    var newArray = [this[0]];
    for (var i = 1; i < this.length; i++) {
        if (this.indexOf(this[i]) == i) {
            newArray.push(this[i]);
        }
    }
    return newArray;
}

第三种:

Array.prototype.unique3 = function() {
        var arrayMap = {},
            newArray = [];
        for (var i = 0; i < this.length; i++) {
            if (!arrayMap[this[i]]) {
                arrayMap[this[i]] = true;
                newArray.push(this[i]);
            }
        }
        return newArray;
    }
//先对数组按降序排序,再去重便可实现题目的要求,这样效率也会高一点:
var newArray = [1, 2, 1, 9, 10, 3, 4, 3, 5, 2, 4, 6, 5, 7, 4, 8, 7, 3, 5, 3];
var nowArray = newArray.quickSort().unique1();
console.log(nowArray);

var newArray = [1, 2, 1, 9, 10, 3, 4, 3, 5, 2, 4, 6, 5, 7, 4, 8, 7, 3, 5, 3];
var nowArray = newArray.quickSort().unique1();
console.log(nowArray);

十九、已知下面一段脚本:

var data = {
    name: 'xiaoming',
    age: '18'
};
var template = "My name is {$name}, my age is {$age}";

写一个函数,实现:

function shenmegui(template, data) {} => My name is xiaoming, my age is 18.

解析:

var data = {
    name: 'xiaoming',
    age: '18'
};
var template = "My name is {$name},my age is {$age}."
function outputTemplate(template, data) {
    var regName = /(\{\$name\})/g;
    var regAge = /(\{\$age\})/g;
    template = template.replace(regName, data.name);
    template = template.replace(regAge, data.age);
    return template;
}
alert(outputTemplate(template, data));

二十、利用闭包,实现点击p时,被点击的p的背景色变为 #EEE

解析:

Javascript代码:

window.onload = function() {
    var pObj = document.getElementsByTagName("p");
    for (var i = 0; i < pObj.length; i++) {
        pObj[i].onclick = (function() {
            return function() {
                this.style.background = "#eee";
            }
        })(i);
    };
}

HTMl代码:

<p>第一个</p>
<p>第二个</p>
<p>第三个</p>
<p>第四个</p>
<p>第五个</p>