JavaScript高级——04

目录

1.浅拷贝

2.深拷贝

3.遍历DOM树

4.正则表达式(Regular Expression)

4.1 正则表达式练习

4.2 创建正则表达式对象

4.3 正则表达式案例

4.3.1 验证密码强度

4.3.2 验证邮箱

4.3.3 验证中文名

4.3.4 验证表单

4.4 正则表达式其他方法的使用

4.4.1 字符串中的match方法 

4.4.2 字符串中的replace方法 

4.4.3 正则表达式的exec方法


  1. 基本数据类型(Undefined,Null,Boolean,Number、String、Symbol【ES6】)
  2. 引用数据类型(Object、数组、函数)

深拷贝和浅拷贝只针对Object和数组这两种引用数据类型

1.浅拷贝

浅拷贝:创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本数据类型,拷贝的就是基本数据类型的值;如果属性是引用类型,拷贝的就是内存地址 (指向同一个内存空间),所以如果其中一个对象改变了,就会影响到另一个对象。

分清浅拷贝和赋值的区别:

把一个对象赋值给一个新的变量时,赋的其实是该对象的在栈中的地址,而不是堆中的数据。也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,两个对象是联动的。

    //原对象
    var obj = {
        //第一层
        a:1,
        arr:['a','b'],
        say:function(){
            console.log('hello');
        },
        obj2:{
            //第二层
            a:2,
            arr:['c','d'],
            obj3:{
                //第三层
                say:function(){
                    console.log('world');
                }
            }
        }
    };

    //新对象
    var newObj={};

    //把a对象中的所有的内容复制到对象b中
    function extend(a,b) {
        for(var key in a){
            b[key]=a[key];
        }
    }

    extend(obj,newObj);

    //改变新对象的属性和方法(第一层)
    newObj.a='一';
    newObj.arr[1]='B';
    newObj.say=function(){
        console.log('new hello');
    };

    //改变新对象的属性和方法(第二层及更深层)
    newObj.obj2.a='二';
    newObj.obj2.arr[1]='D';
    newObj.obj2.obj3.say=function(){
        console.log('new world');
    };

    //打印新数组
    console.dir(newObj);
    newObj.say();
    newObj.obj2.obj3.say();

    //打印原数组
    console.dir(obj);
    obj.say();
    obj.obj2.obj3.say();

左边为新数组,右边为原数组:

结果:第一层中为基本数据类型的数据,其值没有随着另一个对象的值改变而改变,但第一层中数组的值改变了(数组是引用类型);而第二层及更深层中,所有的值都一同改变了(对象是引用类型,那么它的所有属性和方法也都会变)。

2.深拷贝

深拷贝:将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的内存存放新对象,且修改其中一个对象不会影响另一个对象。

  //原对象
    var obj = {
        //第一层
        a:1,
        arr:['a','b'],
        say:function(){
            console.log('hello');
        },
        obj2:{
            //第二层
            a:2,
            arr:['c','d'],
            obj3:{
                //第三层
                say:function(){
                    console.log('world');
                }
            }
        }
    };

    //新对象
    var newObj={};

    //通过函数实现,把对象a中的所有的数据深拷贝到对象b中
    function extend(a,b) {
        for(var key in a){
            //先获取a对象中每个属性的值
            var item=a[key];
            //判断这个属性的值是不是数组
            if(item instanceof Array){
                //如果是数组,那么在b对象中添加一个新的属性,并且这个属性值也是数组
                b[key]=[];
                //调用这个方法,把a对象中这个数组的属性值复制到b对象的数组属性中
                extend(item,b[key]);
            }else if(item instanceof Object){//判断这个值是不是对象类型的
                //如果是对象类型的,那么在b对象中添加一个属性,是一个空对象
                b[key]={};
                //再次调用这个函数,把a对象中这个对象的属性值复制到b对象的对象属性中
                extend(item,b[key]);
            }else{
                //如果值是普通的数据,直接复制到b对象的这个属性中
                b[key]=item;
            }
        }
    }

    extend(obj,newObj);

    //改变新对象的属性和方法(第一层)
    newObj.a='一';
    newObj.arr[1]='B';
    newObj.say=function(){
        console.log('new hello');
    };

    //改变新对象的属性和方法(第二层及更深层)
    newObj.obj2.a='二';
    newObj.obj2.arr[1]='D';
    newObj.obj2.obj3.say=function(){
        console.log('new world');
    };

    //打印新数组
    console.dir(newObj);
    newObj.say();
    newObj.obj2.obj3.say();

    //打印原数组
    console.dir(obj);
    obj.say();
    obj.obj2.obj3.say();

