前端基础:JavaScript DOM对象

JavaScript DOM对象

通过HTML DOM,可以访问JavaScript HTML文档的所有元素。
一、HTML DOM(文档对象模型)
当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。HTML DOM模型被构造为对象的树:

通过可编程的对象模型,JavaScript获得了足够的能力来创建动态的HTML。

  • JavaScript能够改变页面中的所有HTML元素;
  • JavaScript能够改变页面中的所有HTML属性;
  • JavaScript能够改变页面中的所有CSS样式;
  • JavaScript能够对页面中的所有事件作出反应;

二、DOM节点
1.节点类型:HTML文档中的每个成分都是一个节点,DOM是这样规定的:

  • 整个文档是一个文档节点;
  • 每个HTML标签是一个元素节点;
  • 包含在HTML元素中的文本是文本节点;
  • 每一个HTML属性是一个属性节点;

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

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

  • 在节点树中,顶端节点被称为根(root);
  • 每个节点都有父节点,除了根(它没有父节点);
  • 一个节点可以拥有任意数量的子节点;
  • 同胞是拥有相同父节点的节点;
    下图展示了部分节点树的节点关系:

3.节点查找:有两种方式
方式一:直接查找节点

        // 节点查找(节点也就是一个个的标签)
        document.getElementById('idname');        //按照id查找,拿到的是一个标签对象
        document.getElementsByClassName('classname');        //按照class标签去找,得到的是一个数组里存放的标签
        document.getElementsByTagName('tagname');        //通过标签名去找,拿到的也是一个数组
        var a = document.getElementsByName('yuan');         //按照name属性去找,拿到的也是一个数组
        console.log(a);

length属性

    var ele = document.getElementById('div1');
    console.log(ele.length);        //返回undified

    var ele2 = document.getElementById('div3');
    console.log(ele2.length);        //返回undified

    var ele3 = document.getElementsByClassName('div2');
    console.log(ele3.length);         //返回1

    var ele4 = document.getElementsByTagName('p');
    console.log(ele4.length) ;        //返回1

    var ele5 = document.getElementsByName('haiyan');
    console.log(ele5.length); //返回1

    // id和name的不支持
   var div1=document.getElementById("div1");

    //支持;
   var ele= div1.getElementsByTagName("p");
   alert(ele.length);
    //支持
   var ele2=div1.getElementsByClassName("div2");
   alert(ele2.length);
    //不支持
   var ele3=div1.getElementById("div3");
   alert(ele3.length);
    //不支持
   var ele4=div1.getElementsByName("yuan");
   alert(ele4.length)

方式二:间接查找(导航查找节点,通过某个标签的位置去查找另一个标签,这是一个导航属性)

parentElement           // 父节点标签元素
children                // 所有子标签
firstElementChild       // 第一个子标签元素
lastElementChild        // 最后一个子标签元素
nextElementtSibling     // 下一个兄弟标签元素
previousElementSibling  // 上一个兄弟标签元素
//    方式二:导航查找
//<div id ='div1'>
//     <div class="div2" name = 'haiyan'>lallala</div>
//     <div name="haiyan">lkkaakkka</div>
//     <div id ='div3'>aaaaaaaaaaaaaa</div>
//    <p>hrllo</p>
//</div>

//注意:1.如果是数组的话后面切记getElementsByClassName('div2')[0]
//        2.查找元素的那些方法Elements加了s的打印的就是数组
//    1,==================
    var ele = document.getElementsByClassName('div2')[0];
    var ele1= ele.parentElement;
    console.log(ele1)  ;//找div2标签的父亲
//    2.===============
    var ele = document.getElementById('div1');
    var ele1 = ele.children;
    console.log(ele1) ; //找到div1下的所有的子标签
//    3.===================
    var ele = document.getElementById('div1');
    var ele1 = ele.firstElementChild;
    console.log(ele1);  //找到div1下的第一个子标签的元素
//    4.==================
    var ele = document.getElementById('div1');
    var ele1 = ele.lastElementChild;
    console.log(ele1);  //找到div1下的最后一个子标签的元素
//    5.===============
    var ele = document.getElementsByName('haiyan')[0];
    var ele1 = ele.nextElementSibling;
    console.log(ele1) ; //下一个兄弟标签元素
//    6.===============
    var ele = document.getElementsByName('haiyan')[0];
    var ele1 = ele.previousElementSibling;
    console.log(ele1)  //上一个兄弟标签元素

4.节点操作
1)创建节点

createElement(标签名):创建一个指定名称的标签;

例如:
var tag = document.createElement("input");
tag.setAttribute("type", "text");

2)添加节点

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

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

3)删除节点

removeChild():获得要删除的元素,通过父元素调用删除

4)替换节点

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

5)节点属性操作

  • 获取文本节点的值:innerText、innerHTML
    innerText:不管是赋值还是取值,只能识别纯文本;innerHTML:既可以识别纯文本,也可以识别标签;
