[ 题目练习 ] 前端技能练习1

题目来源:http://www.nowcoder.com/ta/front-end

1.数组去重

1.两个循环:

思路: 新建一个新数组用于存放重复的数组元素,通过两个循环,比较两个数组元素是否相同。外循环控制第一个比较元素,内循环控制第二个比较元素,如果有重复元素则将该元素添加到新数组中,最后返回这个新数组。
实现:

Array.prototype.distinct = function() {
    var ret = [];
    for (var i = 0; i < this.length; i++)
    {
        for (var j = i+1; j < this.length;) {
            if (this[i] === this[j]) {
                ret.push(this.splice(j, 1)[0]);
            } else {
                j++;
            }
        }
    }
     return ret;
};
//for test
alert([‘a‘,‘b‘,‘c‘,‘d‘,‘b‘,‘a‘,‘e‘].distinct());

2.一次循环

思路:创建一个空对象的和空数组,通过循环,将原数组中的每个元素的值作为键值对添加到控对象中,如果这个对象中已经存在该属性,则说明这个数组元素是重复的,则将他添加到空数组中,最后返回新创建的数组。
实现:

Array.prototype.distinct=function(){
    var arr=[];
    var obj={};
    for(var i=0;i<this.length;i++){
        if(obj[this[i]]==undefined)
            obj[this[i]]=this[i];
        else if(obj[this[i]])
            arr.push(this[i]);
    }
    return arr;
 }
alert([‘a‘,‘b‘,‘c‘,‘d‘,‘b‘,‘a‘,‘e‘].distinct());

2.dom 节点查找

描述:查找两个节点的最近的一个共同父节点,可以包括节点自身
思路:

有两个dom的节点,dom1,dom2
1.判断dom1节点是否包含dom2节点;包含则返回dom1,不包含继续向下运行;
2.判断dom2节点是否包含dom1节点;包含则返回dom2,不包含继续向下运行;
3.通过其中一个节点dom1去获取该节点的父节点,dom_p;
4.通过父节点dom_p去查dom_f的子节点,看dom2是否在父节点dom_f的子节点中;
5.如果dom2在dom_f的子节点中,则dom_f是最近的父节点;
6.如dom2不在dom_f的子节点中,则以domf_f继续去查dom_f的父节点,重复1,2,3,4步骤最终得出父节点dom_f

实现1:

function commonParentNode(oNode1, oNode2) {
    if(oNode1.contains(oNode2)){
        return oNode1;
    }else if(oNode2.contains(oNode1)){
        return oNode2;
    }else{
        return commonParentNode(oNode1.parentNode,oNode2);
    }
}

实现2:

function commonParentNode(oNode1, oNode2) {
    if(oNode2.contains(oNode1)) return oNode2;
    while(oNode1) {
        if(oNode1.contains(oNode2)){
            return oNode1;
        }
        oNode1 = oNode1.parentNode;
    }
}

3.URL相关

描述:

获取 url 中的参数
1. 指定参数名称,返回该参数的值 或者 空字符串
2. 不指定参数名称,返回全部的参数对象 或者 {}
3. 如果存在多个同名参数,则返回数组
输入:
getUrlParam(‘http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe‘, ‘key‘)

输出:
[‘1‘, ‘2‘, ‘3‘]

实现:

