JavaScript知识点大总结来了-------这一篇就足够啦!!!

JavaScript基础知识

一、对象的使用

1、创建对象

这里创建对象的方法我们采用最常用的一种:

//第一种
<script>
    var Person = {
      name: "zhangsan",
      age: "19",
      weight: "140",
      hight: "170",
      print:function(){
        console.log("hi");
      } 
    };
</script>

//第二种
<script>
    var obj = new Object();//创建了一个空的对象
    obj.name = "zhangsan";
    obj.age = 19;
    obj.sayHi = function () {
      alert("hi");
    }

  </script>

//第三种,利用构造函数创建对象

/*

//构造函数的语法格式
    function 构造函数名(){
      this.属性名1 = 属性值1;
      this.属性名2 = 属性值2;
      this.属性名3 = 属性值3;
      this.方法名 = function(){}
    }
    //调用构造函数创建对象
    new 构造函数名();
*/
    
script>
    function Star(name, age, sex) {
      this.name = name;
      this.age = age;
      this.sex = sex;
      this.sing = function () {
        alert("情深深雨濛濛")
      }
    }

    var ldh = new Star("刘德华", 50, "男");
    ldh.sing();
  </script>



注意这里在声明对象里面的方法的时候和之前说的不一样!!!

2、 调用属性和方法

<script>
    var Person = {
      name: "zhangsan",
      age: "19",
      weight: "140",
      hight: "170",
      print: function () {
        alert("hi")
      }
    };

    document.write(Person.name);
    document.write(Person.print())

  </script>

3、遍历对象

<script>
    var obj = {
      name: "zhangsan",
      age: 18,
      sex: "man"
    }

    for (var k in obj) {
      console.log(k);//这个是属性名
      console.log(obj[k]);//这个就是属性值
    }
  </script>

二、JavaScript中的内置对象

1、Math对象

<script>
    //Math不是一个构造函数,不需要new对象来使用

    //圆周率 Math.PI
    //最大值 Math.max(1,54,9); //54
    //Math.max(1,54,"asda");  //NaN
    //Math.max();    //-Infinity

    //绝对值 Math.abs(-1); ----1
    //绝对值 Math.abs('-1'); ----1 隐式转换,会把字符类型的数据转换为数字类型
    绝对值 Math.abs('asfdia'); ---- NaN

    //向下取整 Math.floor(1.9); ----1
    //向上取整 Math.ceil(1.1); ----2
    //四舍五入 Math.round(1.1); ---

    //随机数
    Math.random();//  此函数返回一个浮点数,返回一个[0,1)的数值
    console.log(Math.random() * 100);
    //得到两个数之间的随机数,并且包含这两个数
    function getRandom(min, max) {
      console.log(Math.floor(Math.random() * (max - min + 1)) + min);
    }
    getRandom(1, 10);
  </script>
①、猜数字游戏
<script>
    function getRandom(min, max) {
      return Math.floor(Math.random() * (max - min + 1) + min);
    }

    var randomNumber = getRandom(1, 10);

    while (true) {
      var inputNumber = +prompt("请输入一个整数");
      if (randomNumber > inputNumber) {
        alert("猜小了");
      } else if (randomNumber < inputNumber) {
        alert("猜大了");
      } else {
        alert("猜对了");
        break;
      }
    }

  </script>

2、Date对象

创建一个Date对象

var d = new Date();//表示当前代码执行的时间
//创建一个指定的时间对象
//需要在构造函数中传递应该表示时间的字符串作为参数
var d = new Date("12/03/2024 12:22:54");
//日期的格式:月/日/年 时/分/秒
①、常用的方法
var d = new Date();
d.getDate();//获取当前的日期是几号
d.getDay();//返回日期是一周中的哪一天,0-6,0表示周日
d.getMonth();//获取月份。0-11,0表示一月,11表示12月
d.getFullYear();//获取年份

//时间戳指,1970年1月1日 0时0分0秒到当前日期所花的毫秒数
d.getTime();//获取当前日期对象的时间戳

//获取当前的时间戳
time = Data.now();

/*
利用时间戳来测试代码的执行时间
var start = Date.now();

for(var i = 0;i<100;i++){
	console.log(i);
}

var end = Date.now();
console.log(end-start);  
*/

3、String对象

在底层字符串时以字符数组的形式保存的,下标从0开始

①常用的方法
 var str = "hello world";
 str.length;//是记录字符串的长度
 str.charAt();//返回字符串中指定位置的字符
 str.charCodeAt();//返回指定位置字符的unicode编码
 String.fromCharCode();/根据字符编码区获取字符,得通过构造函数对象调用
 str.concat();//用来连接两个或者多个字符串
 str.indexOf();//该方法可以检索一个字符串中是否含有指定内容,如果字符串中含有该内容,则会返回其第一次出现的索引,如果没有,则返回-1,例:str.indexOf("h");
