【js高级 Day5】深入理解浅拷贝,深拷贝,遍历DOM树,正则表达式

01 课程介绍

在这里插入图片描述

02 复习

apply和call方法的使用和区别

  • 都可以改变this指向的

使用方式:

  • 函数名.apply(对象,[参数1,参数2,参数3,…]);

  • 函数名.call(对象,参数1,参数2,参数3,…);

我想要使用其他对象的某个方法,其他对象.方法名.apply(当前对象,参数,…);
这个方法就会被当前的对象所使用,同时这个方法中的this就是当前的对象,在调用方法的时候改变了this的指向

bind方法的使用和区别
复制一个方法或者是函数,是在复制的同时改变了this的指向
使用方式:
函数名.bind(对象,参数1,参数2,…);------>返回值是复制之后的这个函数

高阶函数---->函数的使用的方式:函数作为参数使用,函数作为返回值使用
函数作为参数使用的时候,这个函数可以是匿名函数,也可以是命名函数

作用域和作用域链及预解析

闭包:函数中有另一个函数,或者是一个函数中有另一个对象,里面的函数或者是对象都可以使用外面函数中定义的变量或者数据,此时形成闭包

 function f1(num){

   return function(){
   console.log(num);
   }
 }

 f1(20);

闭包模式:函数模式闭包,对象模式的闭包
闭包的作用:缓存数据,延长作用域链,同时也是缺点,函数中的变量不能及时的释放

沙箱:就是一个环境,也可以叫黑盒,在这个环境中模拟外面真实的开发环境,完成需求,效果和外面的真实的开发环境是一样的
沙箱避免命名冲突

递归:函数中调用函数自己,递归一定要有结束的条件,否则就是死循环

递归:一般应用在遍历上
递归轻易不要用,效率很低,

 var num=100;
 (function () {
   var num=10;
   console.log(num);
 }());
 console.log(num);
 (function () {

 })();

03 浅拷贝

浅拷贝:拷贝就是复制,就相当于把一个对象中的所有的内容,复制一份给另一个对象,直接复制,或者说,就是把一个对象的地址给了另一个对象,他们指向相同,两个对象之间有共同的属性或者方法,都可以使用

var obj1={
  age:10,
  sex:"男",
  car:["奔驰","宝马","特斯拉","奥拓"]
};
//另一个对象
var obj2={};

写一个函数,作用:把一个对象的属性复制到另一个对象中,浅拷贝
把a对象中的所有的属性复制到对象b中

 function extend(a,b) {
    for(var key in a){
      b[key]=a[key];
    }
  }
  extend(obj1,obj2);
  console.dir(obj2);//开始的时候这个对象是空对象
  console.dir(obj1);//有属性

04 深拷贝

深拷贝:拷贝还是复制,深:把一个对象中所有的属性或者方法,一个一个的找到.并且在另一个对象中开辟相应的空间,一个一个的存储到另一个对象中

var obj1={
  age:10,
  sex:"男",
  car:["奔驰","宝马","特斯拉","奥拓"],
  dog:{
    name:"大黄",
    age:5,
    color:"黑白色"
  }
};

var obj2={};//空对象
//通过函数实现,把对象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(obj1,obj2);
console.dir(obj1);
console.dir(obj2);

05 遍历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>dsa</p>
    <h3>
      <span>dsads</span>
    </h3>
  </div>
</div>
//获取页面中的根节点--根标签
  var root=document.documentElement;//html
  //函数遍历DOM树
  //根据根节点,调用fn的函数,显示的是根节点的名字
  function forDOM(root1) {
    //调用f1,显示的是节点的名字
   // f1(root1);
    //获取根节点中所有的子节点
    var children=root1.children;
    //调用遍历所有子节点的函数
    forChildren(children);
  }
  //给我所有的子节点,我把这个子节点中的所有的子节点显示出来
  function forChildren(children) {
    //遍历所有的子节点
    for(var i=0;i<children.length;i++){
      //每个子节点
      var child=children[i];
      //显示每个子节点的名字
      f1(child);
      //判断child下面有没有子节点,如果还有子节点,那么就继续的遍历
      child.children&&forDOM(child);
    }
  }
  //函数调用,传入根节点
  forDOM(root);
  function f1(node) {
    console.log("节点的名字:"+node.nodeName);
  }

