JS长见的问题(变量提升,作用域,事件冒泡,事件委托,面向对象)

2017-06-13  本文已影响0人  wyq_0bed

一、变量提升

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

在JS里不同,如果先使用变量然后在定义,这种情况下会打印undefined,而不是程序报错,这就是JS里的变量提升

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

JS里会把函数和变量的声明提升到最顶部,这样能避免在使用的时候因为变量或者函数不存在而报错,但是JS不会把变量的初始化赋值也进行提升,所以打印的结果是undefined而不是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,所以调用函数的时候会出问题,
!!!!变量提升只是把变量声明过程进行了提升,
!!!!函数则会提升函数定义和函数体,所以变量提升更确切讲应该是声明提升

二、事件冒泡
事件冒泡是事件触发和传递过程里常见问题,通过最上一层的元素触发事件,会把事件根据结构进行传递,子传父,直到传到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();,所以要清楚事件传递的顺序

<div id="div1">div
    <ul id="ul1">ul
        <li id="li1">li
            <a href="" id="a1">a</a>
        </li>
    </ul>
</div>
<script>
    var oUl = document.getElementById('ul1'),
            oLi = document.getElementById('li1'),
            oA = document.getElementById('a1');
   // 以下为支持w3c的浏览器  比如chrome firfox等
    oUl.addEventListener('click',function (){
        alert('ul');
    },true);
    oLi.addEventListener('click',function (){
        alert('li');
    },true);
    oA.addEventListener('click',function (){
        alert('a');
    },true);
</script>

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

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

<ul id="ul">
    <li>0001</li>
    <li>0002</li>
    <li>0003</li>
    <li>0004</li>
</ul>
var ul1 = document.getElementById("ul1");
ul1.onmouseover = function(){
    event.target.style.background = "red";
 }
ul1.onmouseout = function(){
    event.target.style.background = "";
}

四、面向对象
(未完待续)

上一篇下一篇

猜你喜欢

热点阅读