左边为新数组,右边为原数组:(可以看出原数组没有受到任何影响)

3.遍历DOM树

<h1>遍历 DOM 树</h1>
<p style="color: green;">Tip: 可以在遍历的回调函数中任意定制需求</p>
<div>
    <ul>
        <li>123</li>
        <li>456</li>
        <li>789</li>
    </ul>
    <div>
        <div>
            <span>haha</span>
        </div>
    </div>
</div>
<div id="demo_node">
    <ul>
        <li>123</li>
    </ul>
    <p>hello</p>
    <h2>world</h2>
    <div>
        <p>sfdbg</p>
        <h3>
            <span>mnjjlk</span>
        </h3>
    </div>
</div>
<script>
    //获取页面中的根节点--根标签
    var root=document.documentElement;//html
    //函数遍历DOM树
    //根据根节点,寻找所有子节点
    function forDOM(root1) {
        //获取根节点中所有的子节点
        var children=root1.children;
        //调用遍历所有子节点的函数
        forChildren(children);
    }
    //把所有子节点(某个节点的子节点集)中的所有的子节点显示出来
    function forChildren(children) {
        //遍历所有的子节点
        for(var i=0;i<children.length;i++){
            //每个子节点
            var child=children[i];
            //显示每个子节点的名字
            show(child);
            //判断child下面有没有子节点,如果还有子节点,那么就继续的遍历
            child.children&&forDOM(child);
        }
    }
    //函数调用,传入根节点
    forDOM(root);
    //显示节点名字
    function show(node) {
        console.log("节点的名字:"+node.nodeName);
    }
</script>

4.正则表达式(Regular Expression)

正则表达式的作用:匹配字符串

正则表达式的组成:是由普通字符(包括大小写的字母和数字)和一些元字符组成的一个式子

元字符:

.  除了\n以外的任意的一个字符

[] 范围;可以把正则表达式中元字符的意义去掉:[.] 就是一个.

[0-9]:0到9之间任意的一个数字

[1-7]:1到7之间任意的一个数字

[a-z]:所有小写字母中任意的一个

[A-Z]:所有大写字母中任意的一个

[a-zA-Z]:所有字母(大小写)中任意的一个

[0-9a-zA-Z]:所有的数字或者字母(大小写)中的一个

|  或者 

[0-9]|[a-z]:要么是一个数字,要么是一个小写的字母

() 分组,提升优先级 

([0-9])([1-5])([a-z]) :三组, 从最左边开始计算

限定符(也是元字符):限定前面的表达式出现的次数

* 前面的表达式出现了0次-多次

[a-z][0-9]*:小写字母中的任意一个,后面是要么是没有数字的,要么是多个数字的,可匹配 "fdsfs3223323"

+ 前面的表达式出现了1次-多次

 [a-z][9]+:小写字母中的任意一个,后面最少一个9,或者多个9,可匹配"fesfewww9fefds"

? 前面的表达式出现了0次-1次,最少是0次,最多1次;另一个含义:阻止贪婪模式(趋向于最大长度匹配,非贪婪匹配:匹配到字符就好,最少地匹配)

{} 更加明确前面的表达式出现的次数

{5,10} 表示的是前面的表达式出现了5次到10次

{4} 前面的表达式出现了4次

{0,} 和*一样

{1,} 和+一样

{0,1} 和?一样

^ 在[]外面时表示:以什么开始;在[]里面时表示:取非(取反)

^[0-9] 以数字开头

[^0-9] 取反,非数字

$ 以什么结束

[0-9][a-z]$  必须以小写字母结束

^[0-9][a-z]$ 相当于是严格模式   只能匹配"4f"这样的一个数字开头,一个小写字母结尾的字符

\d 匹配一个数字,等价于[0-9]

\D 匹配一个非数字字符,等价于[^0-9]