//    文本属性
//  1.innerText:不管你是赋值还是取值,只能识别纯文本
        var a1 = document.getElementsByClassName('c2')[0];
//        console.log(a1);
        //取值操作
        console.log(a1.innerText); //你好吗/
        console.log(a1.innerHTML); //你好吗/
        //赋值操作
        a1.innerText='Egon';
        a1.innerHTML='<a href="">hello</a>';

//  2.innerHtml:既可以识别纯文本,也可以识别标签
        var b1 = document.getElementsByClassName('c2')[1];
//        console.log(b1);
        //取值操作
        console.log(b1.innerText);
        console.log(b1.innerHTML);
        //赋值操作
        b1.innerText = 'lala';
        b1.innerHTML = '<input type="text">';
  • 属性(attribute)操作
    泛指所有的属性,getAttribute可以操作其他的,但是不可以操作class
    elementNode.setAttribute(name,value)    
    elementNode.getAttribute(属性名)        <-------------->elementNode.属性名(DHTML)
    elementNode.removeAttribute(“属性名”);
<body><div class="c1" id="d1">DIV</div>
<script>
    var ele = document.getElementsByClassName('c1')[0];
    ele.id='d2';//修改id
    console.log(ele);

//取属性值 :
//    方式一
    console.log(ele.getAttribute('id'));
//    方式二
    console.log(ele.id);
/ 属性赋值
//    方式一
    ele.setAttribute('id','d3');
    console.log(ele);
//    方式二
    ele.id = 'd3';
    console.log(ele);
  • value获取当前选中的value值
    input
    select(selectIndex)
    textarea

  • 关于class的操作

//    class属性=============
     var ele = document.getElementsByClassName('c1')[0];
     console.log(ele.className); //打印类的名字
     
     ele.classList.add('hide');
     console.log(ele); //<div class="c1 hide" id="d1">

     ele.classList.remove('hide');//吧添加的remove移除了
     console.log(ele)
  • 改变css样式
// 如需改变 HTML 元素的样式,请使用这个语法
document.getElementById(id).style.property=新样式
下面这个例子会改变<p>元素的样式

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript DOM 改变CSS样式</title>
</head>
<body>
 
<p id="p1">Hello World!</p>
<p id="p2">Hello World!</p>
<script>
document.getElementById("p2").style.color="blue";
document.getElementById("p2").style.fontFamily="Arial";
document.getElementById("p2").style.fontSize="larger";
</script>
<p>以上段落通过脚本修改。</p>
 
</body>
</html>

三、DOM Event(事件)
1.事件类型

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

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

onkeydown      某个键盘按键被按下。          应用场景: 当用户在最后一个输入框按下回车按键时,表单提交.
onkeypress     某个键盘按键被按下并松开。
onkeyup        某个键盘按键被松开。

onload         一张页面或一幅图像完成加载。

onmousedown    鼠标按钮被按下。
onmousemove    鼠标被移动。
onmouseout     鼠标从某元素移开。
onmouseover    鼠标移到某元素之上。
onmouseleave   鼠标从元素离开

onselect       文本被选中。
onsubmit       确认按钮被点击

2.绑定方式
方式一

<!--绑定事件的方式一-->
<div onclick="foo(this)">div</div>
<div class="c1">div2</div>
<script>
    function foo(self) {
        console.log(self); //<div onclick="foo(this)" style="color: red;">
        self.style.color = 'red';
    }

方式二

//方式二
//    事件的绑定方式2:标签对象.on事件 = function (){}
     var ele=document.getElementsByClassName("c1")[0];
     ele.onclick=function () {
        console.log(this); // this 代指: 当前触发时间的标签对象;
        this.style.fontSize="30px"
    }

3.onload事件
onload事件开发中,只给body元素加。这个事件的触发标志着页面内容被加载完成,应用场景:当有些事情我们希望页面加载完成立刻执行,就可以使用该事件(什么时候加载完,什么时候触发)

