DOM

Window对象:

所有浏览器都支持 window 对象。
概念上讲.一个html文档对应一个window对象.
功能上讲: 控制浏览器窗口的.
使用上讲: window对象不需要创建对象,直接使用即可.

 Window 对象方法

alert()            显示带有一段消息和一个确认按钮的警告框。
confirm()          显示带有一段消息以及确认按钮和取消按钮的对话框。
prompt()           显示可提示用户输入的对话框。

open()             打开一个新的浏览器窗口或查找一个已命名的窗口。
close()            关闭浏览器窗口。
setInterval() 按照指定的周期(以毫秒计)来调用函数或计算表达式。 clearInterval() 取消由 setInterval() 设置的 timeout。 setTimeout() 在指定的毫秒数后调用函数或计算表达式。 clearTimeout() 取消由 setTimeout() 方法设置的 timeout。 scrollTo() 把内容滚动到指定的坐标。

方法使用

1、alert、confirm、prompt、open:

alert('I can do it!')
var flag= confirm('Are you sure?');
console.log(flag); //确定:True;取消:false

//获取年龄
function getAge(){
    var age = prompt('How old are you?');

    if(isNaN(age))
    {
        alert('that"is not Number');
        getAge();
    }
    else if(age >=18){
         alert('恭喜你已成年!玩的愉快!');
         // open参数:open(url,windowName,windowSize)
         open('http://www.xiaohuar.com','new','height=800,width=800')
    }
    else{
        alert('哥们你还是未成年啊!');
    }
}
执行
getAge();

2、setInterval,clearInterval

setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。

语法:
setInterval(函数,时间(毫秒))

示例:

<input id="ID1" type="text" onclick="begin()">
<button onclick="end()">停止</button>

<script>
    function showTime(){
           var nowd2=new Date().toLocaleString();
           var temp=document.getElementById("ID1");
           temp.value=nowd2;

    }
    var ID;
    function begin(){
        if (ID==undefined){
             showTime();
             ID=setInterval(showTime,1000);
        }
    }
    function end(){
        clearInterval(ID);
        ID=undefined;


    }
</script>

 DOM 对象

  • HTML  Document Object Model(文档对象模型).
  • HTML DOM 定义了访问和操作HTML文档的标准方法。
  • HTML DOM 把 HTML 文档呈现为带有元素、属性和文本的树结构(节点树)。

DOM树:

 画dom树是为了展示文档中各个对象之间的关系,用于对象的导航

 Dom节点:

HTML 文档中的每个成分都是一个节点。

DOM 是这样规定的:
    整个文档是一个文档节点 
    每个 HTML 标签是一个元素节点 
    包含在 HTML 元素中的文本是文本节点 
    每一个 HTML 属性是一个属性节点

 

其中,document与element节点是重点。

 节点关系:

节点树中的节点彼此拥有层级关系。
父(parent),子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。

  •     在节点树中,顶端节点被称为根(root):<html>
  •     每个节点都有父节点、除了根(它没有父节点)
  •     一个节点可拥有任意数量的子节点
  •     同胞是拥有相同父节点的节点

下面的图片展示了节点树的一部分,以及节点之间的关系:

访问 HTML 元素(节点),访问 HTML 元素等同于访问节点,我们能够以不同的方式来访问 HTML 元素。

节点查找

直接查找节点:

注意:涉及到寻找元素,注意<script>标签的位置,最好将Script标签放到html最后或者将标签中的内容封装成函数(防止渲染之前获取元素)。

document.getElementById(“idname”) 
document.getElementsByTagName(“tagname”)
document.getElementsByName(“name”)
document.getElementsByClassName(“name”)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .button{
            background-color: lightseagreen;
            font-size: 20px;
        }
    </style>

</head>
<body>
    
    <button class="button" onclick="change()">更改搜索</button>
    <div>
        通过tag找到标签
        <a href="http://www.sogou.com" id="sogou">搜索一下</a>
        <span name="s">通过name获取标签</span>
    </div>


</body>
<script>
    //更改超链接标签的内容
    function change() {
        //通过id获取标签a
        var a1 = document.getElementById('sogou');
        a1.href = 'http://www.baidu.com';
        var font = a1.getElementsByTagName('font')[0];
        font.innerHTML = '百度一下';
        
        //通过class获取相同class名称的标签列表,获取第一个button,更改其中的文字
        var button_1 = document.getElementsByClassName('button')[0];
        button_1.innerText='停止';
        
    }
    //通过tag获取
    var div_1 = document.getElementsByTagName('div')[0];
    console.log(div_1)
    