str.indexOf("d",0);//这第二个参数就是指定从第几次出现这个字符的位置开始查找,0表示从第一次指定字符出现的位置开始查找,1表示第二次
str.lastIndexOf();//该方法的和indexOf方法一样,只不过indexOf从前往后,lastIndexOf从后往前,也可以指定第二个参数
str.slice(0,2);//从字符串中截取指定的内容,不会影响原字符串,第一个参数是开始位置的索引(包括开始位置),第二个参数是结束位置的索引(不包括结束位置),如果省略第二个参数,则截取第一个参数后面所有的
str.substring();//也可以截取字符串,第一个参数是开始位置的索引(包括开始位置),第二个参数是结束位置的索引(不包括结束位置),如果省略第二个参数,则截取第一个参数后面所有的;但是不同的是,这个方法不能接收负值,有负值表示0
str.substr(1,2);//
//参数:
	1:截取开始位置的索引,
    2:截取的个数
str.split(",");//需要一个字符串作为参数,根据参数去拆分数组,返回值是一个数组

4、正则表达式

正则表达式用于定义一些字符串的规则:

计算机可以根据正则表达检查一个字符串是否符合规则
//创建正则表达式的对象

/*
语法:
	var 变量名 = new RegExp("正则表达式","匹配模式");
	使用typeof检查正则对象,会返回object
	
	在构造函数中,可以传递一个匹配模式作为第二个参数
		可以是:
			i:忽略大小写
			g:全局匹配模式
*/

	正则表达式的方法:
	test();
		用来检查一个字符串是否符合正则表达式的规则,符合返回true,否则返回false
        
    <script>
    var reg = new RegExp("a");//这个正则表达式用来检查字符串中是否含有a
    var str = "abc";
    var ret = reg.test(str);
    console.log(ret); // true

	var reg = new RegExp("A","i");//这个正则表达式用来检查字符串中是否含有a
    var str = "Abc";
    var ret = reg.test(str);
    console.log(ret); // true
    </script>
可以使用字面量创建正则表达式
/*
	①使用字面量创建正则表达式
	var 变量名 = /正则表达式/匹配模式
	
	例:
	<script>
    	var reg = /a/i
    	console.log(reg.test('bc'))//false
    	console.log(reg.test('ABC'))//true
   		console.log(reg.test('abc'))//true
  	</script>
  	
  	②创建一个正则表达式用来检测字符串中是否有a或者b,使用|,或者使用[],[]里面的内容也是或者的意思,[bc]就是b或者c的意思
  	<script>
   		 var reg = /a|b/i
    	 console.log(reg.test("a"))
   		 console.log(reg.test("bc"))
  </script>
  
  ③创建一个正则表达式用来检测字符串中是否有字母
  <script>
   		 //[a-z]表示任意的小写字母,[A-Z]表示任意的大写字母,[A-z]表示任意的字母,[0-9]表示任意数字
    	 var reg=/[a-z]/

   		 console.log(reg.test('a'))//true
   		 console.log(reg.test('A'))//false
  </script>
  
  ④创建一个正则表达式用来检测字符串中是否有abc或者adc或者aec
  <script>
    	var reg = /a[bde]c/

    	console.log(reg.test('abc'))//true
   		console.log(reg.test('adc'))//true
    	console.log(reg.test('acd'))//false
        console.log(reg.test('abd'))//false
    	console.log(reg.test('abf'))//false
  </script>
  
  ⑤[^ ]表示除了
  <script>
  		var reg=/[^ab]/
  		console.log(reg.test("abc"));//true
  </script>
*/
字符串和正则表达式一起使用
/*
	split()
	- 可以将一个字符串拆分成一个数组
	- 方法中可以传一个正则表达式作为参数,这样的方法将会根据正则表达式去拆分字符串
	例:根据任意的字符将字符串进行拆分
	注意:
	  这个方法不指定全局匹配都会给拆完
	<script>
    var str = "1a2b3c4d5f6e7";
    var ret = str.split(/[A-z]/);
    console.log(ret.length);
  	</script>
  	
  	search()
  	例:可以搜索字符串中是否含有指定内容
  	<script>
    var str = "hello abc bcd hello";
    var ret = str.search("abc"); 
    console.log(ret);//等于6,是从下标0开始数的
    //如果搜索到指定内容返回第一次出现的索引,否则返回-1,他可以接受正则表达式去检索字符串
    注意:
       search只会查找第一个,即使设置了全局匹配
    例:搜索字符串中是否含有abc 或者 aec或者 afc
     var str = "hello abc bcd afc aec";
    var ret = str.search(/a[bef]c/); 
  	</script>
  	
  	match()
  	可以根据正则表达式,从一个字符串中符合条件的内容提取出来
  	注意:
  	  一般情况下match只会找到第一个符合要求的内容,找到以后就停止检索,我们可以设置正则表达式为全局模式(写一个g),这样就会匹配到所有的内容
  	  可以为一个正则表达式设置多个匹配模式,且不用在意顺序
  	  match会将匹配到的内容封装到一个数组中,即使只有一个查询结果
  	var str = "1a2b3c4d5f6e7";
  	var ret = str.match(/A-z/);
  	
  	replace(参数1,参数2)
  	可以将字符串中指定的内容替换为新的内容
  	参数1:被替换的内容:可以接受一个正则表达式
  	参数2:新的内容
  	注意:
  	   默认只会替换第一个
  	var str = "1a2b3c4d5f6e7";
  	var ret = str.replace("a","@_@");
  	ret = str.replace(/a/gi,"@_@");
*/
量词
  • 通过量词可以设置一个内容出现的次数,{a}表示正好出现n次
    • var reg = /a{3}/;//这个就是aaa的表达
    • 注意:量词只对前面一个内容起作用
    • {m,n}表示出现m到n次
    • {m,}表示m次以上
    • +表示至少一个,即{1,}
    • *表示0个或者多个,相当于{0,}
    • ?0个或者1个,相当于{0,1}