// onload事件:基于节点操作的修改
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>节点操作</title>
    <style>
        .c1 {
            width: 300px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
    <script>
        //如果要把script写在body的上面就可以用onload事件
        //onload什么时候加载完什么时候触发这个事件
        window.onload = function () {
            var ele_add = document.getElementsByClassName('addBtn')[0];
            var ele_del = document.getElementsByClassName('delBtn')[0];
            var ele_repleace = document.getElementsByClassName('replaceBtn')[0];
            console.log(ele_add);
            //绑定的添加节点的事件
            ele_add.onclick = function () {
                //先创建一个标签
                var ele_a = document.createElement('a');
                console.log(ele_a); //<a></a>
                ele_a.innerHTML = '点击'; //<a>点击</a>
                ele_a.href = 'http://www.baidu.com'; //<a href='http://www.baidu.com'>点击</a>
                //先创建一个标签
                var ele_img = document.createElement('img');
                ele_img.src = '1.png';
                ele_img.width = 50;
                ele_img.height = 50;
                //找到父标签
                var ele_parent = document.getElementsByClassName('c1')[0];
                //然后添加
                ele_parent.appendChild(ele_a);
                ele_parent.appendChild(ele_img);
            };
            //绑定的删除节点的事件
            ele_del.onclick = function () {
                //先获取要删除的元素
                var ele_p = document.getElementById('p1');
                //获取它的父元素
                var ele_parent = document.getElementsByClassName('c1')[0];
                //然后删除(注意是父元素删除子元素)
                ele_parent.removeChild(ele_p)
            };
            //绑定的替换节点的事件
            ele_repleace.onclick = function () {
                //找被替换的标签(旧标签)
                var ele_p = document.getElementById('p2');
                //创建一个替换后的标签(新标签)
                var ele_img = document.createElement('img');
                ele_img.src = '2.png';
                ele_img.width = 100;
                ele_img.height = 50;
                //找到父节点
                var ele_parent = document.getElementsByClassName('c1')[0];
                //做替换(父节点替换子节点中的某一个节点):相当于一次删除加一次添加
                ele_parent.replaceChild(ele_img, ele_p);
            };
            //表格绑定删除节点的事件
            var ele_dels = document.getElementsByClassName('delbtn');
            for (var i = 0; i < ele_dels.length; i++) {
                ele_dels[i].onclick = function () {
                    //获取删除的元素
                    var ele_tr = this.parentElement.parentElement;
//            console.log(ele_tr)
                    //找到父节点
                    var ele_tbody_parent = document.getElementById('t1');
                    //然后删除
                    ele_tbody_parent.removeChild(ele_tr)
                }
            }
        }
    </script>
</head>
<body>
<div class="c1">
    <p id="p1">年后</p>
    <p id="p2">hello</p>
</div>
<button class="addBtn">ADD</button>
<button class="delBtn">DEL</button>
<button class="replaceBtn">Replace</button>
<ul>
    <li>创建节点:var ele_a = document.createElement('a');</li>
    <li>添加节点:ele_parent.appendChild(ele_img);</li>
    <li>删除节点:ele_parent.removeChild(ele_p);</li>
    <li>替换节点:ele_parent.replaceChild(新标签,旧标签);</li>
</ul>
<table border="1">
    <tbody id="t1">
    <tr>
        <td><input type="checkbox"></td>
        <td><input type="text"></td>
        <td>
            <button class="delbtn">del1</button>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox"></td>
        <td><input type="text"></td>
        <td>
            <button class="delbtn">del2</button>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox"></td>
        <td><input type="text"></td>
        <td>
            <button class="delbtn">del3</button>
        </td>
    </tr>
    <tr>
        <td><input type="checkbox"></td>
        <td><input type="text"></td>
        <td>
            <button class="delbtn">del4</button>
        </td>
    </tr>
    </tbody>
</table>
</body>
</html>
// onload实例二
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script>
         /*
              window.onload=function(){
                   var ele=document.getElementById("ppp");
                   ele.onclick=function(){
                   alert(123)
                };
             };
         
         */



          function fun() {
              var ele=document.getElementById("ppp");
               ele.onclick=function(){
                alert(123)
            };
          }

    </script>
</head>
<body onload="fun()">

<p id="ppp">hello p</p>

</body>
</html>

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="text" class="test">
<input type="text" id="t1"/>
<script>
    //测试event对象
    var ele = document.getElementsByClassName('test')[0];
//    event :每次触发事件时所有的状态信息
//    event.keyCode :保存着所有的状态信息
    ele.onkeydown =function (event) {
//        onkeydown按下键盘触发的事件
        console.log(event);
        console.log(event.keyCode);
        if (event.keyCode==13){
            //按回车就会弹出
            alert(666)
        }
    }
</script>
<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);
//        console.log(keynum); //每次键盘敲下的状态信息
//        console.log(keychar);  //输入的字符
//        alert(keynum);
//        alert(keychar)  //你键盘输入的字符
    };
</script>
</body>
</html>

5.onsubmit事件
当表单再提交时触发,该事件也只能给form表单使用。应用场景:在表单提交验证用户输入是否正确,如果验证失败,在该方法中,我们应该阻止表单的提交:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>onsubmit事件</title>
    <!--onsubmit事件:确定按钮被点击-->
    <!--在表单提交前验证用户输入是否正确.如果验证失败.在该方法中我们应该阻止表单的提交.-->
    <!--提交按钮本身就有一个默认事件(你点击提交的时候就会把数据发过去)-->

</head>
<body>
<form action="" id="submit">
    <p>姓名:<input type="text" class="name"></p>
    <p>年龄:<input type="text" class="age"></p>
    <input type="submit">
