zoukankan      html  css  js  c++  java
  • 前端面试题准备 2

    写博客真是一个好事情,自已花了一天弄了这篇,加深了很多印象。可以时不时复习一下,也希望能够帮助到他人。

    一、HTML5的语义化标签:大概有<header><nav><article><section><aside><footer>,比<div class="">更直观,也方便搜索引擎。

    二、正则,这是一大块,项目中也常用到。(有时用js有时用C#,虽然规则是一样的,但命令常搞混)

    (资料参考:http://blog.csdn.net/zaifendou/article/details/5746988

    http://www.blogjava.net/onejavaer/articles/79070.html

    http://www.jb51.net/article/25313.htm)

    1、exec()

    var regx=/a(d+)(A)c/;
    var result = regx.exec("a123Acddd");
    result

    result是["a123Ac","123","A"] ,其中第一个是匹配到的值,后面两个是括号里的值。

    但console.log(result)却是 ["a123Ac", "123", "A", index: 0, input: "a123Acddd"],有时调试时要注意,不要搞混了

    var regx=/ad+c/;
    var result=regx.exec("a123cddd");

    没有括号,result是["a123c"]

    var regx=/userd/g;
    var rs=regx.exec("ddduser1dsfuser2dd");
    var rs1=regx.exec("ddduser1dsfuser2dd");
    console.log(rs);
    console.log(rs1);

    得到rs1是["user1"],rs2是["user2"]。。。这是个坑,以前都没注意到。

    不符合条件的话,是返回null

    2、test()

    var regx=/userd+/g;
    var flag=regx.test("user12dd");
    console.log(flag);

    得到true,其实用其它方法不符合时就会返回null,就可以判断了,一般都不用专门test()来判断

    ============以上两个是regx的方法,后面的是string的方法,常弄混==============

     3、match()

    var regx=/userd/g;
    var str="user13userddduser345";
    var rs=str.match(regx);
    console.log(rs)

    显示 ["user1", "user3"],这会又没后面那个什么Index,Input了。。。不知为何exec在console.log时会附带那些东西。

    regx加了/g,是显示全部,不加/g是第一个,如果不匹配,是返回null。

    4、search()

    var regx=/userd/g;
    var str="ABCuser13userddduser345";
    var rs=str.search(regx);

    rs是3,如果不符合条件,得到-1。

    和indexOf()非常类似

    var regx=/userd/g;
    var str="ABCuser13userddduser345";
    str.indexOf("user");

    得到的也是3,查不到也是-1。但indexOf()只能查具体的字符串,不能查正则。

     5、replace(expr,str)

    var regx=/user/g
    var str="user13userddduser345";
    var rs=str.replace(regx,"ABC");

    得到rs是"ABC13ABCdddABC345"

    如果不加/g,或直接是字符串"user",则仅替换第一个

    var regx=/user/    //或var regx="user"
    var str="user13userddduser345";
    var rs=str.replace(regx,"ABC");

    得到的都是 "ABC13userddduser345"

    6、split(expr)

    不管是否加/g,或直接是字符串,效果都是一样的。这点和replace有所不同,也是个坑

    var regx=/user/g;    //或 var regx="user"
    var str="user13userddduser345";
    var rs=str.split(regx);

    得到的都是 ["", "13", "ddd", "345"]

    7、转义

    需要转义的有    * . ? + $ ^ [ ] ( ) { } | / 

    8、预定义

    .     IE下[^ ],其它[^ ] 匹配除换行符之外的任何一个字符 
    d     [0-9] 匹配数字 
    D     [^0-9] 匹配非数字字符 
    s     [ fx0B] 匹配一个空白字符 
    S     [^ fx0B] 匹配一个非空白字符 
    w     [a-zA-Z0-9_] 匹配字母数字和下划线 
    W     [^a-zA-Z0-9_] 匹配除字母数字下划线之外的字符 

    9、/g是全局,/i是忽略大小写,/m是多行查找。

    另有RegExp.$n (n为1~99),表示第几个匹配项

    var r = /(d+)-(w+)/;
    var b=r.exec("1234-abcd-b");
    console.log(RegExp.$1+"~"+RegExp.$2);
    
    b = r.test("1234-abcd");
    console.log(RegExp.$1+"~"+RegExp.$2);

    得到的均为  1234~abcd

    10、匹配方式

    *是零次或多次,+是一次或多次,?是零次或一次,而且在量词后面加?就变成惰性模式,即匹配尽量少(默认是贪婪模式,即匹配尽量多)。

    var str = "abc"; 
    var re = /w+/; //将匹配abc
    var result = re.exec(str)
    console.log(result)
    
    re = /w+?/;//将匹配a
    result = re.exec(str)
    console.log(result)

    基本上就这些,其它高级用法一时也没法列全,在项目中可以边试边用,面试时这些应该就差不多了。

    三、原型,扩展原型方法,项目中有用过String.Format(),就是像C#的string.Format("xxx{0}",str)一样用法。

    if (!String.prototype.format) {
        String.prototype.format = function () {
            var args = arguments;
            return this.replace(/{(d+)}/g, function (match, number) {
                return typeof args[number] != 'undefined' ? args[number] : match;
            });
        };
    }

     

    四、阻止冒泡:preventDefault(阻止事件默认行为)、stopPropagation(阻止冒泡)、return false(相当于前面两个都执行)。

    五、兼容

    var e = window.event || evt;
    var tag = e.target || e.srcElement;
    var keyCode = evt.keyCode || evt.which;

    判断浏览器(顺序不能错)就记住关键词window.navigator.userAgent,然后顺序IE、火狐、谷歌、欧朋、苹果

    function getExplorer() {
        var explorer = window.navigator.userAgent ;
        if (explorer.indexOf("MSIE") != -1) {
            console.log("ie");
        }
        else if (explorer.indexOf("Firefox") != -1) {
            console.log("Firefox");
        }
        else if(explorer.indexOf("Chrome") != -1){
            console.log("Chrome");
        }
        else if(explorer.indexOf("Opera") != -1){
            console.log("Opera");
        }
        else if(explorer.indexOf("Safari") != -1){
            console.log("Safari");
        }
    }

    六、作用域(配合this、闭包),经常有坑,一般是function声明会提到最前,且function内部有定义变量的,就不会再去找上一级,但是定义的变量又未执行到,还是undefined

    http://mianshiti.diandian.com/post/2013-04-05/40048538140这一题比较有代表性

    var foo = 'hello';
    (function() {
      var foo = foo || 'world';
      console.log(foo);
    })();
    //显示world
    
    var foo = 'hello';
    (function() {
      console.log(foo);
      var foo = foo || 'world';
    })();
    //显示undefined
    
    var foo = 'hello';
    (function(f) {
      var foo = f || 'world';
      console.log(foo);
    })(foo);
    //显示hello
    var i=9;
    function fo(){
        var i=0;
        return function(n){
            return n+(++i);
        }
    };
    var f=fo();
    
    var a = f(15);console.log(a)
    var b = fo()(15); console.log(b)
    var c = fo()(20); console.log(c)
    var d = f(20);console.log(d)

    分别得到16 16 21 22

     珠峰有一题比较复杂  http://www.iqiyi.com/w_19rr1au1fh.html

    var number=2;
    var obj={
        number:4,
        fn1:(function(){
            this.number *= 2;
            number=number*2;
            var number=3;
            return function(){
                this.number *= 2;
                number *= 3;
                console.log("inside:"+number);
            }
        })(),
        db2:function(){this.number *= 2}
    };
    console.log("Only Define,number is:"+number);
    var fn1=obj.fn1;
    console.log("After Assign,number is:"+number);
    console.log("Run fn1():");
    fn1();
    console.log("After Run fn1(),number is:"+number);
    console.log("Run obj.fn1():");
    obj.fn1();
    console.log("After Run obj.fn1(),number is:"+number);
    console.log("window.number is:"+window.number);
    console.log("obj.number is:"+obj.number)

    Only Define,number is:4  //在定义中,fn1的方法是立即执行的(function(){})(),里面的this.number,是执行时的window,所以window.number*2 = 4
    After Assign,number is:4  //赋值只是引用对象一下,不改变什么
    Run fn1():
    inside:9  //fn1() ->obj.fn1() ->执行闭包里面的函数,里面的number就是上一级的 var number = 3,所以最后是3*3==9
    After Run fn1(),number is:8  //这时的window.number,在一开始已经变成4了,再执行一次,又*2,变成8了
    Run obj.fn1():
    27  //和前面的fn1()是一样的,相当于再执行一次,而闭包不释放,上次又经是9了,再*3=27
    After Run obj.fn1(),number is:8
    window.number is:8
    obj.number is:8

    有些难搞懂,要配合下面这个再测一下 ,为了不混淆,把各参数都改成质数,虽然数字看着有些大,但能弄清问题实际

    var number=3;
    var obj={
        number:5,
        fn1:(function(){
            this.number *= 7; console.log("this.number *= 7,this.number="+this.number);console.log(this)
            number=number*11; console.log("number=number*11;,number="+number);
            var number=13;
            return function(){
                this.number *= 17; console.log("this.number *= 17,this.number="+this.number); console.log(this)
                number *= 19; console.log("number *= 19,number="+number);
                console.log("inside:"+number);
            }
        })(),
        db2:function(){this.number *= 23;  console.log("this.number *= 23,this.number="+this.number);}
    };
    console.log("var fn1=obj.fn1;");
    var fn1=obj.fn1;
    console.log("obj.fn1();")
    obj.fn1();
    console.log("obj.fn1() 1times, number is:"+number);
    console.log("obj.fn1() 1times, obj.number is:"+obj.number);
    obj.fn1();
    console.log("obj.fn1() 2times, number is:"+number);
    console.log("obj.fn1() 2times, obj.number is:"+obj.number);
    obj.fn1();
    console.log("obj.fn1() 3times, number is:"+number);
    console.log("obj.fn1() 3times, obj.number is:"+obj.number);
    fn1();
    console.log("fn1() 1times, number is:"+number);
    console.log("fn1() 1times, obj.number is:"+obj.number);
    fn1();
    console.log("fn1() 2times, number is:"+number);
    console.log("fn1() 2times, obj.number is:"+obj.number);
    fn1();
    console.log("fn1() 3times, number is:"+number);
    console.log("fn1() 3times, obj.number is:"+obj.number);

    this.number *= 7,this.number=21
    Window {top: Window, location: Location, document: document, window: Window, external: Object…}
    number=number*11;,number=NaN

    此时是仅定义时输出的。因为是(function(){})()这种直接执行的形式,所以定义时就执行了。以后都是执行return里面的返回值。

    此时的this指向window,把全局的number变成3*7=21了。而number=number*11,此时的number在fn1中有定义var number=13,但未执行到,所以此时还是undefined(这是个坑)

    ===================

    var fn1=obj.fn1; //仅是引用赋值,未引发输出


    obj.fn1();  //执行obj.fn1()
    this.number *= 17,this.number=85
    Object {number: 85}db2: ()fn1: ()number: 24565__proto__: Object
    number *= 19,number=247
    inside:247

    此时的this指向obj,obj.number=5,所以obj.number ->5*17=85。

    而number会去找上下文,发现obj.fn1有定义var number=13,所以number*=19   ->  13*19=247


    obj.fn1() 1times, number is:21
    obj.fn1() 1times, obj.number is:85

    所以此时输出全局number是21,obj.number是85

    ===================

    //第二次执行
    this.number *= 17,this.number=1445
    Object {number: 1445}
    number *= 19,number=4693
    inside:4693

    同理this依然指向obj,而上一次obj.number已经变成85了,所以此次85*17=1445

    number继续是obj.fn1.number,所以number  -> 247*19=4693
    obj.fn1() 2times, number is:21
    obj.fn1() 2times, obj.number is:1445

    全局number=21一直没变

    //第三次执行,和前两次一样分析即可
    this.number *= 17,this.number=24565
    Object {number: 24565}
    number *= 19,number=89167
    inside:89167
    obj.fn1() 3times, number is:21
    obj.fn1() 3times, obj.number is:24565

    //第一次执行fn1()
    this.number *= 17,this.number=357
    Window {top: Window, location: Location, document: document, window: Window, external: Object…}
    number *= 19,number=1694173
    inside:1694173

    this指向了window,这也是个坑。所以window.number  ->21*17=357,而obj.number就不会再变化了。
    fn1() 1times, number is:357
    fn1() 1times, obj.number is:24565

    //第二次执行fn1()
    this.number *= 17,this.number=6069
    Window {top: Window, location: Location, document: document, window: Window, external: Object…}
    number *= 19,number=32189287
    inside:32189287

    主要就是this指向了window,现在this.number就是window.number。而内部的number一直是*19
    fn1() 2times, number is:6069
    fn1() 2times, obj.number is:24565

    //第三次执行fn1(),和前两次一样分析即可
    this.number *= 17,this.number=103173
    Window {top: Window, location: Location, document: document, window: Window, external: Object…}
    number *= 19,number=611596453
    inside:611596453
    fn1() 3times, number is:103173
    fn1() 3times, obj.number is:24565

    这题比较绕,能搞清楚的话,就把闭包、作用域之类的全搞懂了,关键是fn1()指向了window。也不知道我理解的对不对,暂时先这样吧。

     

    七、符号在html中表现

    <    &lt;
    
    >    &gt;
    
    &    &amp;
    
    "    &quot;
    
    空格    &nbsp;

    八、js异步加载(而不是在页头直接引用,增加页面载入速度)

    function loadScript(url,callback){
        var script=document.creatElement("script");
        script.type="text/javascript";
        if(script.readyState){
            script.onreadystatechange=function(){
                if(script.readyState=="loaded"||script.readyState=="complete"){
                    script.onreadystatechange=null;
                    callback();
                }
            }
        }else{
            script.onload=function(){
                callback();
            }
        }
        script.src=url;
        document.getElementsByName("head")[0].appendChild(script);
    }
        1.直接document.write");
            <script>
            document.write("<script src="test.js"></script>");
            </script>
    
         2.动态改变已有script的src属性
            <script src="" id="s1"><script>
            <script>
            s1.src="test.js"
            </script>
         3.动态创建script元素
            <script>
            var oHead=document.getElementsByTagName("HEAD").item(0);
            var oScript=document.createElement("script");
            oScript.type="text/javascript";
            oScript.src="test.js";
            oHead.appendChild(oScript);
           </script>

     

  • 相关阅读:
    相机篇
    ValueAnimator动画跳过中间过程的问题
    android 双向文字问题
    android让xml布局的底部跟随软键盘
    给fragment设置进入和退出动画
    android布局控件的LayoutParams
    注意点
    关于与条件判断中的顺序
    栈的反转
    从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/liuyouying/p/5023308.html
Copyright © 2011-2022 走看看