⑤检查一个字符串是否以一个字符开头或者结尾
  • 使用^+字符

    • var reg = /^a/;//就是检查字符串是否是以一个字符开头
  • 使用字符+$

    • var reg = /a$/;//检查字符串是否是以指定字符结尾
  • 即使用^,有使用$

    • var reg = /^a$/;表示在正则表达式中只能有这个字符串
    • var reg = /^a|a$/;表示以a为开头或者以a结尾
⑥使用正则表达式检查电话是否符合规则
<script>
    var str = "18882636878";
    var reg = /^1[3-9][0-9]{9}$/;
    /*
      手机号规则:
         第一位以1开头
         第二位以3-9中的数字开头
         第三位及其以后只要是数字就行,但是最后必须以数字结尾
    */
    console.log(reg.test(str));
  </script>
⑦检查一个字符串中是否含有.
  • 但是在正则表达式中,光是写点表示任意字符
  • 像这样的还有很多
    • 表示\:使用两个\,即\
    • 表示.:使用.
    • \w:表示任意字母、数字、__
    • \W:表示除了字母、数字、__
    • \S:除了空格
    • \s:表示空格
    • \D:除了数字
    • \d:任意的数字,0-9
    • \B:除了单词边界
    • \b:单词边界
      • 创建一个正则表达式检测一个字符串中是否含有单词child
      • var reg = /\bchild\b/;

注意:使用构造函数的时候,由于它的参数是一个字符串,而\是字符串中转义字符,如果要使用\,就必须使用\\来代替

var str = "a.";
var reg = /\./;//要使用转义字符
console.log(reg.test(str));//true
⑧去除空格
  • 去除字符串前后的空格
  • 去除空格就是使用“”来替换空格
<script>
    var str = "     hel   lo       ";
    //去除开头的空格
    var str = str.replace(/^\s*/, "");
    //去除结尾的空格
    var str = str.replace(/\s*$/, "");
    //去除两端的空格
    var str = str.replace(/^\s*|\s*$/g, "");

    console.log(str);
  </script>
⑨判断一个字符串是否是电子邮件
 <script>
    /*
      电子邮件
          任意字母数字下划线 .任意字母数字下划线 @  任意字母数字 . 任意字母(2-5位)
    */
    var reg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;
    var email = "2326709846@qq.com";
    console.log(reg.test(email));
  </script>

三、DOM对象

节点

  • 文档节点:整个html文档
  • 元素节点:html文档中的html标签
  • 属性节点:元素的属性
  • 文本节点:html标签中的文本内容
<body>
  <button id="butId" name="btn">我是按钮</button>
</body>
<script>
  //通过id获取元素
  var but = document.getElementById("butId");
  //修改元素内容
  but.innerHTML = "我是一个大but";
  //通过name属性获取元素
  var btn = document.getElmentsByName("btn");
  //通过标签名获取元素
  var btn = document.getElementsByTagName("button");
</script>

1、事件