</form>
<input type="text" class="test">
<script>
    var ele_form = document.getElementById('submit');
    var ele_name = document.getElementsByClassName('name')[0];
    var ele_age = document.getElementsByClassName('age')[0];
    ele_form.onsubmit = function (event) {
        var username = ele_name.value;
        var age = ele_age.value;
        alert(username);
        alert(age);
        if (username=='haiyan'){
            //阻止默认事件的两种方式
//            方式一:
//            return false;
//            方式二
//            给函数给一个形参,这个形参写什么都行,一般我们写成event
            event.preventDefault() //阻止默认事件(表单的提交)
        }
    }
</script>
<script>
    //测试event对象
    var ele = document.getElementsByClassName('test')[0];
//    event :每次触发事件时所有的状态信息
//    event.keyCode :保存着所有的状态信息
    ele.onkeydown =function (event) {
//        onkeydown按下键盘触发的事件
        console.log(event);
        console.log(event.keyCode);
        if (event.keyCode==13){
            //按回车就会弹出
            alert(666)
        }
    }
</script>
</body>
</html>

6.事件传播

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件传播</title>
    <style>
        .box1 {
            width: 300px;
            height: 300px;
            background-color: rebeccapurple;
        }
        .box2{
            width: 150px;
            height: 150px;
            background-color: yellow;
        }
    </style>
</head>
<body>
<div class="box1">
    <div class="box2"></div>
</div>
<script>
    //因为盒子1是盒子2的父亲,所以当给父亲绑定一个事件,给儿子也绑定一个事件,就像
//    继承一样,儿子会继承父亲的事件,所以现在运行的时候如果点击盒子2,会把自己的是事件和
//    父亲的事件都执行了。所以如果只想让儿子执行自己的事件,那么就得阻止发生事件传播
    var ele1 = document.getElementsByClassName('box1')[0];
    var ele2 = document.getElementsByClassName('box2')[0];
    ele1.onclick = function () {
        alert(123)
    };
    ele2.onclick = function (event) {
        alert(456);
        console.log(event);
        console.log(event.keyCode);
        //    阻止事件传播的方式
        event.stopPropagation();
    };


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

7.search实例
模拟placeholder属性的功能,placeholder和value的区别:

  • placeholder:只是一个提示功能,不传值;
  • value:是一个默认的值,如果输入框中不写数据时,它会将默认的数据发送出去
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模拟placeholder属性的功能</title>
</head>
<body>
<input type="text" placeholder="username" id="submit">
<input type="text" value="username" id="submit1">
<script>
//    var ele = document.getElementById('submit1');
    var ele = document.getElementById('submit1');
    ele.onfocus = function () {
        //先获取焦点,点击输入框就获取到焦点,光标一上去就把值设成空
        this.value=""
    };
    ele.onblur = function () {
//        当光标不点击那个输入框的时候就失去焦点了
        //当失去焦点的时候,判断当前的那个值是不是为空,是否含有空格
//        如果为空或者有空格,用trim()去掉空格。然后赋值为username
        if (this.value.trim()==""){
            this.value='username'
        }
    }
</script>
</body>
</html>

8.onchange事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>onchange事件</title>
</head>
<body>
<select name="" id="s1">
    <option value="">甘肃省</option>
    <option value="">安徽省</option>
    <option value="">湖北省</option>
</select>
<script>
    var ele = document.getElementById('s1');
    //下拉菜单,和你当前事件不同的时候出发事件
    ele.onchange= function () {
        alert(123)
    }
</script>
</body>
</html>
// 使用onchange事件实现菜单二级联动
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>二级联动</title>
</head>
<body>
<select name="" id="s1">
    <option value="">请选择省份</option>
    <option value="gansu">甘肃省</option>
    <option value="hebei">河北省</option>
    <option value="henan">河南省</option>
</select>
<select name="" id="c1">
    <option value="city">请选择城市</option>
</select>
<script>
    var data = {'gansu':['兰州市','天水市','武威市'],'hebei':['保定','石家庄'],'henan':['郑州','开封']}
    var ele_select = document.getElementById('s1');
    var ele_critys = document.getElementById('c1');//父亲标签
    ele_select.onchange  =function () {
//        alert(123)
//        console.log(this.value)
        var ele_provice = this.value;
        var citys = data[ele_provice];
        console.log(citys);
        //要在没有添加之间清空,不然你点一次添加一次,点一次添加一次
        //方式一
//        ele_critys.children.length=1;  //不可行。。但是原理和方式二的一样
        //方式二
//        ele_critys.options.length = 1; //留一个,一般多的是设成0了
        for (var i =0;i<citys.length;i++) {
            //创建一个option标签
            var ele_option = document.createElement('option'); //<option></option>
            ele_option.innerHTML = citys[i];  //得到有文本的option标签
            ele_option.value = i + 1; //设置属性值
            console.log(ele_option);
            ele_critys.appendChild(ele_option);
        }
    }