function getUrlParam(sUrl, sKey) {

    var r = [] , s = null  , i = 0;
    var regexp = new RegExp(/[?&]([\w]*)=([^&#]*)/g);

    while((s = regexp.exec(sUrl)) != null){
        if(!r[s[1]])r[s[1]] = s[2];
        else if(typeof(r[s[1]]) == ‘object‘){
            r[s[1]].push(s[2]);
        }else{
            r[s[1]] = [r[s[1]],s[2]];
        }
    }
    if(sKey){
        //有参数,返回参数值或空
        if(r[sKey]){
            return r[sKey];
        }else{
            return ‘‘;
        }
    }else{
        return r;
    }
}

扩展:

1.window.location属性相关:

  • 设置或获取对象指定的文件名或路径。
    alert(window.location.pathname);
  • 设置或获取整个 URL 为字符串。
    alert(window.location.href);
  • 设置或获取与 URL 关联的端口号码。
    alert(window.location.port);
  • 设置或获取 URL 的协议部分。
    alert(window.location.protocol);
  • 设置或获取 href 属性中在井号“#”后面的分段。
    alert(window.location.hash);
  • 设置或获取 location 或 URL 的 hostname 和 port 号码。
    alert(window.location.host);
  • 设置或获取 href 属性中跟在问号后面的部分。
    alert(window.location.search);

2.其他的获取url参数的方法:

方式一:只能对固定url进行操作,返回全部参数

function GetRequest() {
var url = location.search; //获取url中"?"符后的字串
var theRequest = new Object();
if (url.indexOf("?") != -1) {
  var str = url.substr(1);
  strs = str.split("&");
  for(var i = 0; i < strs.length; i ++) {
     theRequest[strs[i].split("=")[0]]=(strs[i].split("=")[1]);
  }
}
 return theRequest;
}

方式二:正则表达式方式,只能对固定url操作,返回指定参数

function GetQueryString(name) {
   var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)","i");
   var r = window.location.search.substr(1).match(reg);
   if (r!=null) return (r[2]); return null;
}

方式三:对任意的url操作,返回指定数量的参数

function getUrlParames(url,keys){

    var request = {},
        result,
        parameStr = ‘‘,
        parames = [],
        keyValue = [],
        index = url.indexOf(‘?‘);

    if (index) {
        parameStr = url.substr(index+1);
        parames = parameStr.split("&");
        for(var i = 0, lng = parames.length; i < lng; i ++) {
            keyValue = parames[i].split("=");
            request[keyValue[0]] = keyValue[1];
      }
    }

    if (typeof keys == ‘string‘) {
        result = request[keys];
    }else if(!keys){
        return request;
    }
    else{

        result = {};
        for(var j = 0,lng = keys.length;j < lng;j++){
            result[keys[j]] = request[keys[j]];
        }
    }

    return result;
}

4:修改 this 指向

描述:
封装函数 f,使 f 的 this 指向指定的对象
输入:bindThis(function(a, b){return this.test + a + b}, {test: 1})(2, 3)
输出:6
思路:
我们可以观察到
1.bindThis这个函数接受两个参数,第一个参数为执行函数,第二个参数是要指定的对象。
2.bindThis函数返回一个匿名函数

实现:

function bindThis(f, oTarget) {
    return function(){
        var parames = Array.prototype.slice.call(arguments);
        return f.apply(oTarget,parames); //注意这里需要返回f的执行结果
    }
}

5.根据包名,在指定空间中创建对象

描述:
根据包名,在指定空间中创建对象 :
输入:namespace({a: {test: 1, b: 2}}, ‘a.b.c.d‘)
输出:{a: {test: 1, b: {c: {d: {}}}}}

思路:
namespace函数的第一个参数是原始对象,第二个参数是需要创建的对象的包含关系。
通过输出结果可以看出,如果第二个参数中的对象在原始对象中存在并且是它的值为一个对象则不做改变,若不为对象,则重新赋值为空对象{}.

实现:

function namespace(oNamespace, sPackage) {

    var properties = sPackage.split(‘.‘);
    var parent = oNamespace;

    for (var i = 0, lng = properties.length; i < lng; ++i) {

        var property = properties[i];

        if (Object.prototype.toString.call(parent[property])!== ‘[object Object]‘) {
            parent[property] = {};
        }

        parent = parent[property];

    }

    return oNamespace;

}

6.斐波那契数列

描述:

什么是斐波那契数列:1,1,2,3,5....n 。很容易看出规律,从第三个数字开始,每个数字等于前两个数字之和。

思路:

1.前两个数字都为 1
2.使用递归

实现:

function fibonacci(n) {
    if(n ==1 || n == 2){
        return 1
    }
    return fibonacci(n - 1) + fibonacci(n - 2);
}

7.时间格式化输出

描述:

按所给的时间格式输出指定的时间
格式说明
对于 2014.09.05 13:14:20
yyyy: 年份,2014
yy: 年份,14
MM: 月份,补满两位,09
M: 月份, 9
dd: 日期,补满两位,05
d: 日期, 5
HH: 24制小时,补满两位,13
H: 24制小时,13
hh: 12制小时,补满两位,01
h: 12制小时,1
mm: 分钟,补满两位,14
m: 分钟,14
ss: 秒,补满两位,20
s: 秒,20
w: 星期,为 [‘日‘, ‘一‘, ‘二‘, ‘三‘, ‘四‘, ‘五‘, ‘六‘] 中的某一个,本 demo 结果为 五
输入例子:
formatDate(new Date(1409894060000), ‘yyyy-MM-dd HH:mm:ss 星期w‘)

输出例子:
2014-09-05 13:14:20 星期五

实现:

function formatDate(oDate, sFormation) {
    var obj = {
        yyyy:oDate.getFullYear(),
        yy:(""+ oDate.getFullYear()).slice(-2),//非常精辟的方法
        M:oDate.getMonth()+1,
        MM:("0"+ (oDate.getMonth()+1)).slice(-2),
        d:oDate.getDate(),
        dd:("0" + oDate.getDate()).slice(-2),
        H:oDate.getHours(),
        HH:("0" + oDate.getHours()).slice(-2),
        h:oDate.getHours() % 12,
        hh:("0"+oDate.getHours() % 12).slice(-2),
        m:oDate.getMinutes(),
        mm:("0" + oDate.getMinutes()).slice(-2),
        s:oDate.getSeconds(),
        ss:("0" + oDate.getSeconds()).slice(-2),
        w:[‘日‘, ‘一‘, ‘二‘, ‘三‘, ‘四‘, ‘五‘, ‘六‘][oDate.getDay()]
    };
    return sFormation.replace(/([a-z]+)/ig,function($1){return obj[$1]});
}

8.获取字符串的长度

描述:

如果第二个参数 bUnicode255For1 === true,则所有字符长度为 1
否则如果字符 Unicode 编码 > 255 则长度为 2
输入例子:

strLength(‘hello world, 牛客‘, false)

输出例子:
17

实现:

function strLength(s, bUnicode255For1) {

    if(bUnicode255For1) return s.length;

    var length = s.length;
    for(var i = 0, lng = length; i < lng; i++){
        if(s.charCodeAt(i)>255){
            length ++;
        }
    }
    return length;
}

9.邮箱字符串判断

描述:

判断输入是否是正确的邮箱格式
输入: 邮箱字符串
输出: true表示格式正确,false表示错误

实现:

function isAvailableEmail(sEmail) {
    var parter = /^[a-z0-9_+.-]+\@([a-z0-9-]+\.)+[a-z0-9]{2,4}$/;
    return parter.test(sEmail);
}

这题的关键是理解这个正则表达式,我们拆开来看看:

1.^[a-z0-9_+.-]+ : 这个表示以一个或多个小写字母,数字或_,+,.,-这几个个字符开头

2.\@([a-z0-9-]+\.)+ : 这个表示1中的字符连着@,后面再接着一个多个由小写字母,数字,-字符和点.的组成的字符串。

3.[a-z0-9]{2,4}$ 这个比较简单,表示以长度为2-4的,由小写字母和数字任意组合组成的字符串结尾。

时间: 2024-10-14 16:29:57

[ 题目练习 ] 前端技能练习1的相关文章

第三次作业-前端与后台数据交换问题

问题:JS前端取得并解析后台服务器返回的JSON数据方法有哪些? 前一段时间,我在做一个有关美食的Web App,很多商家的店铺信息以及一些用户评论信息等内容需要从后台来获取,如果仅仅只是静态布局的话就太过于死板,但是在进行前端与后端的数据交换时遇到不少问题,如题目JS前端取得并解析后台服务器返回的JSON数据的方法就是问题之一. 在解决这个问题之前,首先需要了解JavaScript eval()函数,eval(string)函数可计算某个字符串,并执行其中JavaScript代码. JS前端取

4/13 收获满意offer!

今天是来到北京第二天.之前一直在想,到底什么样的offer能让我满意,或者我想要的工作是什么样的,但都没有一个大概的轮廓. 昨天下午.今天上午.今天下午,来了一天半,面了三场,各有感觉.第一场地理位置很靠前,在朝阳门附近,足证公司实力,进入公司,感觉到每个人都很严谨地工作,前台接待态度也非常好,一直到做笔试题之前,感觉都非常良好,但是因为笔试题的原因,我被PASS掉了,当然,我更愿意认为是其对算法的不理解导致我将其PASS掉的,也算是给自己一点心理安慰,后来也发现确实语法部分有所欠缺,在此不再赘

网易云课堂微专业 学习列表

页面制作 课程学习指南 <web前端开发实践>的大作业题目 Photoshop切图 工具.面板.视图 测量.取色 切图 保存 修改.维护 图片优化与合并 Photoshop切图的单元测试(作业) 开发.调试工具 开发调试工具 HTML HTML简介 标签 实体字符 HTML的单元测试(作业) HTML的单元作业(作业) CSS CSS简介 选择器 文本 盒模型 背景 布局 变形 动画 CSS的单元测试 CSS的单元作业 JavaScript程序设计 课程学习指南 <web前端开发实践&g

backend alpha review

[Backend] Alpha Review展示博客 团队成员介绍:仅限于Alpha阶段有贡献的成员. 典型场景描述:描述并说明你们认为的产品面向的典型场景. 团队管理与协作:包括但不限于团队内部如何协作,与其他团队如何协作,如何使用源代码管理工具,各成员工作量分配等. 项目质量控制:包括但不限于项目各方面(场景符合度,代码规范,测试,文档)的质量评估,开发中如何控制项目质量,燃尽图走势,代码签入统计等. 技术细节介绍:包括但不限于技术框架,技术难点(可以是算法上的,也可以是数据库设计等),独到

[极客大挑战]PHP——目录泄露+反序列化

考点:目录泄露+PHP反序列化 题目一览 拿到题目,前端是个逗猫游戏 源码也没什么东西,先dirsearch跑一遍,这里设置下delay,防止频率过快被报429: 发现备份文件,打开发现源码: 分析 index.php: <?php include 'class.php'; $select = $_GET['select']; $res=unserialize(@$select); ?> class.php: ?php include 'flag.php'; error_reporting(0

[转]关于Web前端开发,附:(百度web前端笔试面试题目)

关于Web前端及百度web前端笔试面试题目 随着各大互联网公司设立了Web前端开发工程师.设计工程师等职位,web前端越来越得到互联网企业的认可.而且其重视程度与地位也随着浏览器 端的富客户端的体现而日益提高. 眼前对HTML5的未来和走向,业内的预测是会和Flash.Silverlight等相结合,从而取代传统的客户端应用程序.而实现这个目标的客户端核 心工作是有Web前端工程师来完成的. 从另一个角度,对于web产品来说,交互和用户体验是产品的第一价值,这部分价值的体现就是在web前端.可以

有趣的前端题目,看了不懊悔

今天在前端群里面和群友讨论了一下几道自己遇过的前端题目.尽管是小题目,可是还是挺好玩.所以今天还是写下来,和大家分享一下. 1.一道大概4年前遇到的题目,知识点简单,可是新鲜又好玩. 题目:有一个div 宽和高都是250px. 仅仅要往div里面加随意的四个div,里面的div宽和高都会是原来50%.分别在左右上下:随意加div.就会向四个角延伸. 同一时候.整个div是垂直水平居中浏览器. 例如以下图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvb

有趣的前端题目,看了不后悔

今天在前端群里面和群友讨论了一下几道自己遇过的前端题目,虽然是小题目,但是还是挺好玩.所以今天还是写下来,和大家分享一下. 1.一道大概4年前遇到的题目,知识点简单,但是新奇又好玩. 题目:有一个div 宽和高都是250px: 只要往div里面加任意的四个div,里面的div宽和高都会是原来50%,分别在左右上下:任意加div,就会向四个角延伸.同时,整个div是垂直水平居中浏览器. 如下图 图解:任意添加div,就分别向4个角延伸 下面是出代码,想试试的同学记得先不看代码啦. <!doctyp

2017年五月前端面试题目的总结

持续心累的找工作阶段算是结束了,不同公司对面试的知识侧重点不同,整体的感受就是:大公司可能更偏向一些JS基础或者原理.html布局.一些经典算法方面.小公司的面试更加侧重对经验和细节的把握,或者说是偏向于解决问题层面的比如说给你一个场景用你的一些想法来解决问题.现将我在面试过程遇到的问题总结下.目前先传题目答案整理好之后再发布出来. html.css 1.CSS中绝对定位和相对定位的文档流是怎样的 以及他们是如何使用的?2.margin.padding属性值存在一个 两个 三个 四个的情况下分别