节点:nodeName,nodeType,nodeValue

第一个函数:给我根节点,我会找到所有的子节点:forDOM(根节点)
获取这个根节点的子节点

var children=根节点的.children

调用第二个函数

第二个函数:给我所有的子节点,我把每个子节点的名字显示出来(children)

for(var i=0;i<children.length;i++){
  每个子节点
  var child=children[i];
  f1(child);给我节点,我显示该节点的名字
  child是子节点,但是如果child里面还有子节点,此时child就是爹了
  child.children&&第一个函数(child)

}

06 正则表达式

正则表达式:也叫规则表达式,按照一定的规则组成的一个表达式,这个表达式的作用主要是匹配字符串的,
“我的电话:10086,他的电话:10010,你的电话:10000” 正则表达式,把这个字符串中的所有的数字找到

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

在大多数编程语言中都可以使用

正则表达式的组成:是由元字符或者是限定符组成的一个式子

元字符:

`.`  表示的是:除了\n以外的任意的一个字符   "fdsfs238"
[] 表示的是:范围,  [0-9] 表示的是09之间的任意的一个数字,  "789" [0-9]
[1-7] 表示的是17之间的任意的一个数字
[a-z] 表示的是:所有的小写的字母中的任意的一个
[A-Z] 表示的是:所有的大写的字母中的任意的一个
[a-zA-Z] 表示的是:所有的字母的任意的一个
[0-9a-zA-Z] 表示的是: 所有的数字或者是字母中的一个
[] 另一个函数: 把正则表达式中元字符的意义干掉    [.] 就是一个.
| 或者     [0-9]|[a-z] 表示的是要么是一个数字,要么是一个小写的字母
() 分组 提升优先级   [0-9]|([a-z])|[A-Z]
([0-9])([1-5])([a-z]) 三组, 从最左边开始计算
(()(()))
都是元字符,但是也可以叫限定符,下面的这些
  `*`   表示的是:前面的表达式出现了0次到多次
  [a-z][0-9]* 小写字母中的任意一个 后面是要么是没有数字的,要么是多个数字的
  "fdsfs3223323"  [a-z][0-9]*
  `+`  表示的是:前面的表达式出现了1次到多次
  [a-z][9]+  小写字母一个后面最少一个9,或者多个9
  "fesfewww9fefds"
  ?  表示的是:前面的表达式出现了0次到1,最少是0,最多1,另一个含义:阻止贪婪模式
  [4][a-z]? "1231234ij"
限定符:限定前面的表达式出现的次数
{} 更加的明确前面的表达式出现的次数
{0,} 表示的是前面的表达式出现了0次到多次,*一样的
{1,} 表示的是前面的表达式出现了1次到多次,+一样的
{0,1} 表示的是前面的表达式出现了0次到1,?一样的
{5,10} 表示的是前面的表达式出现了5次到10{4} 前面的表达式出现了4{,10} 错误的========不能这么写
^ 表示的是以什么开始,或者是取非(取反) ^[0-9] 以数字开头
^[a-z] 以小写字母开始
[^0-9] 取反,非数字
[^a-z] 非小写字母
[^0-9a-zA-Z_]
$ 表示的是以什么结束   [0-9][a-z]$  必须以小写字母结束
^[0-9][a-z] 相当于是严格模式   "3f2432e"  "4f"
 \d 数字中的任意一个,
 \D 非数字中的一个
 \s 空白符中的一个
 \S 非空白符
 \w 非特殊符号
 \W 特殊符号
 \b 单词的边界
 "what are you no sha lei"

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

[]  范围
() 分组,提升优先级
| 或者
* 0-多次
+ 1-多次
? 0-1{0,}*一样
{1,}+
{0,1}?
  
\d 数字中的一个
\D 非数字
\s 空白符
\S 非空白符
 \W  特殊符号
 \w 非特殊符号 _
 ^ 取反,以什么开始
 $ 以什么结束

07 正则表达式练习

写正则表达式,根据字符串来写正则表达式进行匹配

经验: 1.找规律 2.不要追求完美

身份证的正则表达式

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

练习:
1.座机号码的正则表达式
010-19876754
0431-87123490

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

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

2.qq号码的正则表达式

 [1-9][0-9]{4,10}
 \d{5,11}