</script>

</body>
</html>

9.onmouse事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>onmouse事件</title>
    <style>
        .box{
            width: 300%;
            height: 200px;
        }
        .title{
            background: steelblue;
            line-height: 40px;
        }
        .con{
            background: slategray;
            line-height: 30px;
        }
        .hide{
            display: none;
        }
    </style>
</head>
<body>
<div class="box">
    <div class="title">onmouse</div>
    <div class="con hide">
        <div><a href="" class="item">你好吗?</a></div>
        <div><a href="" class="item">我好啊</a></div>
        <div><a href="" class="item">好就好呗</a></div>
    </div>
</div>
<script>
    var ele_title = document.getElementsByClassName('title')[0];
    var ele_box = document.getElementsByClassName('box')[0];
    //鼠标指上去的事件
    ele_title.onmouseover = function () {
        this.nextElementSibling.classList.remove('hide');
    };
    //鼠标移走的事件的两种方式
//    方式一(推荐)
     ele_box.onmouseleave= function () {
        ele_title.nextElementSibling.classList.add('hide');
    };
//    方式二
//    ele_title.onmouseout = function () {
//       this.nextElementSibling.classList.add('hide');
//    }
//    方式一和方式二的区别:
//    不同点
//      onmouseout:不论鼠标指针离开被选元素还是任何子元素,都会触发onmouseout事件
//      onmouseleave:只有在鼠标指针离开被选元素时,才会触发onmouseleave事件
//    相同点:都是鼠标移走触发事件
</script>
</body>
</html>

10.事件委派

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件委派(委派给所有的子元素)</title>
</head>
<body>
<ul>
    <li>111</li>
    <li>222</li>
    <li>333</li>
</ul>
<button class="addbtn">点我添加</button>
</body>
<script>
    var ele_btn = document.getElementsByClassName('addbtn')[0];
    var ele_ul = document.getElementsByTagName('ul')[0];
    var ele_li =document.getElementsByTagName('li');
    //绑定事件
    for (var i=0;i<ele_li.length;i++){
        ele_li[i].onclick = function () {
            alert(this.innerHTML)
        }
    }

    //事件委派
    ele_btn.onclick = function () {
        //创建一个li标签
        var ele_li = document.createElement('li');
//        ele_li.innerHTML= 444;
        ele_li.innerText = Math.round(Math.random()*1000);
        ele_ul.appendChild(ele_li);//吧创建的li标签添加到ul标签
        ele_ul.addEventListener('click',function (e) {
            console.log(e.target); //当前点击的标签
            console.log(e.target.tagName);//拿到标签的名字  LI
            if (e.target.tagName=='LI'){
                console.log('ok');
//                alert(ele_li.innerHTML)
            }
        })
    }
</script>
</html>

