资讯专栏INFORMATION COLUMN

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

afishhhhh / 3137人阅读

摘要:题目来源数组去重两个循环思路新建一个新数组用于存放重复的数组元素,通过两个循环,比较两个数组元素是否相同。设置或获取与关联的端口号码。设置或获取的协议部分。很容易看出规律,从第三个数字开始,每个数字等于前两个数字之和。

  

题目来源: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

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,使 fthis 指向指定的对象
输入: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的,由小写字母和数字任意组合组成的字符串结尾。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85805.html

相关文章

  • 前端开发-从入门到Offer - 收藏集 - 掘金

    摘要:一些知识点有哪些方法方法前端从入门菜鸟到实践老司机所需要的资料与指南合集前端掘金前端从入门菜鸟到实践老司机所需要的资料与指南合集归属于笔者的前端入门与最佳实践。 工欲善其事必先利其器-前端实习简历篇 - 掘金 有幸认识很多在大厂工作的学长,在春招正式开始前为我提供很多内部推荐的机会,非常感谢他们对我的帮助。现在就要去北京了,对第一份正式的实习工作也充满期待,也希望把自己遇到的一些问题和...

    sf_wangchong 评论0 收藏0
  • 前端该如何准备数据结构和算法?

    摘要:很多前端同学在看到数据结构和算法后会有一定的抵触心理,或者尝试去练习,但是被难倒,从而放弃。本文选择的数据结构和算法的类别均是出现频率最高,以及应用最广的类别。面试这是非常现实的一点,也是很多前端学习数据结构和算法的原因。 一、导读 据我了解,前端程序员有相当一部分对数据结构和算法的基础概念都不是很清晰,这直接导致很多人在看到有关这部分的内容就会望而却步。 实际上,当你了解了数据结构和...

    simon_chen 评论0 收藏0
  • 进攻即是最好的防御!19个练习黑客技术的在线网站

    摘要:进攻即是最好的防御个练习黑客技术的在线网站进攻即是最好的防御,这句话同样适用于信息安全的世界。社区有接近万的注册会员也是最大的一个黑客社区之一。 进攻即是最好的防御!19个练习黑客技术的在线网站 进攻即是最好的防御,这句话同样适用于信息安全的世界。这里罗列了19个合法的来练习黑客技术的网站,不管你是一名开发人员、安全工程师、代码审计师、渗透测试人员,通过不断的练习才能让你成为一个优秀安...

    tracy 评论0 收藏0
  • 大厂难进?(来自双非 非科班 应届生的自述信)

    摘要:关于自己届毕业生一本双非学校,非科班可能和很多人一样,因为小时候喜欢打游戏,所以大学一直想学编程,但因为种种原因,自己来到了一个硬件相关专业,但由于现实和兴趣,自己又从事了软件相关的工作。找实习实习对于之后的秋招来说,是非常非常重要的。 ...

    jerryloveemily 评论0 收藏1
  • 在线编程练习实践网站

    摘要:在此收集一些自己遇到的一些在线练习的网站,当然大部分是。建议边学习边编程,学习编程是不能光看不实践的。国外的一个练习网站,有,也有,每种语言都有自己的道场,每个用户都有不同的等级,刷题提高等级,也可以插卡别人优秀的解决方案。 在学习的过程中会发现很多知识点如果不在工作中运用或者手写带验证的话,很容易忘记。任何技能的掌握都是需要不断练习的。在此收集一些自己遇到的一些在线练习的网站,当然大...

    huhud 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<