首页 >工作总结 > 内容

js部分笔记

2023年9月22日 00:21

js 基础 ---->js高级

day01

js的三个书写方式

1.行内式

2.内嵌式

3.外链式

四个常用的js方法

alert()提示弹框

prompt()弹出输入框

console.log ( ) 控制台输出消息

document.write( ) 把内容写入页面body 里面

变量命名规范

1.能使用那些符合规格的字符:数字,字母,$符,_下划线。

2.不能用数字开头

3.不能使用js里面具有特殊功能的单词-------关键字、保留字。

4.区分大小写

5.命名语义化----建议使用驼峰命名(多个单词的组合)

​ 大驼峰:所有单词首字母大写;

​ 小驼峰:第一个单词首字母小写,其他单词首字母大写

数据类型:

基本数据类型(值类型、简单数据类型):number ,string , boolean ,null ,undefined ,es6新增symbol

复杂数据类型(引用类型):函数Function,数组Array,对象Object,时间Date,正则表达式RegExp

类型转换 (三种):

1.其他转为数字:number()、parseInt()、parseFloat ( )

Number(数据) // 把其他的类型转换为数字
parseInt(数据) // 把字符串转换为整数
parseFloat(数据) // 把字符串转换为小数

2.其他转为字符串:String()、. toString()

String(数据)
(数据).toString() // 小数和null、undefined在使用的时候要小心

3.其他转为布尔:Boolean()

以下6种情况会转为false ,其他转为true

0,’ ‘,false,null,undefined,NaN。

day02

一、操作符

运算符 + - * / %

+ 操作符的作用有:

  1. 字符串相连
  2. 数字相加
1. 字符串 + 其他 = 字符串会把其他类型 转换为 字符串 , 两个字符串连接到一起2. 数字 + 数字 = 数字会把其他类型 转换为 数字 ,再相加

-操作符的作用就是数字相减

- 都是优先把非数字的转换为数字,再运算var res3 = '456' - 123; console.log(res3); // 输出 数字 333var res4 = 'abc' - 123;console.log(res4); // 输出NaN这是因为,数字和字符串在相减的过程中,会把字符串隐式转换成数字,再相减。但是如果字符串在转换的过程中,无法转换成数字,就会转换成NaN,再计算就无法得到一个正确的数字结果

*操作符的作用是两个数字相乘

/操作符的作用是两个数字相除

%操作符的作用是两个数字求模(得到余数)

a % b  取模运算:a能不能被b整除  无法整除的部分就是余数    取模就是 得到a除以b的余数      比如:奇偶数判断

隐式转换

隐式转换是指在数据在参与运算的过程中,数据根据操作符的运算规则自动进行的数据类型转换

  • 加法会发生字符串拼接的情况
  • 减法、乘法、除法……默认都会调用Number( )

比较运算符

<  >      >=  <= 以上都是和数学里面的比较是一样的规则==   判断两个值是否相等(数字和字符串)console.log(5 % 2 == 0);!=  判断两个值不相等console.log(5 % 2 != 0);===  判断类型和值是否相等console.log(undefined === null);!==  判断类型和值是否不相等  //特殊的 NaN 和谁都不相等  也不等于自己// 如何验证一个数据, 不是NaN//  isNaN(数据) 判断一个数据是否是NaNconsole.log(isNaN(NaN)) //  NaN是一个NaN, 所以得到的是trueconsole.log(isNaN(123)) //  123不是一个NaN, 所以得到的是false

补充算术操作符

自增自减运算符 ++ – 自增和自减用法一样

数据++;
++数据;

  • 不同点(在运算中):

    • 数据++ 先拿数据原本的值进行计算,计算完后,再自增
    • ++数据 先自增,自增的结果来参与计算

赋值操作符

  赋值运算符  =  执行过程: 先执行 = 右边的代码,得到结果,再给 = 的左边  var num = 30;  // num = num + 20;  // 简写方式  num += 20;  console.log(num); // 50  // -= *= /= %=  

逻辑操作符

逻辑运算符的主要作用是连接多个条件,我们要掌握的比较运算符有

&&    ||

&& 用在需要多个条件同时成立的时候

// 用户在登录的时候要用户名和密码同时正确才能登录var userName = prompt('请输入用户名');var password = prompt('请输出密码');console.log(userName === 'admin' && password === '123456');// 只有 && 两边的 结果都是 true ,最终结果才是 true

|| 用在只需要任意条件成立的时候

// 只要年龄小5岁或者身高小于120cm就可以免费乘坐var age = parseInt(prompt('请输入你的年龄'));var height = parseFloat(prompt('请输入你的身高'));console.log(age < 5 || height < 120);// 只要 || 两边的结果有一个是true,最终结果就是true

! 用于颠倒是非的时候

var res = true;console.log(!res);console.log(!!res);// 转布尔值// 这里暂时用不到,在后面做具体效果的时候都用,那个时候我们再学习具体的使用

操作符的优先级

观察代码

var res = 5 + 2 * 3;console.log(res); // 11

在上述代码中,执行过程是先计算 2*3 再和 5 相加的。在js中的操作符很多,我们要认识到它们之间是有计算的优先顺序的,这个优先顺序我们称为优先级

记忆一下下面的计算优先级

1. 第一优先级: . [] ()                 字段访问、数组下标、函数调用2. 第二优先级: ++ -- !一元运算符3. 第三优先级: *  /  %二元运算符 乘法、除法、取模4. 第四优先级: +  -二元运算符 加法、减法5. 第五优先级: >   >=   <   <=         比较运算符6. 第六优先级: ==   !=    ===    !==   比较运算符7. 第七优先级: &&逻辑与8. 第八优先级: || 逻辑或9. 第九优先级: = += -= *= /= %=        赋值

上面是具体的优先级,但是平时我们不会把很多的操作符放在一起运算,所以我们大致记住

  1. 括号先算
  2. 其次算算术
  3. 再次算比较
  4. 然后算逻辑
  5. 最后算赋值

二、流程控制

js里面的代码是有执行顺序的,通过一些特殊的方式控制那些代码如何执行 —— 流程控制

顺序结构

按照从上到下的顺序,一行不漏的执行

分支结构

在逻辑上有多个分支,只会选择一个分支执行

循环结构

重复的代码,可以使用循环的方式实现多次

表达式

可以得到一个结果的代码 ,比如:

// 下面都可以称为表达式12; // 结果是12a++; // 结果是 a值加15 > 6; // 结果是 false// ...

语句

语句可以理解为一个行为,一般在行为和行为之间,都会使用 ; 隔开

console.log(12); // 行为就是输出了一个12在控制台alert('helloworld'); // 行为就是弹出了个提示框var a = 10;

简而言之:一个程序可以由多个语句组成,一个语句可以由多个表达式组成

三、分支结构

从多个分支里面选择一个 —— 作用 : 判断

判断一下一个人的性别,如果是男的,让他上男厕

if/else结构

只有一个条件的判断:

if( 条件表达式 ){   条件表达式的结果是true的时候要执行的代码}var gender = prompt('请问您的性别是男的吗');if( gender === '男' ){  alert('男厕所在二楼的最东边,请去吧');}

两个条件的判断:

if( 条件表达式 ){   条件表达式的结果是true的时候要执行的代码}else {  条件表达式的结果是false的时候要执行的代码}var gender = prompt('请告诉我你的性别');if(gender === '男'){  alert('男厕所在二楼的最东边,请去吧');}else {  alert('女厕所在3楼的西边');}

多个条件的判断:

if( 条件表达式1 ){   条件表达式1的结果是true的时候要执行的代码}else if(条件表达式2){  条件表达式2的结果是true的时候要执行的代码}else if(){         }// 如果还有更多的判断,继续写 else if ()else {  以上的条件都不为true,就会执行这里的代码}var num1 =  +prompt("请输入一个数字(1~7):");if(num1 === 1){    console.log("星期一");}else if(num1 === 2){    console.log("星期二");}else if(num1 === 3){    console.log("星期三");}else if(num1 === 4){    console.log("星期四");}else if(num1 === 5){    console.log("星期五");}else if(num1 === 6){    console.log("星期六");}else if(num1 === 7){    console.log("星期日");}else{    // 这里的代码,当上面所有条件都不成立, 就执行这里的代码    console.log("请务必输入1-7");}

练习:

  1. 任意输入两个数,求两个数最大值,在弹窗中显示最大值(练习if-else结构)

  2. 判断分数区间,分数在90到100的为A,80到89的为B,70到79的为C, 60到69为D,60以下为E (练习if-else-if 结构)

     // 注意: 数学中 3 < x < 10 的写法在js中不存在,  要改成  3 < x  && x < 10 var score = 11; console.log(3 < score < 10); // true console.log(3 < score && score < 10); // false

switch结构

在js里面如果是比较固定值,推荐使用swtich-case结构

语法:

switch (变量){  case 要比较的固定的值1:    变量和 固定的值1  ===   的时候要执行的代码    break;  case 要比较的固定的值2:    变量和 固定的值2  ===   的时候要执行的代码    break;  case 要比较的固定的值3:    变量和 固定的值3  ===   的时候要执行的代码    break;  default:    当以上所有的条件都不成立的时候,代码在这里执行    break;}

举例:

switch(num){    case 1: alert("星期一");break;    case 2: alert("星期二");break;    case 3: alert("星期三");break;    case 4: alert("星期四");break;    case 5: alert("星期五");break;    case 6: alert("星期六");break;    case 7: alert("星期日");break;    default: alert("请输入正确的数字:1-7"); break;}

细节

  1. 小阔号里面的变量 全等于 case 后面的值得时候,这个case后面的代码就会被执行

  2. default不是必须的,如果小阔号里面的变量都不等于所有的case后面的值,才会执行default 后面的代码

  3. break的作用是结束判断,如果后面没有写break,则代码会继续往下执行

  4. .变量和固定值的比较是 === 严格等于

三元表达式(补充)

三元(三目)表达式的使用是简写if-else结构

语法:

表达式1 ? 表达式2 : 表达式3// 如果表达式1 成立, 那么就执行表达式2// 如果表达式1 不成立, 那么就执行表达式3//例如: 求二个数字中谁更大var a = 10; var b = 20;var max = a > b ? a : b;console.log(max);

总结:

if/else结构,多用于判断区间、不定值判断

switch-case 只能用于定值判断

四、循环结构

在js中,如果我们要连续输出同样的一句话多次,会比较麻烦

//输出 xxx,不愧是你!! 6 次console.log('不愧是你!!');console.log('不愧是你!!');console.log('不愧是你!!');console.log('不愧是你!!');console.log('不愧是你!!');console.log('不愧是你!!');