\s 匹配一个空白字符,包括空格、制表符、换页符和换行符

\S 匹配一个非空白字符

\w 匹配一个非特殊字符(字母、数字或者下划线即单字字符),等价于 [A-Za-z0-9_]

\W 匹配一个特殊字符(非单字字符),等价于 [^A-Za-z0-9_]

\b 单词的边界

4.1 正则表达式练习

1.身份证的正则表达式

15位或者18位

([1-9][0-9]{14})|([1-9][0-9]{16}[0-9xX]) 或者 ([1-9][0-9]{14})([0-9]{2}[0-9xX])?

2.座机号码的正则表达式

010-19876754  0431-87123490

[0-9]{3,4}[-][0-9]{8}或\d{3,4}[-]\d{8}

3.qq号码的正则表达式

 [1-9][0-9]{4,10}

4.邮箱的正则表达式

 sd2113_3.-fd@itcast.com.cn

[0-9a-zA-Z_.-]+[@][0-9a-zA-Z_.-]+([.][a-zA-Z]+){1,2}

4.2 创建正则表达式对象

通过构造函数创建正则表达式对象:

  1. 两个参数:new RegExp('正则表达式主体','修饰符(可选)');
  2. 一个参数:new RegExp(/正则表达式主体/修饰符(可选));
  • new RegExp('abc','i');
  • new RegExp(/abc/i);

正则表达式修饰符

  1. i:不区分大小写
  2. g:执行全局匹配(查找所有匹配,而不是在找到第一个匹配后停止)

4.3 正则表达式案例

4.3.1 验证密码强度

<style type="text/css">
    #dv {
        width: 300px;
        height: 200px;
        position: absolute;
        left: 300px;
        top: 100px;
    }

    .strengthLv0 { /*初始*/
        height: 6px;
        width: 120px;
        border: 1px solid #ccc;
        padding: 2px;
    }

    .strengthLv1 { /*弱*/
        background: red;
        height: 6px;
        width: 40px;
        border: 1px solid #ccc;
        padding: 2px;
    }

    .strengthLv2 { /*中*/
        background: orange;
        height: 6px;
        width: 80px;
        border: 1px solid #ccc;
        padding: 2px;
    }

    .strengthLv3 { /*强*/
        background: green;
        height: 6px;
        width: 120px;
        border: 1px solid #ccc;
        padding: 2px;
    }
</style>
<body>
<div id="dv">
    <label for="pwd">密码</label>
    <input type="text" id="pwd" maxlength="16">
    <div>
        <em>密码强度:</em>
        <em id="strength"></em>
        <div id="strengthLevel" class="strengthLv0"></div>
    </div>
</div>
<script>
    /*
    *
    * 密码: 数字,字母,特殊符号
    *
    * 密码: 只有数字,或者是只有字母,或者是只有特殊符号——1级——弱
    * 两两组合: 数字和字母,数字和特殊符号,字母和特殊符号——2级——中
    * 三者都有: 数字和字母和特殊符号——3级——强
    *
    * */
    function my$(id) {
        return document.getElementById(id);
    }

    /*//获取文本框注册键盘抬起事件
    my$("pwd").onkeyup = function () {
        //每次键盘抬起都要获取文本框中的内容,验证文本框中的内容,得到一个级别,然后下面的div显示对应的颜色
        //如果密码的长度是小于6的,没有必要判断
        if (this.value.length >= 6) {
            var lvl = getLvl(this.value);
            if (lvl == 1) {
                //弱
                my$("strengthLevel").className = "strengthLv1";
            } else if (lvl == 2) {
                my$("strengthLevel").className = "strengthLv2";
            } else if (lvl == 3) {
                my$("strengthLevel").className = "strengthLv3";
            } else {
                my$("strengthLevel").className = "strengthLv0";
            }
        } else {
            my$("strengthLevel").className = "strengthLv0";
        }
    };*/

    //获取文本框注册键盘抬起事件
    my$("pwd").onkeyup = function () {
        //每次键盘抬起都要获取文本框中的内容,验证文本框中有什么东西,得到一个级别,然后下面的div显示对应的颜色
        //如果密码的长度是小于6的,没有必要判断
        var lvl = getLvl(this.value);
        /*if (this.value.length >= 6) {
            my$("strengthLevel").className = "strengthLv" + lvl;
        } else {
            my$("strengthLevel").className = "strengthLv0";
        }*/
        my$("strengthLevel").className = "strengthLv" + (this.value.length >= 6 ?lvl: 0);
    };

    //根据密码,返回对应的级别
    function getLvl(pwd) {
        var lvl = 0;//默认是0级
        //密码中是否有数字,或者是字母,或者是特殊符号
        if (/[0-9]/.test(pwd)) {
            lvl++;
        }
        //判断密码中有没有字母
        if (/[a-zA-Z]/.test(pwd)) {
            lvl++;
        }
        //判断密码中有没有特殊符号
        if (/[^0-9a-zA-Z_]/.test(pwd)) {
            lvl++;
        }
        return lvl;//最小1,最大3
    }