//点击事件,当用户点击按钮,就会弹出对话框
<button id="butId" onclick="alert('你点我干嘛')">我是按钮</button>
//双击事件
<button id="butId" ondblclick="alert('你点我干嘛')">我是按钮</button>
//鼠标移动事件
<button id="butId" onmousemove="alert('你别动')">我是按钮</button>

但是以上的写法,不推荐使用

请看在script标签里面的处理事件

<body>
  <button id="btnId">我是按钮</button>
</body>
<script>
  //获取按钮对象
  var btn = document.getElementById('btnId');
  //绑定单击事件
  btn.onclick = function () {
    alert('按钮被点击了');
  }
</script>

2、获取元素节点的子节点

<body>
 <ul id="city">
   <li>成都</li>
   <li>北京</li>
   <li>上海</li>
   <li>广州</li>
 </ul>
</body>
<script>
 //获取所有的子元素的节点
 var city = document.getElementById("city");
 var lis = city.childNodes;
 /*
   这里的childNodes方法会获取包括文本节点在内的所有节点,注意并不是只有标签
   这里的文本节点就是回车键,所以length就是9
 */

 /*
 children属性可以获取的当前元素的所有子元素,但是不包括文本节点,就是只有标签
 */
 var lis2 = city.children;

 //获取第一个子元素
 /*
   firstChild属性可以获取到当前元素的第一个子节点(包括空白文本节点)
 */
 var firstli = city.firstChild;

 /*
 firstElementChild属性可以获取到当前元素的第一个子元素(不包括空白文本节点)
 但是不支持ie8及以下,
 如果需要兼容ie8及以下,则需要判断
 */
 var first = city.firstElementChild;


 //获取最后一个子元素
 /*
   lastChild属性可以获取到当前元素的最后一个子节点(包括空白文本节点)
 */

 var lastli = city.lastChild;

 /*
 lastElementChild属性可以获取到当前元素的最后一个子元素(不包括空白文本节点)
 但是不支持ie8及以下,
 如果需要兼容ie8及以下,则需要判断
 */
 var last = city.lastElementChild;
</script>

3、获取父节点和兄弟节点

<body>
  <ul id="city">
    <li>成都</li>
    <li id="bj">北京</li>
    <li>上海</li>
    <li>广州</li>
  </ul>
</body>
<script>
  //获取当前节点的父节点
  var bj = document.getElementById("bj");
  var bjParent = bj.parentNode;
  //console.log(bjParent);
  //获取当前节点的前一个兄弟节点,当然也可能获取到空白的文本
  var bjBorther = bj.previousSibling;
  //获取前一个兄弟元素,不包括空白的文本,但是ie8以及之前版本不支持
  var bjBorther2 = bj.previousElementSibling;
  //console.log(bjBorther);
  console.log(bjBorther.innerHTML);
  //获取当前节点的后一个兄弟节点
</script>
4、querySelect选择器选择元素
//document.querySelect这个方法,只会返回一个值,即使匹配的元素有多个也只会返回一个
//document.querySelectSAll这个方法可以返回多哥符合条件的元素


5、dom的增删改

①增
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <ul id="city">
    <li>成都</li>
    <li>北京</li>
    <li>上海</li>
    <li>广州</li>
  </ul>


  <input type="button" id="btn" value="add" />
</body>
<script>

  var btn = document.getElementById('btn');
  btn.onclick = function () {
    //创建一个重庆节点添加到ul下面

    //创建li元素节点
    /*
    该方法用于创建一个元素节点对象,
    需要一个标签名作为参数,并将创建好的元素对象返回
    */
    var li = document.createElement('li');

    //创建广州文本节点
    /*
     *document.createTextNode
     *用来创建一个文本节点对象
     需要文本内容作为参数,并将创建好的文本节点对象返回
     */
    var cqText = document.createTextNode('重庆');

      
      
      
    //将cqText设置为li的子节点
    /***
     * appendChild
     * 将一个节点对象作为子节点添加到父节点中
     * 需要一个子节点对象作为参数
     * 父节点.appendChild(子节点)
     */
    li.appendChild(cqText);


    //获取city元素节点
    var city = document.getElementById('city');
    //将li设置为city的子节点
    city.appendChild(li);
  }


</script>

</html>
②插入
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <ul id="city">
    <li>成都</li>
    <li id="bj">北京</li>
    <li>上海</li>
    <li>广州</li>
  </ul>


  <input type="button" id="btn" value="insert" />