</script>
</html>

导航节点属性:

'''
parentElement // 父节点标签元素
children // 所有子标签
firstElementChild // 第一个子标签元素
lastElementChild // 最后一个子标签元素
nextElementtSibling // 下一个兄弟标签元素
previousElementSibling // 上一个兄弟标签元素 '''

注意,js中没有办法找到所有的兄弟标签!

节点操作

创建节点:

createElement(标签名) :创建一个指定名称的元素。
var  tag=document.createElement(“input")
tag.setAttribute('type','text');

添加节点:

追加一个子节点(作为最后的子节点)
somenode.appendChild(newnode)

把增加的节点放到某个节点的前边
somenode.insertBefore(newnode,某个节点);

删除节点:

somenode.removeChild(某个节点):通过父元素调用删除节点

替换节点:

somenode.replaceChild(newnode, 某个节点);

节点属性操作:

1、获取文本节点的值:innerText、innerHTML

2、attribute操作

     elementNode.setAttribute(name,value)    

     elementNode.getAttribute(属性名)

     elementNode.removeAttribute(“属性名”);

3、value-获取当前选中的value值:
        1.input
        2.select (selectedIndex 获取当前所选标签的index,然后通过children获取option集合来操作。)
        3.textarea  
4、innerHTML 给节点添加html代码:
        该方法不是w3c的标准,但是主流浏览器支持    
        tag.innerHTML = “<p>要显示内容</p>”;  - 赋值的时候也可以赋值标签

5、关于class的操作:

elementNode.className  -获取当前元素class的值
elementNode.classList -获取当前元素class的列表 elementNode.classList.add elementNode.classList.remove

 6、改变css样式:

<p id="p2">Hello world!</p>
document.getElementById("p2").style.color="blue";
                             .style.fontSize=48px;

DOM Event(事件)

onclick        当用户点击某个对象时调用的事件句柄。
ondblclick     当用户双击某个对象时调用的事件句柄。

onfocus        元素获得焦点。               练习:输入框
onblur         元素失去焦点。               应用场景:用于表单验证,用户离开某个输入框时,代表已经输入完了,我们可以对它进行验证.
onchange       域的内容被改变。             应用场景:通常用于表单元素,当元素内容被改变时触发.(三级联动)

onkeydown      某个键盘按键被按下。          应用场景: 当用户在最后一个输入框按下回车按键时,表单提交.
onkeypress     某个键盘按键被按下并松开。
onkeyup        某个键盘按键被松开。
onload 一张页面或一幅图像完成加载。
onmousedown 鼠标按钮被按下。 onmousemove 鼠标被移动。 onmouseout 鼠标从某元素移开。 onmouseover 鼠标移到某元素之上。 onmouseleave 鼠标从元素离开 onselect 文本被选中。 onsubmit 确认按钮被点击。

绑定事件方式

方式1:

<div id="div" onclick="foo(this)">点我呀</div>

<script>
    function foo(self){           // 形参不能是this;
        console.log("点你大爷!");
        console.log(self);   
    }
</script>

方式2:

<p id="abc">试一试!</p>

<script>

    var ele=document.getElementById("abc");

    ele.onclick=function(){
        console.log("ok");
        console.log(this);    // this直接用
    };

</script>

事件介绍

例:

  onfocus、onblur、onchange、onload、onsubmit、事件穿透;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件</title>
    <style>
        *{
            margin: 0px;
        }
        .big{
            height: 200px;
            width: 200px;
            background-color: darkseagreen;
        }
        .small{

            height: 100px;
            width: 100px;
            background-color: yellow;
        }
    </style>
</head>
<body>
    <!--onfocus 、onblur-->
    <input type="text" onfocus="input_str(this)" onblur="exit_input(this)" value="请输入">
    <!--select-二级联动-->
    <select id="style_cooking"></select>
    <select id="dish">
        <option>请选择菜品</option>
    </select>
    <!--obsubmit-form表单中提交按钮-->
    <form action="" method="post" id="form">
        <input type="text"/>
        <input type="submit" value="提交"/>
    </form>
    <!--Event时间传递-->


    <div class="big">
        <div class="small"></div>
    </div>

</body>
<script>
//      ===================input-输入框====================================
        function input_str(self) {
            if(self.value=='请输入'){
                self.value ='';
            }
        }

        function exit_input(self) {
            if(self.value ==''){
                self.value ='请输入'
            }
        }

//      ===================select-二级联动 ====================================
        info ={'请选择菜系':['请选择菜品'],
                '川菜':['鱼香肉丝','酸菜鱼','东坡肘子'],
               '东北菜':['锅包肉','溜肉段','杀猪菜'],
                '湘菜':['剁椒鱼头','金钱鱼']};

        var cook_select = document.getElementById('style_cooking');
        var dish_select = document.getElementById('dish');
//      给style_cooking添加菜系option
        for(var i in info){
            var op = document.createElement('option');
            op.innerText = i;
            cook_select.appendChild(op);
        }

        cook_select.onchange = function () {

            var index = this.selectedIndex;
            var cook_style = cook_select.children[index];
            var change_name = cook_style.innerText;
            console.log('选择的菜系是',index,change_name);

            var dish_list = info[change_name];
            console.log('菜单列表',dish_list);
//          将dish_select中的元素清空
            dish_select.options.length = 0;

            for(var i in dish_list){
                var new_option = document.createElement('option');
                new_option.innerText = dish_list[i];
                dish_select.appendChild(new_option)
            }
        };
//      ===================onlode 等待事物加载完成后再执行 ====================================
        /*onload 属性开发中 只给 body元素加.这个属性的触发 标志着 页面内容被加载完成.应用场景: 当有些事情我们希望页面加载完立刻执行,那么可以使用该事件属性.*/
        window.onload = function () {
//            要执行的代码。
        }

//      =================== obsubmit-form表单中提交按钮 ====================================
        /*当表单在提交时触发. 该属性也只能给form元素使用.应用场景: 在表单提交前验证用户输入是否正确.如果验证失败.在该方法中我们应该阻止表单的提交.*/
        var form_obj = document.getElementById('form');
        console.log(form_obj);
        form_obj.onsubmit=function (event) {

            //第一种阻止提交的方式(常用)
            //onsubmit 命名的事件函数,可以接受返回值. 其中返回false表示拦截表单提交.其他为放行.
            return false;
            //第二种阻止提交方式:
            // 阻止表单提交方式2 event.preventDefault(); ==>通知浏览器不要执行与事件关联的默认动作。
            event.preventDefault()
        }
//      事件传递:两个带有事件的元素重叠,发生事件穿透。
        window.onload= function () {
            var big_obj = document.getElementsByClassName('big')[0];
            var small_obj = document.getElementsByClassName('small')[0];
            big_obj.onclick=function (event) {

                alert('big_Click');
            }
            small_obj.onclick = function (event) {
//              阻止事件传递
                event.stopPropagation();
                alert('small_Click');

            }
        }
    </script>
</html>

onselect:当文本被选中的时候

<input type="text">
<script>
    var ele=document.getElementsByTagName("input")[0];

    ele.onselect=function(){
          alert(222);
    }

</script>

onkeydown:

Event 对象:Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件通常与函数结合使用,函数不会在事件发生前被执行!event对象在事件发生时系统已经创建好了,并且会在事件函数被调用时传给事件函数.我们获得仅仅需要接收一下即可.比如onkeydown,我们想知道哪个键被按下了,需要问下event对象的属性,这里就时KeyCode.

<input type="text" id="t1"/>

<script type="text/javascript">

    var ele=document.getElementById("t1");

    ele.onkeydown=function(e){

        e=e||window.event;

        var keynum=e.keyCode;
        var keychar=String.fromCharCode(keynum);

        alert(keynum+'----->'+keychar);

    };

</script>

onmouseout与onmouseleave事件的区别:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #container{
            width: 300px;
        }
        #title{
            cursor: pointer;
            background: #ccc;
        }
       #list{
           display: none;
           background:#fff;
       }

        #list div{
            line-height: 50px;
        }
        #list  .item1{
            background-color: green;
        }

         #list  .item2{
            background-color: rebeccapurple;
        }

         #list  .item3{
            background-color: lemonchiffon;
        }


    </style>