四、节点操作
前面我们知道了JavaScript的属性操作,接下来了解一下节点操作,很重要!
创建节点:var ele= document.createElement("newnode");
增加节点:ele_parent.appendChild(ele_other);
删除节点:ele_parent.removeChild(ele_p);
替换节点:ele_parent.replaceChild(新标签,就标签);

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>节点操作</title>
    <style>
        .c1 {
            width: 300px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div class="c1">
    <p id="p1">年后</p>
    <p id="p2">hello</p>
</div>
<button class="addBtn">ADD</button>
<button class="delBtn">DEL</button>
<button class="replaceBtn">Replace</button>
<ul>
    <li>创建节点:var ele_a = document.createElement('a');</li>
    <li>添加节点:ele_parent.appendChild(ele_img);</li>
    <li>删除节点:ele_parent.removeChild(ele_p);</li>
    <li>替换节点:ele_parent.replaceChild(新标签,旧标签);</li>
</ul>
<table border="1">
    <tbody id="t1">
        <tr>
            <td><input type="checkbox"></td>
            <td><input type="text"></td>
            <td><button class="delbtn">del1</button></td>
        </tr>
        <tr>
            <td><input type="checkbox"></td>
            <td><input type="text"></td>
            <td><button class="delbtn">del2</button></td>
        </tr>
        <tr>
            <td><input type="checkbox"></td>
            <td><input type="text"></td>
            <td><button class="delbtn">del3</button></td>
        </tr>
        <tr>
            <td><input type="checkbox"></td>
            <td><input type="text"></td>
            <td><button class="delbtn">del4</button></td>
        </tr>
    </tbody>
</table>
<script>
    var ele_add = document.getElementsByClassName('addBtn')[0];
    var ele_del = document.getElementsByClassName('delBtn')[0];
    var ele_repleace = document.getElementsByClassName('replaceBtn')[0];
    console.log(ele_add);
    //绑定的添加节点的事件
    ele_add.onclick = function () {
        //先创建一个标签
        var ele_a = document.createElement('a');
        console.log(ele_a); //<a></a>
        ele_a.innerHTML = '点击'; //<a>点击</a>
        ele_a.href = 'http://www.baidu.com'; //<a href='http://www.baidu.com'>点击</a>
        //先创建一个标签
        var ele_img = document.createElement('img');
        ele_img.src = '1.png';
        ele_img.width = 50;
        ele_img.height = 50;
        //找到父标签
        var ele_parent = document.getElementsByClassName('c1')[0];
        //然后添加
        ele_parent.appendChild(ele_a);
        ele_parent.appendChild(ele_img);
    };
    //绑定的删除节点的事件
    ele_del.onclick = function () {
        //先获取要删除的元素
        var ele_p = document.getElementById('p1');
        //获取它的父元素
        var ele_parent = document.getElementsByClassName('c1')[0];
        //然后删除(注意是父元素删除子元素)
        ele_parent.removeChild(ele_p)
    };
    //绑定的替换节点的事件
    ele_repleace.onclick = function () {
        //找被替换的标签(旧标签)
        var ele_p = document.getElementById('p2');
        //创建一个替换后的标签(新标签)
        var ele_img = document.createElement('img');
        ele_img.src = '2.png';
        ele_img.width = 100;
        ele_img.height = 50;
        //找到父节点
        var ele_parent = document.getElementsByClassName('c1')[0];
        //做替换(父节点替换子节点中的某一个节点):相当于一次删除加一次添加
        ele_parent.replaceChild(ele_img, ele_p);
    }
</script>
<script>
    //绑定删除节点的事件
    var ele_dels = document.getElementsByClassName('delbtn');
    for(var i=0;i<ele_dels.length;i++){
        ele_dels[i].onclick = function () {
            //获取删除的元素
            var ele_tr = this.parentElement.parentElement;
//            console.log(ele_tr)
            //找到父节点
            var ele_tbody_parent =document.getElementById('t1');
            //然后删除
            ele_tbody_parent.removeChild(ele_tr)
        }
    }
</script>
</body>
</html>

五、JavaScript DOM总结
1.JavaScript中for循环遍历,for循环遍历有两种:

  • 有条件遍历,例如:for(var i=0;i<ele.length;i++){}
  • for(var ele in ele_list){}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    var arr = [11,22,33,44,55];
    var obj = {'username':'zzz','agr':20};          //js中的这个类似字典的不叫字典,而是一个对象
    for (var i in obj){
        console.log(i);          //拿到的是键
        console.log(obj[i]);        //值
    }
    for (var j in arr){
        console.log(j);         //拿到索引
        console.log(arr[j]);          //拿到值
    }
</script>
</body>
</html>

2.获取value属性值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>获取value值</title>
</head>
<body>
<input type="text" id="c1">
<select name="pro" id="s1">
        <option value="1">河北省</option>
        <option value="2">河南省</option>
        <option value="3">北京省</option>
</select>
<button>show</button>
<script>
     var ele_button=document.getElementsByTagName("button")[0];

    ele_button.onclick=function () {
        var ele_input=document.getElementById("c1");
        var ele_select=document.getElementById("s1");
        console.log(ele_select.value)
    };
</script>
</body>
</html>

3.表格示例(全选,反选,取消)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>表格示例</title>
</head>
<body>
<button class="select">全选</button>
<button class="reserve">反选</button>
<button class="cancel">取消</button>
<table border="1">
    <tr>
        <td><input type="checkbox" class="check"></td>
        <td>111</td>
        <td>222</td>
        <td>333</td>
    </tr>
     <tr>
        <td><input type="checkbox" class="check"></td>
        <td>111</td>
        <td>222</td>
         <td>333</td>
    </tr>
     <tr>
        <td><input type="checkbox" class="check"></td>
        <td>111</td>
        <td>222</td>
         <td>333</td>
    </tr>
     <tr>
        <td><input type="checkbox" class="check"></td>
        <td>111</td>
        <td>222</td>
        <td>333</td>
    </tr>
</table>
<script>
//    方式一:分别给每个button增加事件
    var ele_select = document.getElementsByClassName('select')[0];
    var ele_reserve = document.getElementsByClassName('reserve')[0];
    var ele_cancel = document.getElementsByClassName('cancel')[0];
    var ele_input = document.getElementsByClassName('check');
    //全选
    ele_select.onclick = function () {
        for (var i = 0; i < ele_input.length; i++) {
            //添加一个checked属性
            ele_input[i].checked = 'checked'
        }
    };
    //取消
    ele_cancel.onclick = function () {
         for (var i =0;i<ele_input.length;i++){
            //删除checked属性,直接设置为空就行了
            ele_input[i].checked = ''
        }
    };
    //反选
    ele_reserve.onclick = function () {
        for (var i = 0; i < ele_input.length; i++) {
            var ele = ele_input[i];
            if (ele.checked) {//如果选中了就设置checked为空
                ele.checked = '';
            }
            else {//如果没有就设置checked = checked
                ele.checked = 'checked';
            }
         }
    };




    //方式二:方式一的优化循环增加事件
//    var ele_button = document.getElementsByTagName('button');
//    var ele_input = document.getElementsByClassName('check');
//    for(var i=0;i<ele_button.length;i++) {
//        ele_button[i].onclick = function () {
//            if (this.innerHTML == '全选') {
//                for (var i = 0; i < ele_input.length; i++) {
//                    //添加一个checked属性
//                    ele_input[i].checked = 'checked'
//                }
//            }
//            else if (this.innerHTML == '取消') {
//                for (var i = 0; i < ele_input.length; i++) {
//                    //删除checked属性,直接设置为空就行了
//                    ele_input[i].checked = ''
//                }
//            }
//            else {
//                for (var i = 0; i < ele_input.length; i++) {
//                    var ele = ele_input[i];
//                    if (ele.checked) {//如果选中了就设置checked为空
//                        ele.checked = '';
//                    }
//                    else {//如果没有就设置checked = checked
//                        ele.checked = 'checked';
//                    }
//                }
//            }
//        }
//    }


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

4.模态对话框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .back{
            background-color: white;
            height: 2000px;
        }

        .shade{
            position: fixed;
            top: 0;
            bottom: 0;
            left:0;
            right: 0;
            background-color: grey;
            opacity: 0.4;
        }

        .hide{
            display: none;
        }

        .models{
            position: fixed;
            top: 50%;
            left: 50%;
            margin-left: -100px;
            margin-top: -100px;
            height: 200px;
            width: 200px;
            background-color: wheat;

        }
    </style>
</head>
<body>
<div class="back">
    <input class="c" type="button" value="click">
</div>

<div class="shade hide handles"></div>

<div class="models hide handles">
    <input class="c" type="button" value="cancel">
</div>


<script>


    var eles=document.getElementsByClassName("c");
    var handles=document.getElementsByClassName("handles");
    for(var i=0;i<eles.length;i++){
        eles[i].onclick=function(){

            if(this.value=="click"){

                for(var j=0;j<handles.length;j++){

                    handles[j].classList.remove("hide");

                 }

            }
            else {
                for(var j=0;j<handles.length;j++){

                    handles[j].classList.add("hide");
                }

            }
        }
    }

</script>

</body>
</html>

5.搜索框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模拟placeholder属性的功能</title>
</head>
<body>
<input type="text" placeholder="username" id="submit">
<input type="text" value="username" id="submit1">
<script>
//    var ele = document.getElementById('submit1');
    var ele = document.getElementById('submit1');
    ele.onfocus = function () {
        //先获取焦点,点击输入框就获取到焦点,光标一上去就把值设成空
        this.value=""
    };
    ele.onblur = function () {
//        当光标不点击那个输入框的时候就失去焦点了
        //当失去焦点的时候,判断当前的那个值是不是为空,是否含有空格
//        如果为空或者有空格,用trim()去掉空格。然后赋值为username
        if (this.value.trim()==""){
            this.value='username'
        }
    }
</script>
</body>
</html>

6.tab切换

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>tab</title>
  <style>
    *{margin:0; padding:0; list-style:none;}
    body{
        font-family: "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei", "\9ED1\4F53", Arial, sans-serif;
    }
    h3{
        text-align: center;
        color:darkcyan;
        margin-top: 30px;
        letter-spacing: 5px;
    }
    .box{
      width: 1000px;
      margin:50px auto 0px;
    }
    #title{
      line-height: 40px;
      background-color: rgb(247,247,247);
      font-size: 16px;
      font-weight: bold;
      color: rgb(102,102,102);
    }
    #title span{
      float: left;
      width: 166px;
      text-align: center;
    }
    #title span:hover{
      /*color: black;*/
      cursor: pointer;
    }
    #content{
      margin-top: 20px;
    }
    #content li{
      width: 1050px;
      display: none;
      background-color: rgb(247,247,247);
    }
    #content li div{
      width: 156px;
      margin-right: 14px;
      float: left;
      text-align: center;
    }
    #content li div a{
      font-size: 14px;
      color: black;
      line-height: 14px;
    /*  float: left;*/
    display: inline-block;
      margin-top: 10px;
    }
    #content li a:hover{
      color: #B70606;
    }
    #content li div span{
        font-size: 16px;
        line-height: 16px;
        /*float: left;*/
        display: block;
        color: rgb(102,102,102);
        margin-top: 10px;
      }
    #content img{
      float: left;
      width: 155px;
      height: 250px;
    }
    #title .select{
      background-color: #2459a2;
      color: white;
        border-radius: 10%;
    }
    #content .show{
      display: block;
    }

    .show span{
        color: red!important;
        font-size: 30px;
    }
  </style>