同样的代码我们写了6次,这样是不好的,重复多次时,我们使用循环结构结构

for循环

语法:

for(初始化表达式 ; 条件表达式 ; 递增或者递减表达式){  循环体(需要重复执行的代码)}for(var count = 0;count < 6; count++){  console.log('javascript天下无敌!!!');}

执行过程:

1.先执行初始化表达式

2.判断条件是否成立

3.如果成立,执行循环体

4.执行递增表达式

重复2~4,直到第2步的条件为false,就结束循环

练习:

  1. 求1~10之间的所有整数和
  2. 在控制台输出1到10的数字中偶数的累加和

嵌套for循环

// 需求:在浏览器中用*打印一个矩形形****************
 var str = "";  for (var i =0; i < 4; i++) {        for (var j =0; j < 4; j++) {      str = str += "*";    }    str = str += "\n";  }  console.log(str);

day03

1.数组 Array

//数组:数据的集合//类似于文件夹,将同类数据放在一个文件夹内let arr =[10,20,30,40] ;//通过 arr[索引]  获取数组中的每一项//索引(也叫下标)是从0开始的 //数组的增删改查//增 数组中没有则增,有则改//增arr[5] = 80; //改,也叫重新赋值arr[0] = 100; //删 arr.splice(1,1)//查  console.log(arr[0],arr);   //控制台输出数组arr 中的第0 个元素----10 //如果数组中某项的值为空 则返回undefinedconsole.log(arr[4],arr[10]) //undefined,undefined

数组的遍历

 var arr = [10, 20, 30, 40, 50]; //方法1、         for(var i=0;i<arr.length;i++){           console.log(i,arr[i]);// i 索引   arr[i]值        }//方法2、        for (var key in arr){            console.log(key, arr[key]);// key 索引   arr[key]值        }

计算多个数字的和

  // 机器人案例 请输入  1,2,3  格式的数据,我们帮你求和   var ste = prompt('请输入1,2,3格式的数据(英文,),我们帮你求和')   let arr =ste.split(',')   //将得到的字符串用splice 方法切割得到一个新的数组   console.log(arr);  //['1','2','3'......]   let sum = 0;   for (var i=0;i<arr.length;i++){        sum +=  Number(arr[i])  //遍历数组的每一项,转为数字类型,并累加   }   console.log(sum);

获取当前时间

 //获取当前时间    // 1.获取时间对象    var myDate = new Date ();    //2.获取时间对象上的年月日、时分秒    let y = myDate.getFullYear();        let m = myDate.getMonth()+1;    let d = myDate.getDate()    let h =myDate.getHours()    let ms =myDate.getMinutes()    let s = myDate.getSeconds()    // console.log(y,m,d,h,ms,s);// 希望输出结果为: 2022年02月28日  19时46分26秒// 当 时 分 秒 月 日是个位数的时候需要在前面添加 0let arr =[m,d,h,ms,s ]let newArr=[]arr.map(item=>{    if(item<10){         item = '0'+item    }        console.log(item);    newArr.push(item)                                                })console.log(newArr);let btn = document.getElementById(['btn'])btn.onclick=function(){    alert('当前时间是'+y + '年'+ newArr[0] +'月' +newArr[1] +'日  '+newArr[2] + "时" +newArr[3]+'分'+newArr[4] + '秒');    // alert('当前时间是'+y + '年'+ arr[0] +'月' +arr[1] +'日  '+arr[2] + "时" +arr[3]+'分'+arr[4] + '秒');}

随机数获取

    let arr = ['歌曲1','歌曲2','歌曲3','歌曲4','歌曲5','歌曲5','歌曲7']; //random获取7以下的随机正数console.log(Math.random()*7); //floor向下取整,获取7以下的正整数console.log(Math.floor(Math.random()*7)); //获取数组中随机项let ind = Math.floor(Math.random()*arr.length)console.log(arr[ind]);

求数组的和,平均值,最大值 ,最大值的索引

// 1. 求一个数组中所有数字的” 总和“ 和” 平均值“    // 2. 求数组中所有数字的最大值    // 3. 求数组中最大值的索引    let arr =[1,8,14,7]    let sum = 0;    arr.forEach(item=>{        //求和        sum +=item    })//求平均值    let  mean = sum/arr.length    console.log(sum,mean);//求最大值 方法1    let max =0    let inx =0   arr.forEach((item,index)=>{      if(item>max){                    max=item  //最大值          inx = index //最大值的索引      }   }) console.log(max,inx); //求最大值 方法2 console.log(Math.max(...arr)); //最大值

day04

函数:所有编程语言中都是重要的概念

有一段代码需要重复执行(在不同环境) -----使用函数

函数语法:1.函数声明式(定义式)funtion 函数名 (){函数体 ----- 企图重复运行的代码}2.函数的调用式函数名();

函数命名方式(小驼峰),建议首个单词使用动词 get set create

funtion getNickName() {console.log('张三是一个法外狂徒!!!');}

注意:函数声明之后,不会执行,一定要调用,调用之后才会执行

getNickName();

函数传参

 // 需求: 每次调用函数,人可能不是张三        // 思路: 将死的具体的数据 变成 可修改的变量        // 函数参数: 函数体内 会动态变化的值 使用 参数来代替        /*            函数参数的语法:            function 函数名(形参){------ 形式参数(占位)                // var 形参 = 实参;                函数体            }                        函数名(实参)---------------- 实际参数(具体的内容)        */        function getNickName(name) {            // 相当于 声明了变量  var name = "张三";            console.log(name+"是一个法外狂徒!!");        }        getNickName("张三");        getNickName("阿四");

函数参数的使用

  // 目的: 学会 使用函数 传递 多个参数 (原则上 实参数 == 形参数)        // 原则上,形参可以写无数个,事实上写超过8个都罕见        // 参数和参数之间使用 ,         function getNickName(name, nick) {// 形参            //相当于  var 形参 =  实参  没有实参 就是声明未赋值            console.log(name + "是一个" + nick + "!!");        }        // getNickName("张三","法外狂徒");// 实参        // getNickName("阿四","域外狂魔");        // 不正经的传参        // 1.实参>形参    多余的参数 没有意义         getNickName("张三", "法外狂徒", 50);   //张三是一个法外狂徒!!        // 2.实参<形参   相当于 声明变量未赋值  返回undefined        getNickName("张三");  //张三是一个undefined!!        getNickName();   //undefined是一个undefined!!

回调函数

回调函数就是一个被作为参数传递的函数。

        // 回调函数: 当一个函数作为另一个函数的参数使用,这个函数参数就是回调函数        function fn1(f) {            // f 是 回调函数            /*            相当于             var f  =  fn2 ------- 函数本身            */            console.log("函数1");            f();        }        function fn2() {            console.log("函数2");        }        fn1(fn2);

函数式思维

        函数思维:        1. 一段代码 企图重复去写------它就是一个功能(函数)------过程叫做函数封装        2. 函数中什么值是会变化(参数)        3. 这个函数需不需要得到某个值(返回值)

1.求n-m之间所有数的和

//n~m之和    function Fn(n, m) {        let getSum = 0        for (var i = n; i <= m; i++) {            getSum += i        }        return getSum    }    console.log(Fn(1, 5));     console.log(Fn(2, 5));

函数调用不调用有本质的区别

   function fn(a, b) {            return a + b        }        var sum = fn(10, 30);//  将函数调用式赋值给变量------ 得到的是返回值        var fn1 = fn;        //  将函数名 赋值 给变量--------得到的是 函数 本身        console.log(sum);        console.log(fn);        //       声明一个函数  fn = xxx  又将 fn的值(函数本身) 赋值给了 fn1        // 比如   声明一个变量 a = 10   又将a的值(10) 赋值给 b        var a = 10, b;        b = a;

函数其他写法 :

函数表达式

        // 函数表达式          // var 变量 = 匿名函数         /*            function(){}  匿名函数         */        var fn = function(a,b){            return a+b        }        console.log(fn(10,20)); //得到函数返回值 --- 30        console.log(fn);  //得到函数本身

立即执行函数

自调用函数,匿名函数自执行---- 函数经典结构

/* 语法:      (function(形参){函数体            })(实参)*/     (function (a,b) {            console.log(a+b);        })(10,20);

js的作用域

1.全局作用域 2. 局部作用域 (只有当前作用域生效)

 // 3个作用域: 1. 全局作用域   2. 作用域1包含fn1作用域  3.作用域2包含fn2作用域        /* 此时就形成一个作用域"链"结构  (只有函数可以产生作用域链)        总结:        1. 所有代码必有一个作用域-----全局作用域        2. 如有有函数会产生一个作用域----局部作用域        3. 函数中还有一个函数,就会再产生一个作用域        4. 此时 产生了一个 **由内而外访问的** 链式结构------ 作用域链        5. 最终全局都找不到----报错 */              var a = 10;// 全局变量        function fn1(){            var a = 20;// fn1局部变量            function fn2(){                var a = 30;// fn2局部变量                console.log(a); // 3. 使用fn2局部变量   30            }            console.log(a);// 2. 使用fn1局部变量   20            fn2();// 调用fn2函数        }        console.log(a);// 1. 使用全局变量   10        fn1();// 调用fn1函数         

js预解析

js是解释性语言 (有一个解析器)

执行过程 :1.预解析 2.代码从上往下执行

   var a;        console.log(a); //①  undefined        a = 123;        console.log(a); //②  123        console.log(f); //③ 函数        f(); //④ "函数声明提升"

预解析规则

1、变量和变量同名,解析后,只有一个变量声明

2、函数和函数同名,后面的会覆盖前面的

3、函数和变量同名,只有函数声明提前,忽略变量;变量的值会覆盖函数

4.函数表达式只会提升变量声明,并且函数表达式不能先调用再声明,会报错

day05

arguments参数

  function Fn(a,b){         console.log(a,b);         return a+b     }     console.log(Fn(1,2,3));  // 3------只计算了前两位数的和,实参数 > 形参数 a=1,b=2     console.log(Fn(1));      //  NaN ---实参数 <形参数  a=1,b=undefined    //  arguments 参数集合 是个伪数组 有长度有索引    let num =0    function Fn1(){                 for(var i=0;i<arguments.length;i++){            num += arguments[i]       }       console.log(num);    }    Fn1(1,2,3)

短路运算