</head>
<body>


<p>先看下使用mouseout的效果:</p>

<div id="container">
        <div id="title">使用了mouseout事件↓</div>
        <div id="list">
                <div class="item1">第一行</div>
                <div class="item2">第二行</div>
                <div class="item3">第三行</div>
        </div>
</div>


<script>

// 1.不论鼠标指针离开被选元素还是任何子元素,都会触发 mouseout 事件。

// 2.只有在鼠标指针离开被选元素时,才会触发 mouseleave 事件。

   var container=document.getElementById("container");
   var title=document.getElementById("title");
   var list=document.getElementById("list");


   title.onmouseover=function(){
       list.style.display="block";
   };

   container.onmouseleave=function(){  // 改为mouseout试一下
       list.style.display="none";
   };

/*

因为mouseout事件是会冒泡的,也就是onmouseout事件可能被同时绑定到了container的子元素title和list
上,所以鼠标移出每个子元素时也都会触发我们的list.style.display="none";

*/


  /*
  思考:
  if:
       list.onmouseout=function(){
           list.style.display="none";
   };
     为什么移出第一行时,整个list会被隐藏?

     其实是同样的道理,onmouseout事件被同时绑定到list和它的三个子元素item上,所以离开任何一个
     子元素同样会触发list.style.display="none";

   */