</body>
<script>
  //将重庆节点插入到北京前面
  var btn = document.getElementById('btn');
  btn.onclick = function () {
    //创建一个重庆节点添加到ul下面

    //创建li元素节点
    /*
    该方法用于创建一个元素节点对象,
    需要一个标签名作为参数,并将创建好的元素对象返回
    */
    var li = document.createElement('li');

    //创建广州文本节点

    var cqText = document.createTextNode('重庆');
    //将cqText设置为li的子节点

    li.appendChild(cqText);

    //获取bj节点
    var bj = document.getElementById('bj');

    var city = document.getElementById('city');
    //将li节点插入到bj节点的前面

    /***
     * insertBefore可以在指定的子节点面前插入新的子节点
     * 语法:父节点.insertBefore(新节点,参照节点)
     * 
    */
    city.insertBefore(li, bj);
  }

</script>

</html>
④替换
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <ul id="city">
    <li>成都</li>
    <li id="bj">北京</li>
    <li>上海</li>
    <li>广州</li>
  </ul>


  <input type="button" id="btn" value="replace" />
</body>
<script>
  //将北京节点替换为重庆节点
  var btn = document.getElementById('btn');
  btn.onclick = function () {
    //创建一个重庆节点添加到ul下面

    //创建li元素节点
    var li = document.createElement('li');

    //创建广州文本节点
    var cqText = document.createTextNode('重庆');

    //将cqText设置为li的子节点
    li.appendChild(cqText);

    //获取bj节点
    var bj = document.getElementById('bj');

    //获取city
    var city = document.getElementById('city');

    //开始替换
    /***
     * 可以使用指定的子节点替换已有的子节点
     * 语法
     *  parentNode.replaceChild(newChild,oldChild);
     *   parentNode:父节点
     *   newChild:要插入的节点
     *   oldChild:要替换的节点
     */



    city.replaceChild(li, bj);
  }

</script>

</html>
⑤删除
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <ul id="city">
    <li>成都</li>
    <li id="bj">北京</li>
    <li>上海</li>
    <li>广州</li>
  </ul>


  <input type="button" id="btn" value="erase" />
</body>
<script>
  //将北京节点删除
  var btn = document.getElementById('btn');
  btn.onclick = function () {
    //获取bj节点
    var bj = document.getElementById('bj');
    //获取city节点
    var city = document.getElementById('city');
    //删除bj节点
    /****
     * removeChild
     *  可以删除一个子节点
     *  语法:
     *     父节点.removeChild(子节点)
     */
      
	//知道父元素删除子节点
    、、city.removeChild(bj);
      
    //不使用父元素删除子节点
    bj.parentNode.removeChild(bj);//这个最常用

  }
</script>
</html> 
⑥关于innerHTML的用法
//读取city里面的html代码

<body>
  <ul id="city">
    <li>成都</li>
    <li id="bj">北京</li>
    <li>上海</li>
    <li>广州</li>
  </ul>

  <input type="button" id="btn" value="read" />
</body>
<script>
  var btn = document.getElementById('btn');
  btn.onclick = function () {
    var city = document.getElementById('city');
    alert(city.innerHTML);

  }

</script>

//设置bj节点里面的html代码

<body>
  <ul id="city">
    <li>成都</li>
    <li id="bj">北京</li>
    <li>上海</li>
    <li>广州</li>
  </ul>

  <input type="button" id="btn" value="edit" />
</body>
<script>
  var btn = document.getElementById('btn');
  btn.onclick = function () {
    var bj = document.getElementById('bj');
    bj.innerHTML = '南京';
  }
</script>

//使用innerHTML实现添加的操作

<body>
  <ul id="city">
    <li>成都</li>
    <li id="bj">北京</li>
    <li>上海</li>
    <li>广州</li>
  </ul>

  <input type="button" id="btn" value="add" />
</body>
<script>
  var btn = document.getElementById('btn');
  btn.onclick = function () {
    var city = document.getElementById('city');
    city.innerHTML += "<li>重庆</li>"
  }

</script>

四、BOM对象

BOM对象就是浏览器对象,BOM对象比DOM大

1、定时器-延时对象

/*
仅仅只执行一次,代码延时	
*/
setTimeout(回调函数,延时的时间(毫秒));


var time = setTimeout(回调函数,等待的毫秒数);
//清除延时函数
clearTimeout(time);

2、location对象

关于location对象它拆分并保存了URL地址的各个组成部分

//常用的方法和属性
 属性:
   ①href:获取完整的URL地址,对其赋值时用于地址的跳转
//例:用户点击跳转,如果不点击,则在	5秒之后跳转,要求里面有秒数倒计时
   <!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<style>
  span {
    color: red;
  }
</style>

<body>
  <a href="http://www.itcast.cn">支付成功<span>5</span>秒钟跳转到首页</a>