逻辑运算符 && 且 || 或 !取反

 //  逻辑运算符  && 且    || 或   !取反        // console.log(1>2 && 1<2);        // && 一假全假   左边为假,右边不再读取(短路)        console.log(2 && 0); // 0  false        console.log(0 && 2); // 0  false        console.log(3 && 2); // 2  true        console.log(null && 0); // null  false        // 取决于谁得到谁          // || 一真全真  左边为真,右边不再读取(短路)        console.log(2 || 0); // 2  true        console.log(0 || 2); // 2  true        console.log(3 || 2); // 3  true        console.log(null || 0); // 0  false        // ! 颠倒是非  取反 做逻辑判断        console.log(!0);  //true         console.log(!1);  //false        console.log(!true);  //false

万物皆对象

        console.log(typeof Math);// 数学对象 object 是对象类型        var date = new Date();        console.log(typeof date);// 日期对象        // var arr = new Array();        var arr = [1,2,3];        console.log(typeof arr);// 数组对象        console.log(typeof document);// 文档对象

创建对象

字面量创建对象

      var obj = {};

js内置构造函数创建对象

      var obj = new Object();
 /*重点: 对象只有两个成员            动态行为: 相当于js里面的函数  -------------------- 对象的**方法**            描述信息: 相当于js中的变量------------------------ 对象的**属性**        *///创建对象var obj = new Object();        // 给对象添加**属性** (描述信息)        obj.name = "欧阳三";         //  给对象添加**方法** (动态行为)        obj.eatFn = function(){            console.log("今天吃食堂");        }        console.log(obj);   //获取 对象的属性和方法----------------------------------------       // *** obj.属性名----------可以得到属性值          console.log(obj.name);         // *** obj['属性名']----------可以得到属性值          console.log(obj['name']);        // *** obj.方法名()----------可以调用对象的方法        obj.eatFn();        // *** 对象的属性或方法的  修改和添加        // 如果存在-----修改        // 如果不存在---添加        obj.name = "阿四"; // 修改        obj.email = "asan13524@163.com"; // 添加        obj.eatFn = function () { // 修改            console.log("爱吃螺蛳粉");        }        obj.eatFn(); // 对象属性的删除  delete (关键字) 删除的是一整个键值对 (了解)        // delete obj.age;        obj.age = null;        console.log(obj);   

对象是一个无序的键值对数据集合

  // *** 字面量创建对象,可以创建时候添加属性和方法        // var arr = [10,20,30];        // 对象的内部: 键值对  key:value        //                    键:值        // 键值对和键值对之间用,隔开        var obj = {            //  属性            name:"欧阳三",            age:20,            // 方法            eatFn:function(){                console.log("爱吃螺蛳粉");            },            sayFn:function(){                console.log("喜欢抬杠");            }        }           console.log(obj);        //发现打印的属性和方法是无序的        //总结: 对象是一个无序的键值对组成的数据集合

工厂函数创建对象

需求: 用对象来描述,它的名字叫来福,它有黄色的毛hair,它有四条腿leg和一条尾巴tail,它喜欢吃骨头,喜欢跑到隔壁村找翠花

创建100个对象(并且,名字,颜色都不一样,其他内容一样)

函数封装的思维: 名字和颜色用参数代表,其他的内容,放在函数内,循环使用,提高代码复用性。

​ **** 工厂函数 创建 对象:

优点: 批量创建对象

参数: name,hair 可变的值