3.手机号码的正则表达式

130 131 132 133 134 135 136 137 138 139
143 147
150 151 152 153 154 155 156 157 158 159
170 171 173 176 177
180 181 182 183 184 185 186 187 188 189

 ([1][358][0-9][0-9]{8})|([1][4][37][0-9]{8})|([1][7][01367][0-9]{8})
 \d{11}

邮箱的正则表达式,必须要记住的

 sd2113_3.-fd@itcast.com.cn
 [0-9a-zA-Z_.-]+[@][0-9a-zA-Z_.-]+([.][a-zA-Z]+){1,2}

08 创建正则表达式对象

1.通过构造函数创建对象

2.字面量的方式创建对象

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

//对象创建完毕---
  var reg=new RegExp(/\d{5}/);
 //字符串
  var str="我的电话是10086";
 //调用方法验证字符串是否匹配
  var flag=reg.test(str);
  console.log(flag);



 //对象创建完毕---
 var reg=new RegExp(/\d{5}/);
 //调用方法验证字符串是否匹配
 var flag=reg.test("我的电话是10086");
 console.log(flag);


  //字面量的方式创建正则表达式对象
  var reg=/\d{1,5}/;
  var flag=reg.test("小苏的幸运数字:888");
  console.log(flag);

09 识别正则表达式是否匹配

console.log(/[a-zA-Z]+/.test("hello"));
 
 console.log(/./.test("除了回车换行以为的任意字符"));//true
 console.log(/.*/.test("0个到多个"));//true
 console.log(/.+/.test("1个到多个"));//true
 console.log(/.?/.test("哈哈"));//true
 console.log(/[0-9]/.test("9527"));//true
 console.log(/[a-z]/.test("what"));//true
 console.log(/[A-Z]/.test("Are"));//true
 console.log(/[a-zA-Z]/.test("干啥子"));//false
 console.log(/[0-9a-zA-Z]/.test("9ebg"));//true
 console.log(/b|(ara)/.test("abra"));//true
 console.log(/[a-z]{2,3}/.test("arfsf"));//

浏览器显示结果
在这里插入图片描述

 console.log(/\d/.test("998"));
 console.log(/\d*/.test("998"));
 console.log(/\d+/.test("998"));
 console.log(/\d{0,}/.test("998"));
 console.log(/\d{2,3}/.test("998"));
 console.log(/\D/.test("eat"));
 console.log(/\s/.test("  "));
 console.log(/\S/.test("嘎嘎 "));
 console.log(/\w/.test("_"));
 console.log(/\W/.test("_"));

浏览器显示结果
在这里插入图片描述

10 案例验证密码的强度

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

密码: 数字,字母,特殊符号

密码: 只有数字- 或者是只有字母,或者是只有特殊符号—1级—弱
两两组合: 数字和字母, 数字和特殊符号, 字母和特殊符号 -----2级----中
三者都有: 数字和字母和特殊符号------3级-----强

 //获取文本框注册键盘抬起事件
  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";
    }


  };

  //给我密码,我返回对应的级别
  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
  }

11 案例验证用户输入的是不是邮箱

<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>

12 案例验证用户输入的是不是中文名字

<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="pink";
    }
  };
  //[\u4e00-\u9fa5]    [一-龥]
</script>

</body>

13 大案例验证表单

<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 src="common.js"></script>
<script>

  //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>

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

正则表达式中:g 表示的是全局模式匹配
正则表达式中:i 表示的是忽略大小写

  var str="中国移动:10086,中国联通:10010,中国电信:10000";
  //把里面所有的数字全部显示出来
  var array=str.match(/\d{5}/g);
  console.log(array);
var str = "123123@xx.com,fangfang@valuedopinions.cn 286669312@qq.com 2、emailenglish@emailenglish.englishtown.com 286669312@qq.com...";
var array = str.match(/\w+@\w+\.\w+(\.\w+)?/g);
console.log(array);

提取这里的日

