美文网首页
JS需要注意的内容

JS需要注意的内容

作者: 殷灬商 | 来源:发表于2016-10-23 22:32 被阅读156次

    最近学生面试比较多,关于JS部分的常见面试问题,做一个简单的总结

    1.变量提升

    JS里的很多代码规则和C,Java等有挺多不同的地方,在C等语言里,变量和函数的时候一定要先定义,然后在使用,如果没按照这个要求来做,会有报错,提示变量没有定义,或者函数不存在,但是在JS里不同,如果先使用变量然后在定义,这种情况下会打印undefined,而不是程序报错,这就是JS里的变量提升

    console.log(a);   // undefined
    var a = 10;  
    

    JS里会把函数和变量的声明提升到最顶部,这样能避免在使用的时候因为变量或者函数不存在而报错,但是JS不会把变量的初始化赋值也进行提升,所以打印的结果是undefined而不是10

    var a;
    console.log(a);
    a = 10;
    

    上述代码就是变量提升的执行过程,附上一个例子

    var a = 10;
       function test(){
        console.log(a); // undefined
        var a = 20;
        console.log(a); // 20
       }
       test();
    

    这是一个最常见的变量提升的面试题,这个问题混淆的地方在函数外面有个变量和函数内的变量重名,函数调用之后,进入到函数test自己的作用域里,var a会提升到函数的顶部,即使重名,也会重新声明,所以第一次打印的时候结果是undefined,接下来进行赋值,所以第二次打印结果是20,理解变量作用域能帮助理解变量提升,但是函数的提升和变量的提升,有稍微不同的地方

    test();
       function test(){
        alert("111");      // 正常调用
       }
       test1();
       var test1 = function(){
        alert("222");   // test1不是一个函数,报错
       }
    

    这两种写法区别就是第二个用一个变量接受了函数,从而提升的时候,还是var test1; 这时test1里的内容还是undefined,所以调用函数的时候会出问题,变量提升只是把变量声明过程进行了提升,函数则会提升函数定义和函数体,所以变量提升更确切讲应该是声明提升

    2.事件冒泡

    事件冒泡是事件触发和传递过程里常见问题,通过最上一层的元素触发事件,会把事件根据结构进行传递,子传父,直到传到document,如果在这个过程里各级元素也绑定了相同的事件,事件也会触发,比如:

    <style type="text/css">
       #fa{
        width: 200px;
        height: 200px;
        background: red;
       }
       #ch{
        width: 100px;
        height: 100px;
        background: blue;
       }
      </style>
    
    <div id="fa">
       <div id="ch">
       </div>
      </div>
    
    <script type="text/javascript">
       var fa = document.getElementById("fa");
       var ch = document.getElementById("ch");
       ch.onclick = function(){
        alert("子元素点击事件触发");
       }
       fa.onclick = function(){
        alert("父元素点击事件触发");
       }
       document.onclick = function(){
        alert("document点击事件触发");
       } 
      </script>
    

    点击蓝色div之后三个点击方法都会触发,这个过程就是事件冒泡,当然了也能阻止事件的传递,有两个方法,event.cancelBubble = true;和event.stopPropagation();,所以要清楚事件传递的顺序

    跟事件冒泡的顺序相反的叫事件捕获,事件先从document开始触发,最后才触发子元素事件,但是使用onclick这种方式没办法设置,只能通过addEventLinster()完成绑定,要把这个方法里的第三个参数设置成true,但是只有父元素设置成true之后,才能使捕获.

    3.事件委托

    不是所有的事件冒泡都是不好的,事件委托就是通过冒泡的过程完成事件的触发.当某个元素内有很多子元素,而且子元素都需要触发相同的事件,可以找到子元素,然后循环绑定事件,但是这种方式虽然可以,但是效率非常低,需要把每个元素都绑定上方法,在这个时候可以使用事件委托来完成.

    ul-li

    如果想所有li都有鼠标移动改背景颜色,可以把事件添加到ul上

    var ul1 = document.getElementById("ul1");
    ul1.onmouseover = function(){
        event.target.style.background = "red";
     }
    ul1.onmouseout = function(){
        event.target.style.background = "";
    }
    

    通过事件冒泡,事件会从li传到ul上,然后ul会触发对应的onmouseout和onmouseover事件,然后通过event,target找到触发事件的标签,也就是li,这样写完,大量的节省了代码,而且当添加了新的li,也不需要为新的li单独添加对象,省时省力,这是利用了事件冒泡,提高代码质量

    4.面向对象

    JS不是纯的面向对象语言,对于大家来讲,面向对象和之前面向过程区别太大,JS里的对象创建有几种,一种是写成JSON对象

    var obj = {
        name:"张三",
        age:20
       }
    

    也可以通过构造函数来创建,能解决批量创建对象

    function Student(name, age){
        this.name = name;
        this.age = age;
        this.eat = function(){
         alert("吃饭");
        }
       }
    

    但是这里面有个比较有特色的东西,就是原型,prototype.每一个通过构造函数创建出来对象,都有一个公共的区域,这个区域里用来定义对象的预定义的属性或者方法.Student.prototype实际上就是一个JSON对象,通过原型添加的元素都会添加到这个对象上,这些原型上的属性和方法共用一块存储空间,节省空间.
    对象的属性和方法由两部分组成,一部分是通过构造函数获得的,另外一部分是通过原型上获得的.所以当使用对象的某个属性的时候,先从构造函数获得的属性中查找,是否有对应属性,如果没有再去原型上查找,如果还没有到Object上去查找,如果Object上还没有,则返回null,这就是原型链

    先总结这些吧

    相关文章

      网友评论

          本文标题:JS需要注意的内容

          本文链接:https://www.haomeiwen.com/subject/wjxkuttx.html