</script>
</body>
</html>

 

实例练习

 1 菜单栏:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
          .left{
              width: 20%;
              height: 500px;
              float: left;
              background-color: wheat;
          }

          .right{
              float: left;
              width: 80%;
              height: 500px;
              background-color: lightgray;

          }

           .title{
               text-align: center;
               line-height: 40px;
               background-color: #0e90d2;
               color: white;
           }
        .item{
            padding: 10px;
            text-align: center;
        }

        .hide{
            display: none;
        }
    </style>
</head>
<body>



<div class="outer">
      <div class="left">
           <div class="item">
               <div class="title">川菜</div>
               <ul class="con">
                   <li>鱼香肉丝</li>
                   <li>酸菜鱼</li>
                   <li>东坡肘子</li>
               </ul>
           </div>
          <div class="item">
               <div class="title">东北菜</div>
               <ul class="con hide">
                   <li>锅包肉</li>
                   <li>溜肉段</li>
                   <li>杀猪菜</li>
               </ul>
           </div>
          <div class="item">
               <div class="title">湘菜</div>
               <ul class="con hide">
                   <li>剁椒鱼头</li>
                   <li>金钱鱼</li>
                   <li>小炒肉</li>
               </ul>
           </div>
      </div>
      <div class="right"></div>
</div>

<script>

    var eles_title=document.getElementsByClassName("title");

    for (var i=0;i<eles_title.length;i++){
         eles_title[i].onclick=function(){
             this.nextElementSibling.classList.remove("hide");

             for(var j=0;j<eles_title.length;j++){
                 if (eles_title[j]!=this){
                     eles_title[j].nextElementSibling.classList.add("hide");
                 }
             }
         }
    }




</script>
</body>
</html>

 2 模态对话框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <style>
        *{
            margin: 0px;
        }
        .c1{
            position:relative;
            height: 2000px;
            background:url("属性/gao.jpg");

        }

        .c2{

            position: fixed;
            background-color: silver;
            opacity: 0.4;

            top: 0px;
            right: 0px;
            bottom: 0px;
            left: 0px;
        }

        .c3{
            height: 400px;
            width: 400px;
            background-color: blue;
            /*如果设置了Position属性,就必须设置位置*/
            position: fixed;
            top:50%;
            left:50%;

            margin-top: -200px;
            margin-left: -200px;

        }
        .hide{
            display: none;
        }
    </style>
    <script>
        var showFlag = true;
        function showLayer() {
            var elements = document.getElementsByClassName('button');
            /*这里说一下为什么要多加一个button名字来,因为JavaScript是动态语言,如果我用hide来获取的话,在for循环的删除后,获取的elements就只剩下一个了所以再次获取的话就什么都得不到了。*/
            for(var i=0;i<elements.length;i++){
                if(showFlag){
                    elements[i].classList.remove('hide');
                }
                else {
                    elements[i].classList.add('hide');
                }
            }
            if(showFlag){
                showFlag=false;
            }
            else {
                showFlag=true;
            }
        }
    </script>
</head>
<body>
    <div class="c1">
        <button onclick="showLayer()">showLayer</button>
    </div>
    <div class="c2 hide button"></div>
    <div class="c3 hide button">
        <button onclick="showLayer()">closeLayer</button>
    </div>
</body>
</html>

 3 表格案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<button class="select_all">全选</button>