</head>

<body>
    <h3 id="wel">京东商城欢迎您</h3>
    <!--  direction="right up down left" -->
<!--  behavior:滚动方式(包括3个值:scroll、slide、alternate) -->
<!--  说明:scroll:循环滚动,默认效果;slide:只滚动一次就停止;alternate:来回交替进行滚动。 -->
<!--  scrollamount="5" 滚动速度 -->

<marquee behavior="scroll" direction="right">欢迎海燕来访</marquee>
    <script>

    function test(){

        var mywel = document.getElementById("wel");
        var content = mywel.innerText;

        var f_content = content.charAt(0);
        var l_content = content.substring(1,content.length);

        var new_content = l_content + f_content;
        mywel.innerText = new_content;

    }

    // setInterval("test();", 500);
</script>
    <div class="box">
      <p id="title">
        <span class="select">家用电器</span>
        <span>家具</span>
        <span>汽车</span>
        <span>食品</span>
        <span>女鞋</span>
        <span>医疗保健</span>
      </p>

      <ul id="content">
        <li class="show">

          <div><img src="https://img10.360buyimg.com/n1/s450x450_jfs/t4786/325/2470647304/119102/9e1a4ed5/59005841Nd786a8df.jpg" alt="冰箱"><a href="#">容声(Ronshen)冰箱</a><span>价格:5600</span></div>
          <div><img src="https://img12.360buyimg.com/n1/s450x450_jfs/t3037/347/1290968859/201366/7c1028a0/57c00194N9d0a54c6.jpg" alt="洗衣机"><a href="#">海尔洗衣机</a><span>价格:5400</span></div>
          <div><img src="https://img11.360buyimg.com/n1/jfs/t3289/128/2393835119/236360/af1d283b/57e0f300N53dde603.jpg" alt="电饭煲"><a href="#">福库(CUCKOO)电饭煲</a><span>价格:3999</span></div>
          <div><img src="https://img13.360buyimg.com/n1/jfs/t3235/137/2361713777/152258/a6908440/57e098c2N44a90a5d.jpg" alt="智能电视"><a href="#">三星智能电视</a><span>价格:8999</span></div>
          <div><img src="https://img10.360buyimg.com/n1/jfs/t2053/101/1391591157/215066/572e131b/5696ee9bN2376492d.jpg" alt="净水器"><a href="#">净水器</a><span>价格:1300</span></div>
          <div><img src="https://img14.360buyimg.com/n1/jfs/t3175/78/2357430273/262835/9a8e7f65/57e0a3e9Nbda39dd2.jpg" alt="空气净化器"><a href="#">空气净化器</a><span>价格:5300</span></div>
        </li>

        <li>

          <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div>
          <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div>
          <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div>
          <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div>
          <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div>
          <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div>

        </li>
        <li>
          <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div>
          <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div>
          <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div>
          <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div>
          <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div>
          <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div>
        </li>
        <li>

          <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div>
          <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div>
          <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div>
          <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div>
          <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div>
          <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div>

        </li>
        <li>

          <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div>
          <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div>
          <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div>
          <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div>
          <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div>
          <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div>

        </li>
        <li>

          <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div>
          <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div>
          <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div>
          <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div>
          <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div>
          <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div>

        </li>


      </ul>
    </div>

    <script>
      var title=document.getElementById('title');
      var content=document.getElementById('content');
      var category=title.getElementsByTagName('span');
      var item=content.getElementsByTagName('li');

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

          category[i].index=i;

          category[i].onclick=function(){

            for (var j = 0; j < category.length; j++) {
              category[j].className='';
              item[j].className='';
            }
            this.className='select';
            item[this.index].className='show';
          }


      }

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

7.作用域链

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>作用链域</title>
</head>
<body>
<script>
    var s = 12;
    function f() {
        console.log(s); //undefined
        var s=12;
        console.log(s);//12
    }
    f();
</script>
</body>
</html>

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

  • 全局作用域(Global Scope)

在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下几种情形拥有全局作用域:(1)最外层函数和在最外层函数外定义的变量拥有全局作用域

var name="yuan";

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

        inner();
    }

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

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

var name="yuan";

    function foo(){
        age=23;

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

变量age拥有全局作用域,而sex在函数外部无法访问到。
(3)所有window对象的属性拥有全局作用域
一般情况下,window对象的内置属性都拥有全局作用域,例如:window.alert(),window.location,window.top等。

  • 局部作用域(Local Scope)
    和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所以在某些地方这种作用域被称为函数作用域。

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

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

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

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

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

  console.log(s);
}

foo();

//-----***********************例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);

//-----********************************************************

结果分析
这里我们以例3来分析整个过程:当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充。在函数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这部操作是在词法分析时,即运行前完成的。
posted @ 2018-06-01 11:38  月缺一格  阅读(728)  评论(0编辑  收藏  举报