</script>
</body>

  

4.3.2 验证邮箱

<body>
请输入邮箱:<input type="text" value="" id="email"/>*<br/>
<script>
    //如果输入的是邮箱,那么背景颜色为绿色,否则为红色
    //获取文本框,注册失去焦点的事件
    document.getElementById("email").onblur=function () {
        //判断这个文本框中输入的是不是邮箱
        var reg = /^[0-9a-zA-Z_.-]+[@][0-9a-zA-Z_.-]+([.][a-zA-Z]+){1,2}$/;
        if (reg.test(this.value)) {
            this.style.backgroundColor = "green";
        } else {
            this.style.backgroundColor = "red";
        }
    };
</script>
</body>

 

4.3.3 验证中文名

<body>
请输入名字:<input type="text" value="" id="userName"/>*<br/>
<script>
    //是中文名字,则绿色,否则红色
    document.getElementById("userName").onblur = function () {
        var reg = /^[\u4e00-\u9fa5]{2,6}$/;
        if (reg.test(this.value)) {
            this.style.backgroundColor = "green";
        } else {
            this.style.backgroundColor = "red";
        }
    };
    //[\u4e00-\u9fa5]    [一-龥]
</script>
</body>

4.3.4 验证表单

    <style type="text/css">
        body {
            background: #ccc;
        }

        label {
            width: 40px;
            display: inline-block;
        }

        span {
            color: red;
        }

        .container {
            margin: 100px auto;
            width: 400px;
            padding: 50px;
            line-height: 40px;
            border: 1px solid #999;
            background: #efefef;
        }

        span {
            margin-left: 30px;
            font-size: 12px;
        }
    </style>

</head>

<body>
<div class="container" id="dv">
    <label for="qq">Q Q</label><input type="text" id="qq"><span></span><br/>
    <label>手机</label><input type="text" id="phone"><span></span><br/>
    <label>邮箱</label><input type="text" id="e-mail"><span></span><br/>
    <label>座机</label><input type="text" id="telephone"><span></span><br/>
    <label>姓名</label><input type="text" id="fullName"><span></span><br/>
</div>
<script>
    function my$(id) {
        return document.getElementById(id);
    }

    //qq的
    checkInput(my$("qq"), /^\d{5,11}$/);
    //手机
    checkInput(my$("phone"), /^\d{11}$/);
    //邮箱
    checkInput(my$("e-mail"), /^[0-9a-zA-Z_.-]+[@][0-9a-zA-Z_.-]+([.][a-zA-Z]+){1,2}$/);
    //座机号码
    checkInput(my$("telephone"), /^\d{3,4}[-]\d{7,8}$/);
    //中文名字
    checkInput(my$("fullName"), /^[\u4e00-\u9fa5]{2,6}$/);

    //通过正则表达式验证当前的文本框是否匹配并显示结果
    function checkInput(input, reg) {
        //文本框注册失去焦点的事件
        input.onblur = function () {
            if (reg.test(this.value)) {
                this.nextElementSibling.innerText = "验证成功";
                this.nextElementSibling.style.color = "green";
            } else {
                this.nextElementSibling.innerText = "验证失败";
                this.nextElementSibling.style.color = "red";
            }
        };
    }

</script>
</body>

4.4 正则表达式其他方法的使用

4.4.1 字符串中的match方法 

4.4.2 字符串中的replace方法 

4.4.3 正则表达式的exec方法

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值