</body>
<script>
  const a = document.querySelector('a');
  let num = 5
  let timer = setInterval(function () {

    num--;
    a.innerHTML = `支付成功<span>${num}</span>秒钟跳转到首页`

    if (num === 0) {
      clearInterval(timer);
      location.href = 'http://www.itcast.cn'
    }
  }
    , 1000);
</script>
</html>


   ②search属性获取url(网址)中?后面的内容
   ③hash获取地址(url)中的哈希值,#后面的内容
   ④reload方法用于刷新当前新页面,	传入true参数时表示强制刷新

3、navigator对象

//该对象记录了浏览器自身的相关信息
常用的属性和方法:
  userAgent检测浏览器的版本和平台

  例:
  <!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <script>
    !(function () {
      const userAgent = navigator.userAgent;
      //验证是否为Android或iphone
      const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/);
      const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/);

      //如果是android或者iphone跳转到至移动站点
      if (android || iphone) {
        location.href = "http://m.itcast.cn";
      }
    })();
  </script>
</head>
<body>
  这是pc端
</body>
</html>

4、history对象

//该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等
常用的方法或属性:
 back():后退功能
 forward():前进功能
 go(参数):参数1:前进一个页面,-1:后退一个页面

5、本地存储localStorage

本地存储只能存储字符串类型的数据

//存储一个名字 uname:dxy

//用法:localStorage.setItem("键","值");
  localStorage("uname","dxy");
  
//获取数据
//用法:var uname = localStorage.getItem("键");

//删除数据
	//用法:localStorage.removeItem("键");
localStorage.removeItem("uname");

本地存储复杂数据类型

<script>
    var obj = {
      uname: "dxy",
      age: 18,
      sex: "男"
    }

    //本地存储复杂数据类型
    /***
     * 注意:
     * 第一个obj是键,第二个才是我们创建的对象值
     localStorage.setItem("obj", obj);
     * 但是无法直接使用所存的值
     * 
     * 解决方法:
     * 需要将复杂数据类型转换为JSON字符串的数据类型
     * 语法:JSON.stringify(obj)
     */
    //存
    localStorage.setItem("obj", JSON.stringify(obj));

    //取
    //把JSON字符串转换为对象
    JSON.parse(localStorage.getItem("obj")); 
  </script>

五、javascript进阶

1、垃圾回收机制

  • 关于全局变量的话,一般不会回收(在关闭页面的时候进行回收)

  • 一般情况下局部变量的值,不用了,会被自动回收掉

  • 内存泄漏:程序中分配的内存由于某种原因未被释放获取无法释放

2、闭包

概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域

简单理解:闭包=内层函数+外层函数的变量

简单的Demo理解:

function outer(){
	const a=1;
	function f(){
	console.log(a);
	}
	f();
}

outer();

常见的Demo形式:(外部可以访问使用 函数内部的变量)

function outer(){
	const a=1;
	function f(){
	console.log(a);
	}
	return f;
}
const fun = oute();

fun();

闭包的应用:实现数据的私有

function fn() {
    let count = 0
    function fun() {
      count++;
      console.log(`函数被调用${count}`)
    }
    return fun;
  }

  const ret = fn();
  ret();

//这个count不会被回收

3、箭头函数

语法:

const fn = () =>{函数体}
fn();

//只有一个形参的时候:可以省略小括号
const fn = x =>{
    console.log(x);
}
fn(1);

//只有一个形参的时候:还可以省略大括号
const fn = x => console.log(x);
fn(1);

//只有一个形参的时候,如果有返回值,可以省略return
const fn = x =>x+x
console.log(fn(1)); 

//箭头函数可以直接返回一个对象
const fn = (uname) => ({uname:uname})//第一个参数是属性名,第二个是属性值

console.log(fn("刘德华"));


//箭头函数没有arguments参数,但是有剩余参数
const getSum = (...arr) => {
    let sum = 0;
    for(let i;i<arr.length;i++){
        sum+=arr[i];
    }
    return sum;
}
getSum(2,3);

//箭头函数的this指向的是上一层的this 
<script>
const fn = () => {
    console.log(this);//window,并不是箭头函数里面的this,而是上一层,就是script标签里面的
}
fn();
</script>

//对象方法箭头函数 this
<script>
	const obj = {
        uname:"dxy"sayHi:() => {
			console.log(this);//这个this就是obj
        }
    }    
    
    obj.sayHi();
</script>

const obj = {
    uname:"dxy",
    sayHi:function () {
        console.log(this)
        let i = 10;
        const count = () => {
            console.log(this)//这个this就是obj
        }
        count();
    }
}
obj.sayHi();

4、变量提升

在代码加载前,把变量声明提前,但是不会赋值