var str="2017-11-12";
    var array=str.match(/(\d{4})[-](\d{2})[-](\d{2})/g);
    //console.log(array);
    //正则表达式对象.$3
    console.log(RegExp.$3);


    var email="shuaiyangtaishuaile@itcast.com.cn";
    email.match(/([0-9a-zA-Z_.-]+)[@]([0-9a-zA-Z_-]+)(([.][a-zA-Z]+){1,2})/);
    console.log(RegExp.$1);//用户名
    console.log(RegExp.$2);//126
    console.log(RegExp.$3);//域名


    var str="小苏好帅哦,真的是太帅了,帅,就是真帅";
    str=str.replace(/帅/g,"猥琐");
    console.log(str);

    var str="  哦买噶的    ,太幸福了  ";
    str=str.trim();
    console.log("==="+str+"===");


    var str = "  哦买噶的    ,太幸福了  ";
    str = str.replace(/\s+/g, "");
    console.log("===" + str + "===");

所有的h都替换成S

  var str="HhpphH";//SSppSS
    str=str.replace(/[h]/gi,"S");
    console.log(str);


    var reg = new RegExp(/[h]/gi);
    var str = "HhpphH";//SSppSS
    str = str.replace(reg, "S");
    console.log(str);


var str = "中国移动:10086,中国联通:10010,中国电信:10000";
//把里面所有的数字全部显示出来
//var array = str.match(/\d{5}/g);
//正则表达式对象.exec方法传入字符串
var reg=/\d{5}/g;
//var array=reg.exec(str);
console.log(array);
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));

var result=reg.exec(str);
while(result!=null){
  console.log(result);
  result=reg.exec(str);
}



var str = "中国移动:10086,中国联通:10010,中国电信:10000";
var reg=/\d{5}/g;
//通过正则表达式匹配这个字符串
var array=reg.exec(str);
console.log(array);
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));//null



var str = "中国移动:10086,中国联通:10010,中国电信:10000";
var reg=/\d{5}/g;
//通过正则表达式匹配这个字符串
var array=reg.exec(str);
while (array!=null){
  //输出匹配的内容
  console.log(array[0]);
  array=reg.exec(str);
}

15 伪数组和数组

伪数组和数组的区别
真数组的长度是可变的
伪数组的长度不可变
真数组可以使用数组中的方法
伪数组不可以使用数组中的方法

 function f1() {
   var sum=0;
   for(var i=0;i<arguments.length;i++){
     sum+=arguments[i];
   }
   console.log(sum);
 }
 //arguments得到的是实参的个数及实参的每个值
 f1(10,20,30,40);


  function f1() {
   var sum=0;
    arguments.forEach(function () {

    });
  }
  //arguments得到的是实参的个数及实参的每个值

  f1(10,20,30,40);

  var arr=[10,20,30];
  arr.forEach(function () {

  });



  var arr=[10,20];
  arr.forEach()
  console.dir(arr);

  数组实例对象的__proto__----->Array的prototype

  //数组
  var arr=[10,20,30];
  arr[3]=100;
  console.log(arr.length);
  //对象---假的数组
  var obj={
    0:10,
    1:20,
    2:30,
    length:3
  };

  console.log(obj[0]);
  console.log(obj[1]);
  console.log(obj[2]);
  console.log(obj.length);
  obj[3]=1000;
  console.log(obj[3]);
  console.log(obj.length);

  //遍历数组
  for(var i=0;i<arr.length;i++){
    console.log(arr[i]);
  }

  for(var i=0;i<obj.length;i++){
    console.log(obj[i]);
  }

其他参考链接

【js高级 Day1】深入理解原型及作用,构造函数和实例对象和原型对象之间的关系

【js高级 Day2】深入理解原型添加方法,私有函数,面向对象的编程思想(案例小贪吃蛇)

【js高级 Day3】深入理解原型的方式继承,借用构造函数继承,组合继承,拷贝继承

【js高级 Day4】深入理解apply和call方法,作用域,闭包,递归

【js高级 Day5】深入理解浅拷贝,深拷贝,遍历DOM树,正则表达式

【如果你是新手】推荐链接

【 js基础 Day1】js的介绍及基本语法变量,运算符

【 js基础 Day2】js的流程控制:分支语句,循环.顺序结构

【 js基础 Day3】关键字的使用,数组(重点)和函数(重点)

【 js基础 Day4】面向过程,面向对象,自定义对象,内置对象

【 js基础 Day5】函数(重点),作用域,预解析,arguments,对象

【 js基础 Day6】内置对象和基本包装类型等知识

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿珊和她的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值