<button class="select_reverse">反选</button>
<button class="cancel">取消</button>

<hr>

<table class="server_table" border="2px" cellspacing="2px">
    <tr>
        <td><input type="checkbox" class="item"></td>
        <td>111</td>
        <td>111</td>
        <td>111</td>
    </tr>
    <tr>
        <td><input type="checkbox" class="item"></td>
        <td>222</td>
        <td>222</td>
        <td>222</td>
    </tr>
    <tr>
        <td><input type="checkbox" class="item"></td>
        <td>333</td>
        <td>333</td>
        <td>333</td>
    </tr>
    <tr>
        <td><input type="checkbox" class="item"></td>
        <td>444</td>
        <td>444</td>
        <td>444</td>
    </tr>
</table>


<script>
/*
    var ele_all=document.getElementsByClassName("select_all")[0];
    var ele_reverse=document.getElementsByClassName("select_reverse")[0];
    var ele_cancel=document.getElementsByClassName("cancel")[0];
    var input_arr=document.getElementsByClassName("item");

    ele_all.onclick=function(){
          for(var i=0;i<input_arr.length;i++){
              console.log(input_arr[i]);
              var input=input_arr[i];
              input.checked=true;
          }
    };

     ele_cancel.onclick=function(){
          for(var i=0;i<input_arr.length;i++){
              console.log(input_arr[i]);
              var input=input_arr[i];
              input.checked=false;
          }
    };

    ele_reverse.onclick=function(){
          for(var i=0;i<input_arr.length;i++){
              console.log(input_arr[i]);
              var input=input_arr[i];
              if(input.checked){
                  input.checked=false;
              }
              else{
                  input.checked=true;
              }
          }
    };

*/


    var input_arr=document.getElementsByClassName("item");
    var button_arr=document.getElementsByTagName("button");

    for(var i=0;i<button_arr.length;i++){

        button_arr[i].onclick=function(){


            for (var j=0;j<input_arr.length;j++){
                 var inp=input_arr[j]
                 if(this.innerText=="全选"){
                     console.log("ok");
                 inp.checked=true;
             }
            else if(this.innerText=="取消"){
                  inp.checked=false;
             }
            else {
                 if(inp.checked){
                     inp.checked=false;
                 }else {
                     inp.checked=true;
                 }
             }
                
            }
        }

    }
</script>
</body>
</html>

 5 select移动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>移动</title>
</head>
<style>
    *{
        margin:0;
    }

    #left,#right{
        height: 200px;
        width: 200px;
        background-color: darkseagreen;
    }

    #mid{
        display: inline-block;
        height: 200px;
        background-color: lightseagreen;
        vertical-align: top;

    }

    button{
        margin-top: 10px;
        padding: 0 5px;
    }

</style>
<body>
<select name="" id="left" multiple="multiple">
    <option>水浒传</option>
    <option>西游记</option>
    <option>寻秦记</option>
</select>
<span id="mid">
    <button id="move"> -> move </button><br>
    <button id="move_all"> ->move_all</button>
</span>
<select name="" id="right" multiple="multiple">
    <option>红楼梦</option>
    <option>三国演义</option>
    <option>围城</option>
</select>
</body>
<script>
    window.onload = function () {
        var move = document.getElementById('move');
        var move_all = document.getElementById('move_all');
        var left = document.getElementById('left');
        var right = document.getElementById('right');

        move.onclick = function () {
            for(var i=0; i<left.length;i++){
                if(left[i].selected){
                    right.appendChild(left[i]);
                    i--;
                }
            }
        }
        move_all.onclick =function () {
            for(var i=0;i<left.length;i++){
                right.appendChild(left[0]);
                i--;
            }
        }
    }
</script>
</html>

 6 跑马灯

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>跑马灯</title>
    <style>
        *{
            margin: 0px;
        }
        #welcome{
            
            color: white;
            background-color: darkseagreen;
            text-align: center;
        }

    </style>
    <script>
        var ID;
        function Press_button(self) {
            if(ID == undefined){
                ID = setInterval('start()',200);
//                self.onclick='end()'
                self.innerHTML ='停止';
                self.style.backgroundColor = 'red';
            }
            else{
                clearInterval(ID);
                ID = undefined;
                self.innerHTML = '开始';
                self.style.backgroundColor = 'green';

            }
        }

        function start() {
            var str_h1 = document.getElementById('welcome').innerText;
            var first = str_h1.substr(0,1);
            var after = str_h1.substr(1,str_h1.length-1);
            var new_str = after.concat(first);
            document.getElementById('welcome').innerText = new_str;

        }
    </script>