<script>
    //变量提升,但是只会提升到当前作用域,比如在函数里面,就只会提升到函数作用域
    //相当于 var name;但是不赋值
    console.log("我是" + name);
    var name = "小明";//结果就是我是undefined
  </script>

5、动态参数

<script>
    //动态参数

    function fun() {
      let sum = 0;
      for (var i = 0; i < arguments.length; i++) {
        sum += arguments[i];
      }
      console.log(sum);
    }
    fun(2, 3);



  </script>

6、剩余数组

<script>
    //剩余参数

    function fun(a, b, ...arr) {
      let sum = 0;
      for (let i = 0; i < arr.length; i++) {
        //arr中就是6和7
        sum += arr[i];
      }
      sum += a + b;
      console.log(sum);
    }
    fun(2, 3, 6, 7);//18
  </script>

7、数组解构

<script>
    //第一种
    let a = 1
    let b = 2
    //数组开头的前面必须加分号
    ;[a, b] = [b, a];
    console.log(a, b)

	//第二种
	const [max, min, mid] = [100, 20, 50]
    console.log(max, min, mid)//100 20 50

  </script>

8、对象解构

<script>
    //对象解构  
    const { uname, age, sex } = { uname: "张三", age: 18, sex: "男" }
    /*等价于
    const uname = "张三"
    const age = 18
    const sex = "男"
    */
    console.log(uname, age, sex)

  </script>

注意:

  • 必须保证属性名和变量名一致
  • 变量名可以重新命名,格式:旧属性名:新变量名
    • const {uname:username,age,sex} = {uname: "张三", age: 18, sex: "男"}
①解构数组对象
<script>
    const [{ uname, age }] = [{
      uname: "佩奇",
      age: 6
    }]
    console.log(uname, age);

  </script>
②多级对象解构
<script>
    const pig = {
      name: '佩奇',
      family: {
        mother: '米老鼠',
        father: '小红帽'
      },
      age: 6
    }

    const { name, family: { mother, father }, age } = pig
    console.log(name, mother, father, age)

  </script>

9、遍历数组元素(foreach)

<script>
    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    arr.forEach(function (item, index) {
      //item是数组元素
      //index是数组元素的索引
      console.log(item, index);
    })

  </script>

10、构造函数

<script>
    //这样子就不用每次都写很多代码,可以直接封装成一个函数,new 对象时进行调用
    function Pig(name, age) {
      this.name = name;
      this.age = age;
    }

    const pig1 = new Pig('小猪1', 3);
    const pig2 = new Pig('小猪2', 5);
    console.log(pig1, pig2);


  </script>

11、原型对象

<script>
    function Person(name,age){
        this.name = name
        this.age = age
    }

    //原型就相当于是一个对象,
    /*
        原型的作用:
          ①共享两个对象中相同的方法
          ②可以把不变的方法,直接定义在prototype对象上面
        注意:
          在使用原型的时候,将属性就写在构造函数中,
          而不变的方法就可以使用原型,这样就不用开辟新的地址了
    */

    //原型的使用
    /*
        注意:原型对象中的this还是指向的是实例化对象
        所以在构造函数和原型对象中,this都指向实例化对象
    */
    Person.prototype.sayHi = function(){
        alert("hi")
    }

    const p1 = new Person("张三",18)
    p1.sayHi()

</script>
①使用原型 对数组扩展方法:求和和求最大值、最小值
script>
    //最大值
    Array.prototype.max=function(){
        //展开运算符
        return Math.max(...this)
        //原型对象中的this指向实例化对象
    }

    //最小值
    Array.prototype.min=function(){
        //展开运算符
        return Math.min(...this)
        //原型对象中的this指向实例化对象
    }

    //求和
    Array.prototype.sum=function(){
        //箭头函数:一个以上的参数,就必须带小括号,只有一句代码,可以不用写大括号
         return this.reduce((prev,item)=>prev+item,0)
    }

    alert([1,2,3,4].min())
    alert([1,2,3,4].max())
    alert([1,2,3,4].sum())
</script>

12、原型对象中的constructor属性

<script>
    /*
        constructor属性是原型对象里面的属性
        作用:该属性指向该原型对象的构造函数

    function Person(){
     
    }
    Person.prototype.constructor===Person//是true
    
    */
   function Star(){

   }

   Star.prototype={
    //这样就是直接赋值,就会覆盖掉之前的原本的属性、函数等,
    //所以要使用constructor属性让他找到自己的父亲
    //加上这行代码
    constructor:Star,//重新指回创造这个原型对象的构造函数
    sing:function(){
        console.log("sing")
    },
    dance:function(){
        console.log("dance")
    }
   }

</script>