返回值: 创建出来的新对象

   function createObj(name, hair) {            var obj = new Object();            // obj.name=name            //     key   value(参数)            obj.name = name;            obj.hair = hair;            obj.leg = 4;            obj.tail = 1;            obj.eat = function () {                console.log("喜欢吃骨头");            };            obj.lick = function () {                console.log("喜欢跑到隔壁村找翠花");            }            return obj;        }        var d1 = createObj("来福", "黄色");        var d2 = createObj("旺财", "黑色");        var d3 = createObj("二狗", "粉色");        console.log(d1,d2,d3);

遍历对象

   // 遍历对象        // 字面量创建对象        var obj ={            name:'张三',            age:12,            eatFn:function (){                console.log('今天吃鸡蛋炒饭');            },            asyFn:function(){                console.log('今天天气真好!');            },            key:'啥也不是!!!'        }        // console.log(obj);        //对象的内部都是键值对 ------ key:value        for (var key in obj){            console.log(key); //获取到对象中所有的键值对的key(键名)            console.log(obj.key); //只获取到对象中键值对的key值为key的value值,并且对象有几个键值对就循环几次,打印几次            console.log(obj[key]); //key 是变量,  对象[key] 获取value值        }        obj['eatFn']() //今天吃鸡蛋炒饭-----一般不用

数据类型(首字母大写)

基本数据类型

String Number Boolean Null Undefined Symbol(ES6新增)BigInt(谷歌67新增)

复杂数据类型

Object Array Function

遍历复杂数组

<body>    <!-- <table   >        <tr><td>姓名</td><td>年龄</td></tr>        <tr><td>张三</td><td>23</td></tr>        <tr><td>李四</td><td>26</td></tr>        <tr><td>王五</td><td>18</td></tr>        <tr><td>留流</td><td>11</td></tr>    </table> --></body><script>    // 复杂数组    // 数组和对象内部value值,理论上可以是任何类型的数据    let arr=[        {name:'张三',age:23},        {name:'李四',age:26},        {name:'王五',age:18},        {name:'留流',age:11}    ]    // 外层遍历数组,内层遍历对象    for(var i=0;i<arr.length;i++){        for (key in arr[i]){            console.log(arr[i][key]);        }    }    // 渲染表格    let str = `  <table> <tr><td>姓名</td><td>年龄</td></tr>`        for(var i=0;i<arr.length;i++){            str+='<tr >'                for(var key in arr[i]){                    str+='<td>'+arr[i][key] +'</td>'                                    }                str+='</tr>'           }        str += '</table>'        document.write(str)    // 渲染列表</script>

day06

快速获取对象的key和value

Object.keys(对象)

Object.values(对象)

数组array.findIndex(需要获取索引的值)

Math对象

Math.random( )   取随机数Math.floor( )  向下取整Math.ceil( )   向上取整Math.abs( )   获取绝对值Math.max( )  获取最大值Math.min( )   获取最小值

String 对象

split( 字符)     //通过某个字符进行字符串切割,返回一个新数组chatAt( index )  //获取字符串的index对应的某个字符indexOf( 字符)   //获取字符对应的 在字符串中的索引值,如果字符串中没有则返回-1substring( start, end )  //截取字符串,从索引start 截取到 end,包含start,不包含end      console.log(str1.substring(2)); // 2~最后  只传一个参数 start到结尾      console.log(str1.substring(2, 4)); // 2~3substr( start, n)   //截取字符串,从索引start开始,截取 n 个字符      console.log(str1.substr(2)); // 只传一个参数 start到结尾      console.log(str1.substr(2, 4)); //索引2开始 4个字符      console.log(str1.substr(2, 5)); // 5个字符splace(old, new)    //使用新字符串替换旧字符串(只匹配到字符串中出现的第一次该字符)splaceAll(old, new)  //使用新字符串替换旧字符串(匹配字符串中出现的所有该字符)

Array 对象

1.添加删除方法-----改变了原数组push()        //在数组结尾追加元素pop()         //删除数组最后一个元素unshift()     //在数组最前面插入元素shift()       //删除数组最前面的元素2.数组翻转----改变了原数组reverse()3.splice操作数组----改变了原数组splice(index)    //只传一个参数,从索引index到结尾splice(0)        //清空数组splice(index, n) //传两个参数,从索引index开始,删除n个元素splice(index,n,参数,参数......) //传多个参数  使用第2个参数后面的参数 替换删除的元素--------------上面的方法都改变了原数组------------下面的方法不会改变原数组,重点在返回值--------1.slice(start, end) //从索引start 到 end 截取数组的值(包含start 不包含end)2.indexOf()  //和字符串一样,数组中有这个值则得到索引(第一次出现的值),没有则返回 -13.join(字符)  //将数组转成字符串(并通过某个字符链接)4.数组的遍历4.1 forEach(回调函数)   //有两个参数:数组项和索引,没有返回值4.2 map(回调函数)       //有两个参数:数组项和索引,有返回值4.3 filter(回调函数)     //也叫过滤器    语法上和forEach一样  返回过滤后的数据       var ret = arr.filter(function(item,index){            return item<50        })5.concat()  //数组合并(从左往右进行合并) var newArr = arr1.concat(arr2)

获取时间戳

 //创建当前时间对象var date = new Date();  //获取时间戳 方法1var chuo1 = date.getTime(); //获取时间戳 方法2 var chuo2 = +new Date(); //做了隐式转换// 用时间戳--获取时间对象var oldDate = new Date(1637226997383); console.log(oldDate);  //Thu Nov 18 2021 17:16:37 GMT+0800 (中国标准时间)

把数组的首尾两个元素互换

var arr =["鹿晗", "王俊凯", "蔡徐坤", "彭于晏", "周杰伦", "刘德华", "赵本山"];var m = arr[0];arr[0] = arr[arr.length-1];arr[arr.length-1] = m;console.log(arr)

使用Math对象,制作一个16进制 的随机颜色

<style>.box{ width: 100px; height: 100px;background-color: #D58EE9;}</style><body><div class= "box"> </div></body><script>   //   题目提示:16进制包括 “ 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F ”        //   例:调用 “#f23a4b”         //  0~9   10   10        //  0~15  10   16    16进制  逢16进1    10----A      15----F        function getColor(){       var arr = ['0', "1", "2", "3", "4", "5", "6", "7", "8", "9",'A','B','C','D','E','F'];       var str = '#';              for(var i=0;i<6;i++){       str += arr[Math.floor(Math.random()*arr.length)];       }       return str               }                      console.log(getColor());</script>
        // 2. 字符串:“abaasdffggghhjjkkgfddsssss3444343”,问题如下:         /*          1、 字符串的长度 ------- length          2、 取出指定位置的字符,如:0,3,5,9等 ----- charAt          3、 查找指定字符是否在以上字符串中存在,如:i,c ,b等 ----- indexOf() == -1          4、 替换指定的字符,如:g替换为22,ss替换为b等操作方法 ----- replace()          5、 截取指定开始位置到结束位置的字符串,如:取得1-5的字符串---- substr  substring          6、 *** 找出以上字符串中出现次数最多的字符和出现的次数           7、 遍历字符串,并将遍历出的字符两头添加符号“@”         */        // 6. ******** 数据统计  计算出每个字符出现多少次        /*  ***** 思路: 使用对象,预期的数据类型             obj = {                 a:2,                 b:1,                 ....             }          */        //  6.1 遍历字符串        var str = "abaasdffggghhjjkkgfddsssss3444343";        var obj = {};        for (var i = 0; i < str.length; i++) {            // console.log(str[i]);            // 6.2 存储 当前 元素             var cur = str[i];            // 6.3 合成一个对象            if (obj[cur]) {                // 6.5 如果出现过,次数累加                obj[cur]++;            } else {                // 6.4 第一次出现 初始化为1                obj[cur] = 1;            }        }        console.log(obj);        // 6.6 遍历对象        var max = 0;        var maxVal = null;        for (var k in obj) {            if (max < obj[k]) {                max = obj[k];                maxVal = k;            }        }        console.log("出现最多的字符是:" + maxVal + "-----------出现了" + max + "次");        // 7. 遍历字符串,并将遍历出的字符两头添加符号“@”         // console.log("@"+str+"@");        var newStr = ""        for (var i = 0; i < str.length; i++) {            if (i == 0) {                newStr = "@" + str[i];            } else if (i == str.length - 1) {                newStr += str[i] + "@";            }else{                newStr += str[i];            }        }        console.log(newStr);

js 进阶day1-5

js day-01

获取元素

var _box = document.getElementById("box"); //通过id名获取元素var _p = document.getElementsByTagName("p"); //通过标签名获取元素var _ele = document.getElementsByClassName("ele");  //通过类名获取元素var _username = document.getElementsByName("username"); 通过name 属性获取元素H5新增2种方法 var _box = document.querySelector("#box"); var _ele = document.querySelectorAll("p.ele");

为多个元素绑定事件

事件三要素:1.事件源     被触发的对象2.事件类型     click , mouseover  ,change3.事件处理程序    执行的代码 (函数的形式)var btn= document.getElementById('btn');btn.onclick = function(){var _p = document.getElementsByTagName('p');for(var i = 0; i < _p.length; i++ ){_p[i].innerText = '我们是p标签'}}

排他思想

  // 需求: 排他思想(套路) ---- 点击当前按钮高亮显示(自律),兄弟元素取消高亮        // 1.获取元素集合        var btns = document.getElementsByTagName("button"); // 伪数组        // 2. 遍历伪数组,给每个元素绑定事件        for (var i = 0; i < btns.length; i++) {            btns[i].onclick = function(){                // 4. 排他思想核心: 初始化思维                 // 改变当前元素之前,让所有元素都取消背景色                for (var j = 0; j < btns.length; j++) {                    btns[j].style.background = "none";                }                // 强调: 事件绑定第一件事,测试事件绑定成功没有                // console.log(this);                // 3. 当前按钮(事件源) 高亮显示                this.style.background = "#cfc";            }        }

day-02

表单元素相关属性

非空判断 初始化输入框

value 值       checked 选中效果      disabled 禁用表单项  常用做非空校验   var btn = document.getElementsByTagName("button")[0];  var txt = document.getElementsByTagName("input")[0];                btn.onclick = function(){        var _va = txt.value;        if(_va){    // 非空判断        console.log(_va)                }else{        alert("输入框不能为空哦!")        }            txt.value = "";  //初始化表单元素的值为空        }

动态设置class

 1.  ele.className = "class1 class2...."   添加/删除 类名2.  ele.classList.add("box");-------- 添加类名3.  ele.classList.remove("box");-------- 删除类名
 思路: 修改样式, 预先设计好样式,写逻辑的时候 直接操作类名    getId("btn").onclick=function(){                      /* getId("box").style.width = "200px";            getId("box").style.height = "200px";            getId("box").style.background = "#cfc"; */ //  直接修改 样式            // ***** 思路: 修改样式, 预先设计好样式,写逻辑的时候 直接操作类名            // ****** 1. ele.className = "class1 class2...."   修改/删除 类名(保留原有的类名)            // getId("box").className = "dv box";            // getId("box").className = "";            // ****** 2. ele.classList.add("box");-------- 添加类名            //    ele.classList.remove("box");-------- 删除类名            // console.log(getId("box").classList);            // getId("box").classList.add("box");            getId("box").classList.remove("dv");        }

开关灯思想

// 开关灯//判断 当前状态,进行修改    getId("btn").onclick=function(){   //1.事件绑定    if(document.body.className){ // "bg"------ true -------    // 判断有没有这个类名  有则删除 无则添加                               document.body.classList.remove("bg");                this.innerText = "关灯";                            }else{ // ""  ------ false--------                                this.innerText = "开灯";                document.body.classList.add("bg");            } }      开关思想: 使用变量决定一个状态 由变量的值来决定业务逻辑-----注意点:逻辑写完之后,修改状态   var flag = true;        getId("btn").onclick = function () { //1.事件绑定             if (flag) { //flag------ true -------//  判断有没有这个类名  有则删除 无则添加                  document.body.className = "";                this.innerText = "关灯";                flag = false;            } else { // ""  ------ false--------                 this.innerText = "开灯";                document.body.className = "bg";                flag = true;            }        }   

全选反选 案例

需求:            1. 全选功能: 点击全选, 列表选框全部选中   点击全部不选,列表选框全部不选中            2. 反选功能: 点击列表选框, 但凡发现一个列表选框未选中, 全选框未选中                                     如果列表选框全部选中, 全选框选中                   3. 反选按钮: 列表选框取反(满足反选的逻辑)                                    1. 全选功能         var _put = getEle("j_tb", 'input');        getId('j_cbAll').onclick = function () {            console.log(this);            for (var i = 0; i < _put.length; i++) {                _put[i].checked = getId('j_cbAll').checked;                getId('txt').innerText = getId('j_cbAll').checked ? '全不选' : '全选';            }        }                        点击列表选框, 但凡发现一个列表选框未选中, 全选框未选中  如果列表选框全部选中, 全选框选中                                           for (var i = 0; i < _put.length; i++) {            _put[i].onclick =function() { 思路: 假设所有选框都是选中状态, 遍历所有选框,找到一个未选中, 全选状态 改为false            var flag = true;            for (var j = 0; j < _put.length; j++) {                if (!_put[j].checked) {                    flag = false;                }            }            getId('j_cbAll').checked = flag;            getId('txt').innerText = getId('j_cbAll').checked ? '全不选' : '全选';        }        }                         // 反选按钮         // 1.点击按钮  每个列表选框选中状态改变  取反         // 2.全选按钮 和 每个列表选框 状态 跟着改变         getId("rev").onclick = function () {            for (var i = 0; i < _put.length; i++) {                _put[i].checked = !_put[i].checked;            }                        和上面不占一样,可以做函数封装             var flag = true;            for (var j = 0; j < _put.length; j++) {                if (!_put[j].checked) {                    flag = false;                }            }            getId('j_cbAll').checked = flag;            getId('txt').innerText = getId('j_cbAll').checked ? '全不选' : '全选';        }          

day-03

节点案例

**** 获取父元素--------单数   ele.parentNode  父级节点-------节点包含元素 ele.parentElement  父级元素 ele.childNodes   子级节点       ele.children   子级元素
 点击按钮 切换 p标签背景颜色           getId('btn').onclick = function(){            var _box = getId('box').childNodes;            console.log(_box);            for(var i=0;i<_box.length;i++){                if( _box[i].nodeName == 'P'){                    _box[i].style.background = '#cfc';                }            }        }        

自定义属性 的 操作

 ele.getAttribute("属性名")---------获取自定义(标签属性)属性的属性值 ele.setAttribute("属性名","属性值")------ 设置(新增,修改)自定义属性ele.removeAttribute("属性名")-----------删除自定义属性节点

动态创建列表

 var names = ["杨过", "郭靖", "张无忌", "张三丰", "乔峰", "段飞", "丁棚"];  //方法一 使用innerHTML-----字符串思维(所见即所得)        getId('btn').onclick = function () {            if (!getId('box').innerText) {  //非空校验  如果盒子内容为空 执行里面的代码                //getId('box').innerText  false--空   取反  true 执行里面的代码                var uu = document.createElement('ul');                getId('box').appendChild(uu);               for (var i = 0; i < names.length; i++) {                    uu.innerHTML += '<li>' + names[i] + '</li>';                 }                        }                                    //方法二   用 document.createElement("元素名称")------创建一个元素节点(对象)             // *** 父元素.appendChild(子元素)------ 将元素添加到DOM中                                getId('btn').onclick = function () {            if (!getId('box').innerText) {  //非空校验  如果盒子内容为空 执行里面的代码                //getId('box').innerText  false--空   取反  true 执行里面的代码                                var uu = document.createElement('ul');                getId('box').appendChild(uu);   names.forEach(function(item){   //也可以用forEach()遍历数组   item是数组的项                    var lis = document.createElement('li');                    lis.innerText = item;                       uu.appendChild(lis);                })            }        }

替换和删除节点

 // 需求1:  ul的最前和最后插入新节点        getId("btn1").onclick = function () {            // console.log(this);            // 最前插入新元素节点            var newLi = document.createElement("li");            newLi.innerText = "最前插入新元素节点";            // **** 父元素.insertBefore(新节点,参照节点);  在参照节点之前插入新节点            getId("uu").insertBefore(newLi, getId("uu").children[0]);        }        getId("btn2").onclick = function () {            // console.log(this);            // **** 父元素 最后插入新元素节点  appendChild()            var newLi = document.createElement("li");            newLi.innerText = "最后插入新元素节点";            getId("uu").appendChild(newLi);        }        // 需求2: 实现 替换节点和删除节点的功能        var dels = document.getElementsByClassName("del");        var reps = document.getElementsByClassName("rep");          // 替换li (使用新的li 替换 旧的li)            reps[i].onclick = function () {                var newLi = document.createElement("li");                newLi.innerText = "新元素";                // **** 父元素.replaceChild(新节点,旧节点)------使用新节点替换旧节点                getId("uu").replaceChild(newLi,this.parentElement);            }        }        for (var i = 0; i < dels.length; i++) {            // 删除li            dels[i].onclick = function () {                // console.log(this.parentElement);                // ******** 父元素.removeChild(子节点)------节点删除(不能删除自己)                // 用ul删除li                getId("uu").removeChild(this.parentElement);            }          

day-04

事件的三个阶段

事件的三个阶段1. 捕获阶段(由外向里)  2.目标阶段    3.冒泡阶段(由里向外)

事件对象 event

事件对象  event  书写位置   事件执行程序的 形参     有兼容性btn.onclick = function( e ){ var e = e || window.event;   //IE8 兼容}

阻止事件冒泡

阻止事件冒泡 btn.onclick = function( e ){ var e = e || window.event;   //IE8 兼容if(e.stopPropagation){e.stopPropagation();  //W3C 标准}else{e.cancelBubble;      //IE8 兼容}}

阻止事件默认行为

//阻止事件默认行为   ---比如 点击按钮刷新了表单页面        getId("btn").onclick = function (e) {             var e = e || window.event;            if (event.preventDefault) {                event.preventDefault(); // W3C标准-----IE8不支持                console.log("preventDefault");            } else {                event.returnValue = false; // IE8 特有   亲测火狐有效                console.log("returnValue");            }        }

事件委托

  // 事件委托 e.target     给动态添加的元素绑定事件            // 需求1: 点击按钮,添加一条 li        getId("btn").onclick = function () {            var newLi = document.createElement("li");            newLi.innerHTML = "新列表<button>按钮</button>"            getId("uu").appendChild(newLi);        }                        // 需求2: 点击li的按钮,获取当前 li 的text        // e.target 只委托给 页面本来就存在的 父级                getId("uu").onclick = function(e){            var e = e || window.event;            var tar = e.target;             //此时 tar  是 ul  里面 的所有元素对象            if(tar.nodeName =="BUTTON"){                // this ---- ul                // tar------- button                // tar.parentElement---- li                console.log(tar.parentElement.innerText);            }        }                                                                                                                                                                                                                                                                                                                                                                                                           e.target可以用来实现事件委托,该原理是通过事件冒泡(或者事件捕获)给父元素添加事件监听        e.target指向引发触发事件的元素

事件监听 – 2级事件

  // 需求:事件监听的第三个参数         // addEventListener(参数1,参数2,参数3)        /*  参数1:事件类型    参数2:事件处理程序    参数3:事件的执行阶段(布尔值)                true: 捕获阶段执行                false: 冒泡阶段执行 (默认)*/   getId("box").addEventListener("click", function () {            console.log("第二次点击盒子");        })  //默认为false 可以不写

事件解绑

btn.onclick = function(){console.log('点击成功');}//  0级事件解绑removeBtn.onclick =  function(){  btn.onclick = null;}//  2级事件解绑  function fn1() {//命名函数            console.log("第一次点击");        }        function fn2() {            console.log("第二次点击");        }        getId("btn").addEventListener("click", fn1);        getId("btn").addEventListener("click", fn2);        getId("removeBtn").onclick = function () {            // 解绑 第一次的 事件绑定            /*  getId("btn").removeEventListener("click", function () {                 console.log("第一次点击");             }) */            // 问题: 绑定的第一个事件函数 和 解绑的函数不是一个函数 ---- 两个引用地址            // 注意点: 绑定的函数必须要解绑的函数是同一个引用地址   所以不能用匿名函数,要用命名函数            getId("btn").removeEventListener("click", fn1);        }

day 05

吸顶导航案例

  // 需求: 1. 鼠标滚动 滚动的到相应的位置, 吸顶导航停留在顶部,不会随着鼠标滚动而滚动        //       2. 鼠标回滚的时候, 回滚到相应的位置, 吸顶导航 也回到最初的位置        // 思路:        // 1. 页面滚动的事件  window.onscroll = function(){}        // 2. 监听两个值  1. 初始值  2.内容滚动的值        // 3. 判断   什么情况下吸顶  什么情况下回到初始位置<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title>    <style>        *{            padding: 0;            margin: 0;        }        body {            padding: 0;            margin: 0;        }        #nav {            width: 100%;            height: 60px;            background: pink;            color: #fff;            line-height: 60px;            text-align: center;            padding: 0;            margin: 0;        }        #nav li{                       height: 60px;          list-style: none;        }        .fix {            position: fixed;            top: 0;            left: 0;        }    </style></head><body>    <div class="boxtent">        <h2>我要隐藏了</h2>        <h2>我要隐藏了</h2>        <h2>我要隐藏了</h2>        <h2>我要隐藏了</h2>         <ul id="nav">            <li>标题、标题、标题、</li>                   </ul>        <div class="box">            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>            <p>滚动内容,,,啦啦啦啦</p>        </div>    </div>    <script>         //获取标题的id    var nav_tops = document.querySelector('#nav');    // 获取导航条距页面顶部的距离    var titTop = nav_tops.offsetTop;    console.log('titTop',titTop);    //设置滚动监听事件    document.onscroll = function() {            //获取当前滚动距离             var scrollTop= document.body.scrollTop || document.documentElement.scrollTop;//这里是一个兼容 有的浏览器支持body 有的支持documentElement            //如果滚动距离大于导航条距顶部距离            console.log('scrollTop',scrollTop);            if (scrollTop> titTop) {                    //如果卷进去的距离大于导航栏到顶部的距离的话,导航栏设置fixed 固定在当前位置                    nav_tops.className = "fix";            }else {                    //如果卷进去的距离小于导航栏到顶部的距离的话,设置导航条不是固定定位                    nav_tops.className = "";            }    }    </script></body></html>

单次定时器

  // 目的: 学习 单次定时器  的设置和清除的语法/*            语法:             设置单次定时器: setTimeout(function(){},time)                过time时间之后再执行某代码                           清除单次定时器: clearTimeout(name)   name 定时器名称        */          // 声明定时器名称  一般会用timer        var timer = setTimeout(function () {   // 异步函数  浏览器加载到这段代码的时候,暂时不执行,满足一定条件之后再执行            console.log("01-我今天感觉自己突然行了!!!");        }, 3000)        // 点击按钮之后   清除单次定时器        // 一般情况,也不会清除单次定时器        btn.onclick = function () {            clearTimeout(timer);            console.log("02-突然有感觉自己不行了!!!");        }

循环定时器

  // 目的: 学习  循环定时器  的设置和清除的语法        /*            语法:            设置循环定时器: var timer = setInterval(function(){},time)                            每隔time的时间,就执行一次函数中的代码段            清除循环定时器: clearInterval(timer)   timer 定时器名称                */        // 1. 设置        var timer = setInterval(function () {            console.log("我已经js进阶成功!!!");        }, 1000)        // 2. 清除        btn.onclick = function () {            clearInterval(timer);            console.log("我要进入更高的阶段了!!!");        }

随机点名系统

        // 需求:  1. 模拟后台数据   做页面渲染        //        2. 点击点名按钮之后  光标在 列表内部 随机显示    改掉按钮文字        //        3. 点击停止按钮之后  光标停留在某个元素上    不再随机闪烁   改掉按钮文字        // 1. 模拟后台数据   做页面渲染        //创造虚拟后台数据        var arrs = ["宋江", "卢俊义", "吴用", "公孙胜", "林冲", "花荣", "鲁智深", "武松", "李逵", "晁盖", "燕青", "潘金莲", "阎婆惜", "关胜", "秦明", "呼延灼", "陈达", "张青", "刘唐", "李俊", "张顺", "高俅", "孙二娘", "戴宗", "朱仝", "方腊", "阮小二", "李瓶儿", "庞春梅", "白胜", "吕方", "董平", "穆春", "宋清", "柴进", "施恩", "李忠", "周通", "杜兴", "时迁", "曹正", "宋万", "杨志", "镇关西", "西门庆"];        // 1.1 遍历数据        arrs.forEach(function (item, index) {            // console.log(item);            // 1.2 列表渲染            var divNode = document.createElement("div");            divNode.innerText = item;            divNode.className = "name"; //添加设置好样式的对应 类名            box.appendChild(divNode);        })        // 3.2 将tim 变量   初始化timer  一般来说会初始为null        var timer = null;        // 2. 点击点名按钮之后  光标在 列表内部 随机显示        // 2.1 使用开关思想        var flag = true; // 文字显示 点名         btn.onclick = function () {            // 3.1 预解析            // var timer;  xxxxx            // console.log(this.innerText);            if (flag) {                // 文字显示 点名                 console.log("点名业务逻辑");                // 2.2 光标在 列表内部 随机显示                // 使用循环定时器                timer = setInterval(function () {                    // 2.5 排他思想----初始化----每次进来都没有背景色                    for (var i = 0; i < arrs.length; i++) {                        box.children[i].style.background = "";                    }                    //2.3 随机显示? random    思路: 光标----背景色     元素列表中随机找一个元素设置背景色                    // box.children   盒子的子元素集合    索引 --- 随机数                    // box.children[myIndex] 随机的一个元素   myIndex-----0~length-1之间的随机数                    var myIndex = Math.floor(Math.random() * arrs.length);                    // 2.4 设置背景颜色                    box.children[myIndex].style.background = "red";                }, 10)                flag = false;            } else {                console.log("停止业务逻辑");                // 3. 点击停止按钮之后  清除定时器                clearInterval(timer);                // 两次点击(点名和停止)                // console.log(timer);                flag = true;            }            this.innerText = flag ? "点名" : "停止";        }

js 高级day 1-7

day01

let 声明变量的特点

  <h3>let声明变量的特点(重要)</h3>    <script>        // 需求: 使用let解决var的问题        // 1. 不能先使用,再声明        /* // console.log(a);        let a = 10;        console.log(a); */        // 2. 不能重复定义一个变量        /* let a = 10;        let a = 20; */            // **** 5.let 没有预解析        // 3. 不会造成全局变量污染的        for(let i=0;i<5;i++){            // 将i变成局部变量            // console.log(i);        }        // console.log(i);        // **** 4.拥有块级作用域(ES6)   {}内的会形成一个作用域        {            let a = 10;        }        // console.log(a);    </script>

const 声明常量的特点

    // 需求: 使用 const声明 常量        // 变量-------可以修改可以变量        // 常量-------不修改,恒常不变        // 个人习惯: 常量首字母大写,区分变量,也有人全部大写        // 1. 不能先使用,再声明(没有预解析)        /* console.log(Data);        const Data = 10; */        // 2. 一旦声明必须赋值        // const DATA;        // 3. 赋值之后 不能修改        /* const DATA = 10;        DATA = 20; */        // 4. 拥有块级作用域        /* {            const DATA = 10;            // console.log(DATA);        }        console.log(DATA); */        // const声明一个常量,这个常量是引用数据类型(对象,数组,函数....)        /*         为什么不能修改: 因为改变了引用地址                const Arr = [10,20,30];        Arr = [1,2,3];        console.log(Arr);// 一旦赋值(引用地址)不能修改 */        const Arr = [10,20,30];        Arr[1] = 200;        console.log(Arr);// 为什么可以修改: 因为引用地址没变过,改的是值        //**** 特点5. 引用类型的值可以修改

模板字符串

//字符串拼接:   +号 和 '' console.log("我叫" + name + ",今年" + age + "岁了,我是一个" + gender + "孩子");//模板字符串:  反引号`` 和  ${} console.log(`我叫${name},今年${age}岁了,我是一个${gender}孩子`)

对象解构

对象解构的语法 *****                  var obj = {            name: "骡窝窝",            age: 1,            type: "jQuery项目"        }//1. 对象解构: 将对象中的值 提取出来,赋值给变量 //注意点: key要和变量同名才可以解构       //语法:   let {变量,变量,变量..}  =  对象 let {name,age,type} = obj;console.log(name,age,type);//2. 将对象的一部分值赋值给变量--------部分解构// **** 解构之后重命名        //语法:  let {对象对应的key:重命名之后的变量名} = obj;        let {name:myName} = obj;       console.log(myName);  // 3.解构 内置对象的方法         // let {变量} = Math内置对象    {random:fn}        let { random } = Math;        console.log(random());

数组解构

let arr = [10,20,30];//数组解构,将数组中的值赋值给变量 //语法: let [变量,变量。。。] = arr//1.完全解构   let [变量,变量] = arrlet [a,b,c]=arr;console.log(a,b,c);//2.部分解构 (按顺序--补全逗号---占位)let [a,b,c,d] =arr; console.log(a, b, c, d);// 变量>数组个数--解构失败//得到undefined  ----10 20 30 undefined      let [, b] = arr; console.log(b);//20let [, , c] = arr; console.log(c);//30        // 3. 复合解构         let arr2 = [10, 20, 30, [100, 200, 300]]; // 二维数组        let [a, b, c, [x, y, z]] = arr2;        console.log(a, b, c, x, y, z);// ES6 是为了简化代码, 当你发现不能简化的时候, 用ES5

字符串解构

// 需求:解构一个字符串(本质上和数组解构是一样的)        // 字符串有索引有长度,不能使用数组方法------本质上是一个伪数组        let str = "申总好厉害!!";let [a,b] = str;        console.log(a,b);

交换两个变量的值

//ES5写法  设置一个中间变量var a=10,b=20;var m = a;a = b;b = m;console.log(a,b);//ES6写法let a=10,b=20;[a,b]=[b,a];console.log(a,b); // 20 10

对象的简化写法

  // 需求: 将多个变量的打包成一个对象(对象的key和变量名同名)        let name = "张三",            age = 20,            gender = "男";        function eat() {            console.log("爱吃螺蛳粉");        }        // ES5 写法       let obj = {            name: name,            age: age,            gender: gender,            eat: eat,        }         // ES6 对象的简化写法        // 语法: 如果对象的key和变量名同名,可以只写key不写value        // 对象解构反向操作        let obj = {name ,age, gender, eat};        console.log(obj);

函数设置默认值

  function add(a, b, c, d) {            return a + b + c + d;      }        console.log(add(1, 2, 3, 4));// 10        console.log(add(1, 2));// number+undefined = NaN         // ES5 解决方案        // 函数调用少传参,会出现业务逻辑问题-------短路         function add(a, b, c, d) {            a = a || 0;            b = b || 0;            c = c || 0;            d = d || 0;            return a + b + c + d;        }         // ES6 --------- **** 设置函数参数默认值        // 语法:  function fn(形参 = 默认值){}   当形参是undefined时候,赋值为默认值        function add(a=0, b=0, c=0, d=0) {            return a + b + c + d;        }        console.log(add(1, 2, 3, 4)); // 10        console.log(add(1, 2)); //3

对函数参数进行解构赋值

 // 终极需求: 实现$.ajax的传参方式----想办法创建一个这样的函数,并获取参数(url,type)        /* $.ajax({            type:"",            url:"",            data:{}        }) */        // 1. 数组参数解构------顺序        function fn([x, y, z]) {            // 不加[]-------相当于 let x = arr ,y,z             // 加了[]-------相当于 let [x, y, z] = arr;            console.log(x, y, z);        }        fn([10, 20, 30]);         // 2. 对象参数解构------无序        function ajaxFn({url,type,data}){            // 加了{}------相当于 let {url,type,data} = obj            console.log(url,type,data);        }        ajaxFn({            type:"GET",            data:{name:"张三"},            url:"xxxx"        })

参数的解构赋值 —解决报错的问题

function ajax({url='xxx.com',type='GET',data={}} = {}){console.log(url,type,data);}  ajaxFn();  // 需求: 解决 函数参数解构赋值  报错问题    // 如果不传参-----相当于 let {url,type,data} = undefined   报错            // 1. 如果传参{}-----相当于 let {url,type,data} = {}  ---- **解决报错**             //             -----  设置默认值{}  得到 三个 undefined            // 2. 解决 undefined 问题 -------  给每个参数都设置默认值

rest 参数 基本语法

 // 需求: 解决实参>形参的问题//剩余参数设置        // ES5: 使用arguments        function add(a,b,c) {            // console.log(arguments);            var sum = 0;            for(var i=0;i<arguments.length;i++){                sum+=arguments[i];            }            console.log(sum);        }        add(10, 20, 30, 40, 50);         // ES6: rest参数         /* 注意点: 1. rest得到的是真数组                 2. 重点是...   不是rest, rest只是一个叫法                3. 可以获取剩余参数                4. Rest参数必须是最后一个形参 */            function add(...rest){            // console.log(rest);// 转化为一个真数组[10, 20, 30, 40, 50]            let sum = 0;            rest.forEach(function(item){                sum+=item            })            console.log(sum);        }add(10, 20, 30, 40, 50);                      // 获取剩余参数         function fn(a,...b){            console.log(a,b);        }        fn(1,2,3);         // 剩余参数 放在中间---报错        function fn(a, ...b, c) {            console.log(a, b, c);        }        fn(1, 2, 3, 4, 5, 6, 7, 8, 9);//报错

拓展运算符,

也叫rest运算符,俗称叫“尾巴”解构

数组合并,对象合并

 // 拓展运算符: 将数组或对象中的值一个一个的拿出来        let arr = [10, 20, 30];        console.log(...arr);        let obj = {            name: "张三",            age: 20        };        // ...obj-------->name:"张三",age:20        console.log(...obj);        let str = "abc";        // ...str------>"a","b","c"        console.log(...str);        // 使用场景:        // 1. 函数传参使用拓展运算符        /* function fn(a,b,c){            console.log(a,b,c);        }        fn(...arr); */        // console.log(Math.max(10,20,80));        // console.log(Math.max(...arr));        // 2. 合并数组        let arr1 = [1, 2, 3];        let arr2 = [10, 20, 30];        let newArr = [...arr1, ...arr2];        // 不影响原数组        newArr[2] = 300;        // console.log(newArr);        // console.log(arr1);        // 3. 对象合并        let obj1 = {            name: "张三1",            age: 20,            gender: "男"        }        let obj2 = {            name: "张三2",            email: "zhangsan@163.com"        }        // 拓展运算符        let newObj1 = {...obj1,...obj2};        // *** 注意点: 对象的key不能重复的,后面的会覆盖前面的,比如name        // Object.assign key做对象的合并, 将第二个以及后面的对象参数合并到第一个对象参数中        // let newObj2 = Object.assign({}, obj2, obj1);        // 第一个参数传{}目的: 不改变原对象        let newObj2 = Object.assign(obj2, obj1);        // console.log(newObj1);        // console.log(newObj2);        // 4. 在解构赋值中使用        // 在解构赋值中,可以获取数组或字符串解构中剩余的值(不是rest参数)        let arrx = [10,20,30,40,50,60,70,80,90];        let [a,b,c,...d] = arrx;        console.log(a,b,c,d);        let strx = "申总好厉害!!!";        let [x,y,...z] = strx;        console.log(x,y,z);合并数组let a =[1,2,3];let b = [4,5,6];let c =[…a , …b];console.log(c); // [1,2,3,4,5,6]字符串转为数组[ …‘siva’ ] // [‘s’,‘i’,‘v’,‘a’]浅拷贝//数组var a = [1,2,4];var b = […a];a.push(6);console.log(b); //[1,2,4]//对象var a= {a:1};var b ={…a};a.a =5 ;console.log(b.a); //1

day02

箭头函数

    箭头函数写法的注意点:        1. 函数体只有一句话,可以省略{}不写        2. 函数体只有一句话(并且要返回), {}和return都可以不写        3. 函数只有一个参数,可以省略()不写        4. 反之,多个参数,多行函数体----肯定不能简写        5. ****如果需要返回一个对象,不能简写(函数的{}和对象的{}打起来了)        6. ****arguments在箭头函数中不能使用,但是可以使用rest参数
           // 1. 无参无返        let fn1 = () => console.log("今天是个靓仔");        fn1();        // 2. 无参有返        let fn2 = () => "靓仔";        console.log(fn2());        // 3. 有一个参数的函数        let fn3 = a=>console.log(a);        fn3(3);        // 4. 多参数,多行函数体,还有返回        let fn4 = (x,y)=>{            let sum = x+y;            return sum;        }        console.log(fn4(1,2));        // 5. 返回一个对象        /*            预期的返回数据类型            {                x:1,                y:2            }        */        let fn5 = (a,b)=>{            return {x:a,y:b};        }        console.log(fn5(1,2));        // 6. arguments的使用        // let fn6 = ()=>{        //     console.log(arguments);//报错        // }        let fn6 = (...a)=>{            console.log(a);        }        fn6(1,2,3,4,5);

this 指向

1.全局指向window

2.对象中----- 指向该对象,只有对象方法调用,函数作用域内的this才指向对象;

事件中—指向事件源

3.箭头函数中----指向外层作用域

4.构造函数 ------指向该实例对象指向的引用地址

5.call,apply 方法 ----指向借用的对象

Promise

Promise 的三个状态:

默认 pending

成功 resolve( ) ------> fulfilled

失败 reject ( ) ------> rejected

语法:var flag = true;var p = new Promise((resolve,reject)=>{if(flag){resolve('成功返回')}else{reject('抛出异常')})p.then(data=>{console.log(data);}).catch(error=>{console.log(error);})/*promise的两个方法 all  race1. Promise.all([多个Promise对象])   应用场景: 页面一进来,就要加载三个ajax,只有三个全部成功,才可以渲染页面 -----类似于&&特点:      1.1 如果多个异步程序都是成功状态, p的状态就是成功, 多个异步程序的成功结果会打包成一个数组统一返回     1.2 但凡发现一个失败,最快得到失败结果的直接返回     2. Promise.race([多个Promise对象])  ----- 类似于|| 特点:  谁快返回谁 */ 

用promise 解决回调地狱

         // 如何解决回调地狱----将异步代码改成看起来像同步代码(方便维护)        p1.then(data1=>{            console.log(data1);            return p2; //返回下一个 实例对象        }).then(data2=>{            console.log(data2);            return p3        }).then(data3=>{            console.log(data3);        }).catch(err=>{            console.log(err.responseText);        })

promise方法

Promise.all

返回结果由参数(Promise实例的结果)决定,分成两种情况。

(1)只有所有的实例fulfilled,返回才会变成 fulfilled

(2)只要实例有一个rejected返回的状态就变成 rejected`

Promise.race

返回结果跟随最快返回的那个实例的结果

Promise.any

接受一个数组包括多个Promise实例作为参数,返回新的Promise实例,只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态。如果所有参数实例都会变成rejected状态,包装实例就会变成rejected状态。

Promise.allSettled

接受一个数组包括多个Promise实例作为参数,返回传入的Promise的状态。相比于Promise的all方法,可以获取成功或失败的所有状态,因为Promise的all方法遇到一个rejected就会立即停止。

Set 和Map数据结构

new Set ()

  • Set 本身是一个构造函数,用来生成Set数据结构

  • Set 类似于数组,成员的值时唯一的

//Set 数组去重、遍历数组

let arr = new Set([1,2]);arr.size; //2  得到数组成员数量 

操作方法(操作数据)

add (value)   //添加某个值到数组中delete (value)  //删除某个值,返回布尔值has (value)     //判断是否为Set的成员clear()  //清除所有成员

遍历方法(遍历成员)

keys() //返回所有键名values() //返回键值的遍历器entries() //返回键值对forEach() //使用回调函数遍历每个成员

new Map()

  • Map本身也是一个构造函数,用来生成Map数据结构。

  • Map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当做键。

方法和Set 类似

day 03

自定义构造函数:

  1. 使用大驼峰命名(必须首字母大写(可以小写开头(几乎没人这样)));
  2. 不需要手动创建对象
  3. 通过 this(实例对象) 进行添加成员
  4. 不需要手动返回, 会自动返回
  5. 必须搭配 new 关键字进行实例化

自定义构造函数是如何创建对象的?(也叫new关键字做了什么

1.构造函数内部自动,默认创建了一个空对象 var obj = {};2.把这个空对象赋值给了this    this=obj;3.p. __proto__=Person.prototype; 将构造函数的 prototype 赋值给 实例对象的__proto__;4.给this身上添加成员  this.xxx = xxxx;5.自动返回了this 

对 对象进行分类

  // 人类        function Person(name, age) {            this.name = name;         }        // 狗类        function Dog(name, age) {            this.name = name;        }        var p = new Person("申五");        var d = new Dog("旺财");        console.log(p, d);        // 如何分类:         // 1. constructor 属性  获取 构造函数(又叫构造器)        console.log(p.constructor === Person);//true        // 2.instanceof 关键字  判断类型        // a instanceof b   判断a(对象)的类型是不是b(构造函数) 返回布尔值        console.log(p instanceof Person);// true        console.log(d instanceof Person);// false      

获取原型对象的 方式

1.实例对象.__proto__2.构造函数.prototype3.Object.getPrototypeOf(实例对象)

原型对象相关概念

  // 对象的成员有属性和方法        // 1. 构造函数----构造器(类)----创建对象用---------母亲        function Person(name, age) {            // 5. 实例成员-----name age            this.name = name;            this.age = age;        }        // 2. 原型对象----构造函数与生俱来的对象(夫妻)-----父亲        // Person.prototype    函数对象身上的属性prototype        // console.dir(Person);        // 6. 原型成员-----eat        Person.prototype.eat = function () {            console.log(this.name + "爱吃木桶饭");        }        // 3. 实例对象: 构造函数创建出来的新对象p        // 4. 实例化: new的过程 构造函数创建实例对象的过程        var p = new Person("张三", 20);        // 7. 静态成员-------- 给构造函数身上添加的成员        Person.showInfo = "这是一个人类";        // console.log(p.showInfo);// 实例不能使用静态成员        console.log(Person.showInfo);// *** 静态成员只能给构造函数使用        // 之前接触过吗????        // Object.assign()-----Object构造函数的静态成员方法

day 04

原型链访问规则:

原型链访问规则: 顺着__proto__往上去查找,父亲身上找不到,去爷爷身上去找.....1. 整个原型链都找不到  得到 undefined2. 就近原则(爸爸身上有,就不去爷爷身上找了;自己身上有,哪都不找)

完整的原型链结构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J1ms8c9E-1649943311958)(C:\Users\Administrator\Desktop\A截图\Snipaste_2022-03-21_14-42-33.png)]

day 06

异常捕获结构

 // js的代码错误:         // 1. 语法问题,浏览器报错        // console.log(a);// 报错        // 2. 逻辑错误, 浏览器不报错        // console.log(2==2==1);        // 异常处理1----即使报错,也不影响代码运行        /* try{            // 可能会出错的代码            console.log(a);        }catch(e){            // 异常的捕获            //e 是错误信息 error            console.log(e);        }finally{            console.log("不管怎么,都要运行");        } */        // 异常处理2------业务逻辑的问题        // 需求: 判断 函数的参数是不是数字,不是则报错(抛出异常)        function fn(num){            if(typeof num !== "number"){                // 主动抛出异常 throw                throw "数据类型错误";            }else{                console.log(num);            }        }        // fn("1");        try{            fn("1");        }catch(e){            // console.log(e);            if(e=="数据类型错误"){                alert("隔壁的老弟啥也不是!!!")            }        }

严格模式

 "use strict"; /*必须写在第一行 1.严格模式下,不能未声明就赋值 2.有作用域  严格模式写在全局,全局生效,写在局部作用域,局部作用域生效 3.严格模式下,this禁止指向window  ---undefined */  //a=10; //报错  function fn1() {            // "use strict";            x = 1;            console.log(x);        }        fn1();                 function fn(){            console.log(this); //undefined        }        // console.log(this);        fn();

立即执行函数

//立即执行函数,本质上将函数变为函数表达式直接调用 // 优点: 1. 初始化变量(防止全局变量的污染)   //2.全局变量私有化(创建独立作用域) // 需求: 点击不同的按钮,显示对应的索引    /*  var btns = document.getElementsByTagName("button");        for (var i = 0; i < btns.length; i++) {            btns[i].myIndex = i; //添加属性 = i  ------ 这一步相当于 存索引            btns[i].οnclick=function(){                // console.log(i);                console.log(this.myIndex);            }        } */        // 使用立即执行函数解决        var btns = document.getElementsByTagName("button");        for (var i = 0; i < btns.length; i++) {            // 每一次循环,都会创建一个独立的作用域            // 功能: 全局变量私有化            (function (ii) {                btns[ii].onclick = function () {                    console.log(ii);                }            })(i)// 实参        }

闭包

//闭包:函数中返回一个函数的结构/* 特点 1. 防止全局变量的污染 2. 保护了私有变量的安全,不会被修改 3. 让函数外部访问局部变量成为可能,打破了作用域的限制,延迟了变量的生命周期 4. 会造成内层泄露的问题(有一块内存永远被占用不会释放) */ function fn(){            var a = 10;            return function(){                return a            }        }    var x =  fn();     console.log(x());    // console.log(fn()()); //第一个调用外面函数  第二个调用里面的函数            

定时器和闭包

  // 每隔一秒打印1~10        for(var i = 1;i<11;i++){            // 定时器 参数设置---- 第三个及以后的参数都是传给第一个函数的参数            // 定时器允许传参接受第三个及以上的参数            // 第三个及以上的参数都是传给第一个函数的参数            // setTimeout(fn,time,a,b....)            setTimeout(fn(),1000*i,i)        }        // 闭包---函数内部返回一个函数的结构        function fn(ii){            return function(ii){                console.log(ii);            }        }

DOM操作和闭包

 // 需求: 点击不同的按钮,显示对应的索引        var btns = document.getElementsByTagName("button");        for (var i = 0; i < btns.length; i++) {            //for  同步            // 点击事件是异步的            btns[i].onclick=fn(i);        }        // 闭包: 打破了作用域的限制        function fn(ii){            return function(){                // 异步                console.log(ii);            }        }

递归

//递归: 函数中调用函数自己的结构 var i =0;        function fn (){            i++            if (i<6){//入口                console.log('天气真好');                fn();            }//出口        }        fn();        

递归阶乘

//阶乘的递归// 阶乘 : 3!  3*2*1// 求n 的阶乘(函数封装)        function fn(n) {            // 需要一个出口            if (n <= 1) {                 return 1;            }            return n*fn(n-1)//入口            //3*fn(3-1)---3*2*fn(2-1)---3*2*1*fn(1-1)//n=1 return  1        }        console.log(fn(3));

关于深拷贝和浅拷贝

1)浅拷贝

    • Object.assign() 该方法用于对象复制时,也是浅拷贝
    • 数组的slice方法、concat方法、Array.from方法以及扩展运算符都算是浅拷贝

2)深拷贝

    • 递归方案 经典的方案 (其实就是通过循环一层一层的进行拷贝)
    • JSON.parse()方法 这个方案简单易懂,不过也有缺点,对于undefined、function、symbol 会在转换过程中被忽略

深拷贝

    var obj = {            name:'张三',            age:23,            faves:['打球','听音乐','跑步'],            wife:{                name:'李四',                age:20,                faves:['爱马仕','古驰','香奈儿']            }        }        var obj2 ={};  // 浅拷贝        /*    for(var k in obj){               obj2[k]=obj[k];           }           obj2.wife.age = 30; //一改全改           console.log(obj);           console.log(obj2); */        function deepCopy(cur,tar){            for(var k in cur){//1.遍历对象cur ----obj                if(cur.hasOwnProperty(k)){//2.获取 构造函数里面的实例成员                    // console.log(k); name age faves wife                    if(typeof cur[k]==='object'){ //3.判断基本数据类型 和复杂(引用)数据类型                        // console.log(k); //faves wife                        tar[k]= Array.isArray(cur[k])?[]:{};                         deepCopy(cur[k],tar[k]); //调用函数 判断 faves wife里面的实例成员                                           }else{                       tar[k]=cur[k]; //name,age                                          }                }            }        }        deepCopy(obj,obj2)        obj2.wife.age =30;        console.log(obj,obj2);

冒泡排序算法

var  arr = [1,7,3,267,9];for(var i=0;i<arr.length-1;i++){for(var j=i+1;j<arr.length;j++){if(arr[i]<arr[j]){[arr[i].arr[j]]=[arr[j].arr[i]];}}}console.log(arr);

sort 方法排序

    // js封装好的一种排序方法            console.dir(Array);        // sort Array的原型方法------可以给数组的所有实例使用            // 真 sort 排序--------工作要用        var arr = [2, 5, 1, 4547, 3];        var newArr = arr.sort((a,b)=>{            // 升序  a-b            // return a-b;            // 降序            return b-a;        })        console.log(newArr);

day 07

正则

 // 正则: 编程语言的常识-----数组,对象        // 正则表达式本质上是对象        // 用来创建规则校验字符串        // 创建一: 内置构造函数创建         let reg = new RegExp("a");        // console.log(typeof reg);// 实例对象        // 创建二: 字面量创建   /正则表达式/        let reg = /a/i;        /*            修饰符(很少用):             i 忽略大小写            m 多行匹配            g 全局匹配            \d  取数字            \D  取不是数字的            \w  取数字、字母            \W  取不是数字字母的            \s  取空格            \S  取不是空格*/// 手机号码校验 以1开头 第2个数3-9  第3~11位 0-9        var reg = /^1[3-9][0-9]{9}$/;        console.log(reg.test('13523343455')); //true        console.log(reg.test('12455656777')); //false        console.log(reg.test('1331235346'));   //false        // 十六进制 颜色 校验        // 一共7个字符 以#开头    后面六个字符是 十六进制 0-9a-fA-F        var reg1 = /^#[ 0-9a-fA-F]{6}$/;        console.log(reg1.test('#cececf'));//true        console.log(reg1.test('ccececf'));//false        console.log(reg1.test('#cecech'));//false

执行栈

 // 执行栈的调用规则: 先入后出  (包括栈内存也是先入后出,堆内存是列队----先入先出)        // 也叫执行环境的   入栈(压栈) 和 出栈(弹栈)

任务列队

   // 任务列队-------先入先出        setTimeout(() => {            console.log("定时器1");            // 定时器3 再500ms之后进入列队,此时 定时器2只剩500ms            // 如果定时器时间相同----先入先出            setTimeout(() => {                console.log("定时器3");            }, 400)        }, 500)        //         setTimeout(() => {            console.log("定时器2");        }, 1000)        // 先执行同步再执行异步---------js的单线程        // for (var i = 0; i < 10000; i++) {        //     console.log("同步");        // }

node

day01

node环境安装

方法一: 直接安装

Node官网 或者 民间翻译更好的网站 下载安装

方法二: nvm方式安装 (比较推荐)

NVM(Node version Manager) 一个用于管理Node多版本的工具。

实现快速切换node版本的需求

  1. 下载nvm安装包

然后直接安装(如果自己之前安装过node,需要先卸载之前安装的node)

双击安装包,选择接受accept ,第一个目录必须是中文(可以自己选择目录),然后电脑 win + R 建打开,输入nvm version 得到版本号就说明安装成功。

  1. 设置nvm的镜像地址

    打开nvm的安装目录,打开里面的settings.txt,可以对里面的镜像地址进行设置,可以把下面的两行复制到最后

    node_mirror: https://npm.taobao.org/mirrors/node/npm_mirror: https://npm.taobao.org/mirrors/npm/

    因为默认情况下,nvm帮我们下载node环境的时候会到国外的地址下载,我们可以手动改为国内的。不过有时候国内的镜像有时候会崩,如果下载过慢,也可以尝试把这两行删除,再重新下载。

    不行让别人发一份放在nvm的安装目录 也可以使用

    1. 使用nvm 安装node

      win + R 输入cmd (命令行工具)

      nvm install node版本号

    nvm install 14.18.2

    依然在cmd 输入 nvm list查看已经安装的版本

    切换使用需要的版本 nvm use 指定版本号

    nvm use 14.18.2

    此时在cmd里面输入 node -v 就可以查看当前的node版本

    总结:

    1. nvm是一个版本管理工具,安装的时候不能安装在中文目录下
    2. nvm主要命令
      1. nvm version 查看nvm版本
      2. nvm list 查看当前安装的所有node版本
      3. nvm install node版本 安装指定版本的node环境
      4. nvm use node版本 切换指定版本的node环境
    3. 如果下载过慢可以自己更改镜像地址,也可以向同桌要一份已经下载好的

day 02

模块化:以功能为界限,将代码切割为多个js 文件。

作用:提高代码的复用性、扩展性、可维护性。

模块化 在js的发展中 出现过4个标准:AMD 、CMD 、CommonJS、ES Module(ES6)

CommonJS模块化

导出:module.exports = { 导出的数据 }或者module.exports.键 = 导出的数据或者exports.键 = 导出的数据导入:const 模块名 = require('模块'

ES Module(ES6模块化)

导出:export default 要导出的对象 // 默认导出  只能写一次export  { 数据 }    // 按需导出导入:import 模块名 from '模块或者路径'   //默认导入import {数据 , 数据 ...} from '模块或者路径'   // 按需导入import  默认,{按需} from  '模块或路径'     // 混合导入

例如

导出

// 默认导出export default add// 按需导出export { add , reduce }function add(a,b) { return a + b }function reduce(a,b) { return a - b }

导入

// 默认导入import fn from './a.js'// 按需导入import {add} from 'a.js'// 混合导入import fn,{add,reduce} from './a.js'

npm (包管理工具)

node中自带的包管理工具叫 NPM(Node Package Manager),其实说白了无非也是一个软件,只是我们在安装Node的时候就已经"捆绑"安装了。只需要在cmd中输入 npm -v 就能看到当前的npm的版本号。

作用

  1. 下载并管理项目中使用到的第三方式模块(包)
  2. 发布自己的模块到npmjs平台

使用

步骤1:初始化项目

在一个项目中初次使用npm,需要先交项目初始化。在自己项目的根目录,打开终端,输入

npm init -y

会得到一个package.json文件,文件描述了我们整个node项目的基本信息。

步骤2:下载需要使用的第三方模块

npm install 模块名称例如:npm install colors

下载完成我们会发现在根目录下多了一个node_modules文件,里面就是我们下载下来的模块。

步骤3:在https://npmjs.com 查找对应的文档学习如何使用下载下来的模块。

npm安装模式

npm安装第三方模块有三种方式:

1.全局依赖方式 - npm install -g   一次安装,在任何项目都能用,一般是方便项目构建的工具2.生产依赖方式 - npm install -S   上线需要依赖的模块 比如jquey3.开发依赖方式 - npm install -D   只是在开发的时候使用的模块,上线不需要使用 比如color,less

nodemon 工具 : 可以在我们保存代码的时候就自动重启代码

安装nodemon

npm install -g nodemon

如果报错显示:nodemon 无法加载文件XXX,因为此系统上禁止运行脚本:

1.以管理员身份打开Windows PowerShell

  1. 输入 set-ExecutionPolicy RemoteSigned 命令

3.选择 A 或者 Y

4.重新运行nodemon,就会发现已经运行成功了。

全局安装了nodemon后,只需要把node命令换成nodemon即可

yarn (包管理工具)

Yarn 是于 2016 年 10 月 由 Facebook、Google、Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具,旨在取代 npm 这种包管理工具。

官网:
https://yarnpkg.com/en/docs

中文参考链接:
https://yarn.bootcss.com/

特点

  • 速度超快

yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率,因此安装速度更快。

  • 超级安全

在执行代码之前,yarn 会通过算法校验每个安装包的完整性。

  • 超级可靠

使用详细、简洁的锁文件格式和明确的安装算法,yarn 能够保证在不同系统上无差异的工作。

安装:

管理员模式运行cmd :npm install -g yarn

常用命令

npmyarn
npm init -yyarn init -y
npm install react --saveyarn add react
npm uninstall react --saveyarn remove react
npm install react --save-devyarn add react --dev
npm update --saveyarn upgrade
npm install -g nodemonyarn global add nodemon

yarn 全局安装后,命令不生效

背景:

  1. 执行 yarn global add nodemon 后,重启 bash…`, vue 命令依然不生效
  2. 而 npm 全局安装(npm install -g nodemon)后,命令生效

解决办法:

1.执行如下命令,得出 yarn 全局安装的命令所处的安装目录

yarn global bin 

2.复制安装目录至电脑的环境变量中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z4z6pOvO-1649943311960)(F:/叩丁狼/06-nodejs/211224Node第二天/笔记/assets/2018110718150477.png)]

3.重新启动终端,发现全局命令行可以生效了

yarn和npm的对比

  • 速度

      npm 是按照队列执行每个 package,也就是说必须要等到当前 package 安装完成之后,才能继续后面的安装。  而 Yarn 是同步执行所有任务,提高了性能。
  • 安装版本统一

     Yarn 默认会生成这样的锁定文件 npm 要通过 shrinkwrap 命令生成 npm-shrinkwrap.json 文件,只有当这个文件存在的时候,packages 版本信息才会被记录和更新。 npm5.0之后新增了类似yarn.lock的 package-lock.json。如果软件包的根目录中同时存在package-lock.json和npm-shrinkwrap.json,package-lock.json将被完全忽略。
  • 更简洁的输出

    npm 的输出信息比较冗长。在执行 npm install <package> 的时候,命令行里会不断地打印出所有被安装上的依赖。Yarn 简洁太多:默认情况下,结合了 emoji直观且直接地打印出必要的信息,也提供了一些命令供开发者查询额外的安装信息。

package.json 文件

我们发现使用yarn和npm,都要先把项目初始化,而初始化的结果就是生成一个package.json文件。这个文件到底有什么用?

  1. 记录了你这个项目的主要信息
  2. 可以明确项目的依赖,将来即使把node_modules删除了,也可以通过这个文件找回
  3. 声明简短 的命令,来代替复杂的命令

小结:

  1. 包管理工具是我们在后面的学习,以后的工具中一定会用到的,所以一定要会使用
  2. 每个项目一定要检查有没有 package.json ,如果没有,一定要先 创建一个 package.json npm init -y
  3. node_modules文件夹里面就是我们下载的第三方模块,在传输代码的时候要记得排除这部分
  4. 将来在工作中,yarn或者npm都可能会使用,要熟悉对应的命令


参考文章:https://blog.csdn.net/CSSAJBQ_/article/details/124182400

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时候联系我们修改或删除,在此表示感谢。

特别提醒:

1、请用户自行保存原始数据,为确保安全网站使用完即被永久销毁,如何人将无法再次获取。

2、如果上次文件较大或者涉及到复杂运算的数据,可能需要一定的时间,请耐心等待一会。

3、请按照用户协议文明上网,如果发现用户存在恶意行为,包括但不限于发布不合适言论妄图

     获取用户隐私信息等行为,网站将根据掌握的情况对用户进行限制部分行为、永久封号等处罚。

4、如果文件下载失败可能是弹出窗口被浏览器拦截,点击允许弹出即可,一般在网址栏位置设置

5、欢迎将网站推荐给其他人,网站持续更新更多功能敬请期待,收藏网站高效办公不迷路。

      



登录后回复

共有0条评论