</head>
<body>
    <h1 id="welcome">北京欢迎你,为你开天辟地。</h1>
    <button onclick="Press_button(this)" style = color:white;background-color:green;>开始</button>
</body>
</html>

 7 跑马灯与tab切换

 js的作用域:

作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理。

任何程序设计语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。

作用域

1. 全局作用域(Global Scope)

在代码中任何地方都能访问到的对象拥有全局作用域,一般来说一下几种情形拥有全局作用域:

(1)最外层函数和在最外层函数外面定义的变量拥有全局作用域

var name="111";

    function foo(){
        var age=23;
        function inner(){
            console.log(age);
        }

        inner();
    }

    console.log(name);    // 111
    //console.log(age);   // Uncaught ReferenceError: age is not defined
    foo();                // 23
    inner();              // Uncaught ReferenceError: inner is not defined

(2)所有末定义直接赋值的变量自动声明为拥有全局作用域,例如:

    var name="111";

    function foo(){
        age=23;

        var sex="male"
    }
    foo();
    console.log(age);   //  23
    console.log(sex);   // sex is not defined

变量blog拥有全局作用域,而sex在函数外部无法访问到。

(3)所有window对象的属性拥有全局作用域

一般情况下,window对象的内置属性都都拥有全局作用域,例如window.alert()、window.location、window.top等等。

2. 局部作用域(Local Scope)

和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所有在一些地方也会看到有人把这种作用域成为函数作用域.

如示例1中的age与inner都只有局部作用域。(js中if、for没有自己的作用域)

 作用域链(Scope Chain)

在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。

示例演示

//-----**********************例1*********************************

    var s=12;
    function f(){
        console.log(s);   
        var s=11;          // s=11
        console.log(s)  
    }
    f();   // undefined 11

//-----**********************例2*********************************

var s=10;
function foo(){
  console.log(s);
  var s=5;
  console.log(s);
  function s(){console.log("ok")}// 函数的定于或声明是在词法分析时完成的,执行时已不再有任何操作

  console.log(s);
}

foo();  function s 、5、5

//-----***********************例3********************************

function bar(age) {

        console.log(age);
        var age = 99;
var sex= 'male'; console.log(age); function age() {
alert(123) }; console.log(age);
return 100; } result=bar(5); 同上 //-----********************************************************

结果分析

当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充。在函数bar创建时,它的作用域链中会填入一个全局对象,该全局对象包含了所有全局变量,如下图所示:

解析到函数调用时,即bar(5),会生成一个active object的对象,该对象包含了函数的所有局部变量、命名参数、参数集合以及this,然后此对象会被推入作用域链的前端,当运行期上下文被销毁,活动对象也随之销毁。新的作用域链如下图所示:

过程解析:

function bar(age) {

        console.log(age);
        var age = 99;
        var sex="male";
        console.log(age);
        function age(){
            alert(123);
        } ;
        console.log(age);
        return 100;
}

result=bar(5);

一 词法分析过程(涉及参数,局部变量声明,函数声明表达式):
    1-1 、分析参数,有一个参数,形成一个 AO.age=undefine;
    1-2 、接收参数 AO.age=5;
    1-3 、分析变量声明,有一个 var age, 发现 AO 上面有一个 AO.age ,则不做任何处理
    1-4 、分析变量声明,有一个 var sex,形成一个 AO.sex=undefine;
    1-5 、分析函数声明,有一个 function age(){} 声明, 则把原有的 age 覆盖成 AO.age=function(){};
二 执行过程:
    2-1 、执行第一个 console.log(age) 时,当前的 AO.age 是一个函数,所以输出的一个函数
    2-2 、这句 var age=99; 是对不 AO.age 的属性赋值, AO.age=99 ,所以在第二个输出的age是 99;
    2-3 、同理第三个输出的是 99, 因为中间没有改变 age 值的语句了。

          注意:执行阶段:
                        function age(){
                            alert(123)
                        } ;

            不进行任何操作,将执行语句复制给age这部操作是在词法分析时,即运行前完成的。

JavaScript函数执行过程是先解析,后执行。

 

 

posted @ 2017-08-23 17:55  LeeeetMe  阅读(206)  评论(0编辑  收藏  举报