13、对象原型

在这里插入图片描述

对象都会有一个属性__proto__(两个下划线)指向构造函数的prototype原型对象,使得我们对象才可以使用构造函数prototype原型对象的属性和方法

注意:

  • __proto__不是js的标准属性
  • [[prototype]]和__proto__意义相同
  • __proto__用来表明当前的实例对象指向哪个原型对象prototype
  • __proto__对象原型里面也有一个constructor属性,指向创建该实例对象的构造函数

在这里插入图片描述

14、原型继承

 <script>
  function Person() {
    this.eyes = 2;
    this.head = 1;
  }

  function Woman() {

  }

  //让woman继承person
  Woman.prototype = new Person();
  
  //再指回原来的构造函数
  Woman.prototype.constructor = Woman;

  const woman = new Woman();
  console.log(woman.eyes);
</script>

15、原型链

在这里插入图片描述

查找规则:

  • ①当访问对象的属性时,先找该对象是否有这个属性
  • ②如果没有就查找它的原型(就是__proto__指向的prototype原型对象)
  • ③如果还没有就找原型对象的原型(Object的原型对象)
  • ④以此类推直到找到Ojbect为止
  • ⑤__proto__对象原型的意义就在于为对象成员机制提供一个方向,或者说一条路线
  • ⑥可以使用instanceof运算符用于检查构造函数的prototype属性是否出现在某个实例对象的原型链上面

16、深浅拷贝

(1)浅拷贝

有两种方法

<script>
  const obj = {
    name: '张三',
    age: 18
  }

  //第一种使用展开运算符
  const o1 = { ...obj };
  console.log(o);

  //第二种使用Object.assign()
  const o2 = {};
  Object.assign(o2, obj);
  console.log(o2);
</script>

注意:浅拷贝在拷贝对象的时候,只能把对象里面单层的属性或方法拷贝,如果该对象中,还有对象,就实现不了拷贝的功能

(2)深拷贝
  • 深拷贝通过使用函数递归的方式实现

  • 使用lodash库方法

    •   <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
        <script>
        const obj = {
            name: '张三',
            age: 18,
            family: {
              dad: "李四"
            }
          }
        
          //使用lodash库的cloneDeep方法深拷贝对象
          const newObj = _.cloneDeep(obj);
        
          console.log(newObj); // 输出:{ name: '张三', age: 18 }
        
        </script>
      
  • 使用json实现深拷贝

    •   <script>
          const obj = {
            name: '张三',
            age: 18,
            family: {
              dad: "李四"
            }
          }
        
          //使用json的形式实现深拷贝
          const obj1 = JSON.parse(JSON.stringify(obj));
          console.log(obj1);
        
        </script>
      

17、异常处理

(1)抛出异常

使用throw关键字,会终止程序,经常和error一起使用

  •   <script>
        function func(x, y) {
          if (!x || !y) {
            throw new Error('x和y不能为空');
          }
          return x + y;
        }
      
        console.log(func());
      </script>
    
  • 在这里插入图片描述

(2)try/cathch捕获异常
<script>
  function func() {
    try {
      const p = document.querySelector(".p");
      p.style.color = "red";
    } catch (error) {
      //拦截错误,不会中断程序的执行,提示浏览器提供的错误信息
      console.log(error.message)
      return
    } finally {
      //不管代码对不对,程序都会执行
      console.log("finally")
    }
  }
</script>

18、改变this指向

  • 使用call方法(了解)

  • 使用apply方法(理解)

    • 语法:f.apply(thisArg,[argArray])

      • thisArg:在fun函数运行时指定的this值
      • argArray:传递的值,必须包含在数组里面
      • 返回值就是函数的返回值
    •   <script>
          const obj = {
            name: '123'
          }
          function f() {
            console.log(this);
        
          }
          f();
          f.apply(obj);
        </script>
      
    • 实例:使用Math.max()求数组中的最大值

      •   <script>
            console.log(Math.max.apply(Math, [1, 2, 3]));
          </script>
        
  • 使用bind方法(掌握)

    • 不会调用函数

    • 语法:f.bind(thisArg,arg1,arg2,····)

      • thisArg:在fun函数运行时指定的this值

      • arg1,arg2:传递的参数

      • 返回是一个函数,但是这个函数里面的this是被更改过的

      •   <script>
            const obj = {
              age: 18
            }
            function f() {
              console.log("ad");
            }
            console.log(f.bind(obj))
          </script>
        

综上:call和apply在执行时,会调用函数,而且改变this指向,bind方法不会调用函数,并且会改变this指向

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

要努力点

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

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

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

打赏作者

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

抵扣说明:

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

余额充值