JavaScript第二周笔记

JavaScript第二周总结

冒泡排序

冒泡

  1. 从下往上冒,冒到最上面就破掉,结束

  1. 需要好几轮

  1. 每一轮比较好几次

  1. 当前元素 跟后一个元素进行比较

  1. 第一轮 正序能找出最大值 倒序一定能找到最小,

  1. 第二轮 正序能找出倒数第二大值 倒序一定能找到倒数第二小值,

  1. 下一轮一定比上一轮少一次 (通过4 5得出结论)

  1. 口诀

  1. 双重for循环 一层减一次

  1. 里层减外层 变量想交换

总共需要 length -1轮

每一轮 需要 length-1-轮数 次

i == 0 第0轮 少 0次 length-1-i

i ==1 第1轮 少1次 length-1-i

i==2 第2轮 少2次 length-1-i

     /**
         *  算法: 解决某一个问题, 性能相对更好的哪一个解决方案
        */


        // 需求: 对比数组前一项与他的后一项, 如果前一项的值大于后一项的, 那么将前后两项交换位置
        // var arr = [9, 3, 6, 2, 4, 1, 8, 5, 7]
        // console.log('原数组', arr)

        // 算法: 冒泡排序 (未优化)
        // for (var k = 0; k < arr.length; k++) {
        //     for (var i = 0; i < arr.length; i++) {
        //         if (arr[i] > arr[i + 1]) {
        //             var tem = arr[i]    // 存储最开始 [0] 的值
        //             arr[i] = arr[i + 1]
        //             arr[i + 1] = tem     // 需要使用 最开始 [0] 的值
        //         }
        //     }
        // }


var arr = [9, 3, 6, 2, 4, 1, 8, 5, 7]
        // 下标     0 1  2  3  4  5  6  7  8        length: 9
        console.log('原数组', arr)
        // 优化1
        for (var k = 0; k < arr.length; k++) {  // 决定内部的 冒泡排序执行多少次
            // 内循环: 冒泡排序的核心代码
            /**
             * 
             * for (var i = 0; i < arr.length; i++) {
             *      当前 i 的值为 0~8
             * 
             *      如果最后一轮循环的时候, i === 8
             *          分支语句: if (arr[i] > arr[i + 1])  -> if (arr[8] > arr[9])
             *          因为没有 下标9 的项, 所以当前循环最后一轮是没有意义的, 我们应该减少最一轮循环
             *          所以循环的结束条件应该修改为 i < arr.length - 1
             */
            for (var i = 0; i < arr.length - 1; i++) {
                if (arr[i] > arr[i + 1]) {
                    var tem = arr[i]
                    arr[i] = arr[i + 1]
                    arr[i + 1] = tem
                }
            }
        }




 var nums = [14,2,9,5,10,1,3,7,6,8,4,11,13,12,15];
        console.log('原数组',nums);
        // 第二轮相比第一轮少比较一次
        // 第三轮相比第二轮少比较一次
        // 第四轮相比第三轮少比较一次
        // i == 0  内层循环 少 0次
        // i == 1  内层循环 少 1次
        // i == 2  内层循环 少 2次
        // length - 1-i 第0轮 比较 14
        // length - 1-i 第1轮 比较 13
        // length - 1-i 第2轮 比较 12
        //  1  
        //结束 

        for(var i=0;i<nums.length-1;i++){    //控制几轮 最多14轮 长度-1轮
           for(var j=0;j<nums.length-1-i;j++){ // 控制每一轮的比较次数 最多 nums.length-i-1次
                if(nums[j]<nums[j+1]){
                    var temp = nums[j];
                    nums[j] = nums[j+1];
                    nums[j+1] = temp;
                }
                // console.log(`第${i+1}轮第${j+1}次比较结果是${nums}`);
           }
        //    console.log(`第${i+1}轮结果是${nums}`);
        }
        console.log(nums);

选择排序

  1. 第一轮 找所有元素的最小值 找到以后跟下标[0]进行交换 第一轮结束

  1. 第二轮 下标0不用参与 从下标1到最后 找最小值 找到最小值以后 跟下标1交换

第二轮结束

  1. 第三轮 下标0 下标1 不用参与了 下标2开始 到最后 找到最小值 然后跟下标2交换 第三轮结束

  1. 第四轮 下标0 下标1 下标2 都不用参与了 下标3开始到最后 找到最小值 然后跟下标3交换

找最小值 假设 min = 下标0是最小值 从下标1到最后 挨个跟min比较 ,如果比它小

替换min中的值

规律:

第几轮 跟谁交换 假设最小值的索引 从下标几开始循环

1 0 0 1

2 1 1 2

3 2 2 3


  var arr = [9, 3, 6, 2, 4, 1, 8, 5, 7];

        for(var k =0;k<arr.length;k++){
            var minIndex = k;
            for(var j=k+1;j<arr.length;j++){
                if(arr[minIndex]>arr[j]){
                  minIndex=j;
                }
            }
            var num = arr[k];
            arr[k]= arr[minIndex];
            arr[minIndex]= num;
        }
        console.log(arr);
       

数据类型之间存储的区别

数据类型之间的区别

//

/*

1.基本数据类型

2.复杂数据类型

=> 存储的区别

1.基本数据类型(string,number,undeifined,null,boolean)

直接将数据类型存储到 栈内存中

2.复杂数据类型 (object,array,function )

将数据本体存在堆内存中 ,然后将指向堆内存的地址,存储在变量名中,最后变量名存储在 栈内存中,

=> 赋值的区别

1.基本数据类型

直接将数据赋值给另一个变量

2.复杂数据类型

因为 复杂数据类型的变量名中 存储的是指向一个堆内存的地址,所以在赋值的时候,就把这个地址赋值给另一个变量了

所以修改另一个变量的时候,会影响自身

=> 比较的区别

1.基本数据类型 直接将数据进行对比

2.复杂数据类型 因为变量内部存储的是一个地址,所以对比时 对比的是地址,而不是真正的值

=> 传参的区别

1.基本数据类型

将 数据拷贝一份给形参,在函数内 对形参的修改听不会影响外界

2.复杂数据类型

讲变量内部存储的地址 ,赋值给形参 也就是说函数内部的形参 和外部的变量 共享一个地址

所以在函数内对形参的修改会影响外界

存储的区别

var arr = [1,2,3,4,5,6]

var arr1=[1,2,3,4,5,6]

consloe.log(arr ===arr1)

赋值的区别

数组的常用方法

数组.方法名();
1.原数组发生变化
2.原数组不变 给到的结果是一个新的数组

第一部分:

栈方法 先进后出 后进先出 电梯 操作的是数组的结尾

push();

语法: 数组名.push(数据);

作用: 数组的末尾追加数据

返回值: 追加数据以后 数组最新的长度

pop();

语法: 数组名.pop(); // 括号中不用写数据

作用: 删除数组的最后一个数据

返回值:被删除的数据

队列方法 先进先出 管道 操作的是数组的开头

unshift();

语法: 数组名.unshift(数据);

作用: 数组的开头追加数据

返回值: 追加数据以后 数组最新的长度

shift();

语法: 数组名.shift(); // 括号中什么也不写

作用: 删除数组的第一个数据

返回值:被删除的数据

第二部分:

反转数组

reverse();

语法:数组.reverse();

作用: 反转数组. 反转 仅仅是倒过来 不排序

返回值:反转以后的数组; 原数组发生变化

排序

sort();

语法: 数组.sort();

作用: 对数组内的数据进行排序

返回值: 排序后的数组 原数组发生变化

一个方法默认对字母进行排序 同时 又能排序数字

结果不如我们所愿 排序数字的时候 可能不准确

为了保证准确 我们需要手动干预

干预的方式就是传一个匿名函数

语法:

数组.sort(function(a,b){return a-b}); 升序

数组.sort(function(a,b){return b-a}); 降序

数组.sort(function(a,b){if(a>b){return 1}else{return -1}})

数组.sort(function(a,b){if(a<b){return 1}else{return -1}})

以后开发如果你不想单独写排序方法,可以采用sort();

但是排序的是数字,必须手动干预 .

截取数组

splice();

数组的增

数组.splice(开始的索引,0,插入的数据1,数据2,...数据n);

截取0个放入一个或者多个

数组的删

数组.splice(开始的索引,多少个);

截取多个 不放里插入

数组的改

数组.splice(开始的索引,多少个,插入的数据1,数据2,数据n);

截取多少个 插入多少个

第三部分:

前两部分 直接改变原数组

第三部分 结果会放到一个新的数组中 不会影响原数组

  1. concat()

语法: 原数组.concat(数组1,数组2,数组3,数据1);

作用: 进行数组拼接,将参数的所有数组或者数据 都拼接在原始数组身上

返回值: 拼接好的数组

跟push()的区别

=> 是否改变原数组

push 直接改变原始数组

concat 不会改变原始数组

=> 插入数据

push 直接把数据插入到数组的结尾

concat 如果遇到数组 就把数组拆开 把每一个数据依次插入

 // concat 结果放到一个新数组中 不会对原数组产生影响
        var xiaobao = ['建宁公主','双儿','沐剑屏','曾柔','方怡','苏荃','阿珂'];
        
        console.log('原始数组',xiaobao);
        // var arr = xiaobao.concat(['曾哥','春哥'],'坤坤','小白',['凤姐','芙蓉姐姐']);
        // console.log('拼接后的原数组',xiaobao);
        // console.log('拼接后的新数组',arr);


        // 复制一个一模一样的数组 
        // concat方法  
        var newArr = xiaobao.concat();
        console.log('拼接后的原数组',xiaobao);
        xiaobao[0] = '建宁公主儿子';
        console.log('拼接后的原数组',xiaobao);
        console.log('复制后的新数组',newArr);
  1. join() 数组转字符串的方法

语法:数组.join('连接符');

作用: 使用连接符将数组内的每个元素 连接成一个字符串 (不写连接符 默认用逗号)

返回值:连接好的字符串

var xiaobao = ['建宁公主','双儿','沐剑屏','曾柔','方怡','苏荃','阿珂'];
        
        console.log('原始数组',xiaobao);
        var res = xiaobao.join(' ̄▽ ̄');
        var res1 = xiaobao.join();

        console.log('拼接后原数组',xiaobao);
        console.log('拼接后的字符串',res);
        console.log('拼接后的字符串',res1); // join 什麽都不寫 就是逗號 
        
  1. slice();

语法: 数组.slice(开始索引,结束索引); //[1,10] 1<=x<=10 (1,10) 1<x<10

// [1,10) 1<=x<10

参数的特点:

1:左闭右开 包含开始索引 不包含结束索引

2:开始索引不写 默认开始索引为0 结束索引不写 默认为length

  1. 可以是负数 表示倒数第几个 等同于 length+负数

[1,2,3]

从左到右 0 1 2

从右往左 -3 -2 -1

作用: 截取数组的部分内容

返回值: 截取后的新数组

和 splice 的区别:

1. 是否改变元数组

           		1. splice 改变原数组
           		2. slice 不改变原数组 
          		2. 参数
                  		1.  splice(开始的位置,多少个)
                  		2. slice(开始的索引,结束的索引)
  1. indexOf()

语法: 数组.indexOf('数据');

数组.indexOf('数据',开始的索引);

作用:

从左往右 检索该数据第一次出现在数组中的位置

返回值:

如果数组中 有这个数据 那么返回该数据第一次出现的索引位置

如果数组中没有这个数据 那么返回 -1

  1. lastIndexOf()

语法: 数组.lastIndexOf('数据');

数组.lastIndexOf('数据',开始的索引);

作用:

从右往左 检索该数据第一次出现在数组中的位置

返回值:

如果数组中 有这个数据 那么返回该数据第一次出现的索引位置

如果数组中没有这个数据 那么返回 -1

# 数组的高级方法 (遍历)

1.forEach

语法:数组.forEach(function(item,index,origin){遍历数组需要执行的代码})

item:遍历数组的当前项

\ index:item对应的下标

\ origin:对应的原数组

作用:遍历数组

返回值:forEach 永远没有返回值,他的值永远是undefined

2.map

语法:数组.map(function(){遍历数组需要执行的代码})

item:遍历数组的当前项

index:item对应的下标

origin:对应的原数组

作用:映射数组,映射出来一个数组长度与原数组长度一模一样的数组,但是新数组的值,取决于return

返回值:映射出来的数组

使用for 遍历数组

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

consloe.log(arr[i])}

3.filter

语法:数组.filter(item ,index,origin){}

作用:过滤数组

返回值:过滤后的新数组,过滤条件取决于函数内的return

4.find

语法:数组.find(item ,index,origin){}

作用:查找数据

返回值:在数组内找到的第一个符合条件的数据(不是数组)

5.findIndex

语法:数组.findIndex(item ,index,origin){}

作用:查找数据第一次出现的下标

返回值:在数组内找到的第一个符合条件的数据的下标(不是数组)

如果找不到 返回 -1

6.every

语法:数组.every(item ,index,origin){}

作用:判断数组的每一项是否都符合条件

返回值:如果都符合条件返回true

fasle 至少有一个不符合的

7..some

\ 语法:数组.some(item ,index,origin){}

作用:判断数组是否有一项符合条件

返回值:如果有一项符合条件返回true

fasle 都不符合条件

数组塌陷

// var ages = [3, 10, 18, 20,20,20,20,30, 40, 50, 60, 70, 80, 90, 100];
        //          0   1   2   3  4   5
        // // 删除数组中的20
        // for(var k in ages){
        //     if(ages[k] == 20){
        //         ages.splice(k,1);
        //     }
        // }
        // 4个20只删除了 两个  两个没有被删除 这就是数组塌陷 

        // console.log(ages);
        
        // 解决方案 1 从后往前删除 
        // for(var i=ages.length-1; i>=0; i--){
        //     if(ages[i] == 20){
        //         ages.splice(i,1);
        //     }
        // }
        // console.log(ages);

        // 解决方案 2 从前往后删除 

        // 只要遇到20 删除 这次数从新开始  
        // var ages = [3, 10, 18, 20,20,20,20,30, 40, 50, 60, 70, 80, 90, 100];    
        // for(var i=0;i<ages.length;i++){
        //     if(ages[i] == 20){
        //         ages.splice(i,1);
        //         i--;   // 遇到20 删除 这次数从新开始   
        //     }
        // }

        // console.log(ages); 





/**
         * 数组塌陷
         * */ 
         var arr =[1,2,3,4,5]
        //  删除数组的所有项
        for(var  i =0 ;i<arr.length;i++){
            arr.splice(i,1)
        }
        /**
         * 
         * 
         *1. 使用for循环遍历数组
          2.使用splice删除了 数组的某一项
          此时会出现数组塌陷,解决方式就是在splice后加一个行 i--
        **/





        /**
         *  第 1 轮 for 循环
         *      i === 0     i < arr.length  符合条件, 执行代码
         *          1. arr.splice(i, 1)     -> arr.splice(0, 1)
         *              这一步是将 数组 [0] 剪切掉
         *              剪切后的数组 [2, 3, 4, 5]
         * 
         *  第 2 轮
         *      i === 1     符合条件
         *          1. arr.splice(i, 1)     -> arr.splice(1, 1)
         *              这一步是将数组 [1] 剪切掉
         *              截切后的数组 [2, 4, 5]
         * 
         *  第 3 轮
         *      i === 2     符合条件
         *          1. arr.splice(i, 1)     -> arr.splice(2, 1)
         *              这一步是将数组 [2] 剪切掉
         *              剪切后的数组 [2, 4]
         * 
         *  第 4 轮
         *      i === 3     不符合条件  所以循环到此结束
        */

        console.log(arr)    // []

数组累加

/**
         *  数组提供的方法: reduce  (一般习惯性叫做累加器)
         * 
         *  也算是 数组遍历中的一个方法, 但是使用的时候和之前的方法有一点小区别
         * 
         *      语法:
         *          数组.reduce(function (prev, item, index, origin) {}, init)
         *                  prev: 表示初始值(需要传递init)  或者表示数组[0]的值(需要不传递init)
         *                  item: 如果传递了 init, item 的值为 数组[0]      如果没有传递 init,                             item 的值为 数组[1]
         *                  index/origin:    与forEach 相同
         *      注意:
         *          init 为可选项
         *          如果书写了 init, 那么 prev 的第一次的值, 就是由 init 传递的, 然后 item 的值是从 [0] 开始的
         *          如果没有书写 init, 那么 prev 的第一次的值, 是数组 [0] 的值, 然后 item 的值使用[1]
         *      作用: 累加(叠加)
         *      返回值: 循环运行后的值
         */


应用

  var arr = [1, 2, 3, 4, 5]

        var res = arr.reduce(function (prev, item, index, origin) {
            return prev + item
        })

        console.log(res)

注意事项


 /**
         * reduce   数组提供方法  :reduce(一般叫累加器)
         *          也算是 数组遍历的一个方法,但是使用时跟之前有一些区别
         *        
         *          语法: 数组.reduce(function(prev,item,index,origin){},init)
         *                 prev :表示初始值(需要传递init) 或者表示数组[0]的值(不需要传递init)
         *                 item:如果传递了 init ,item 的值为数组[0]  如果没有传递init ,item的值为数组[1]
         *                 index/origin :  与forEach 相同
         * 
         *          注意:
         *                注意: 叠加条件以 return 的形式书写
                          注意: prev 的值, 如果你传递了 init, 就是 init 的值, 如果你没有传递 init, 那么就是数组 [0] 的值
                          注意: 如果你传递了 init, 循环执行 length 次, 如果你没有传递 init, 循环执行 length - 1 次, 少的是第一次
         * 
         * **/

字符串

创建字符串

  // 字面量的方式创建
        var str =' QF001'
        // 内置构造函数
        var  str1 = String('QF002')
        var arr  =  [100, 200 ,300]
        arr[0] =1
        console.log(arr)
       //   字符串也有对应的索引与下标
       var str = 'QF123'
       console.log(str[0]);
       console.log(str[1]) 
       str[0] = '1234567890'  //字符串的索引获取到的是只读属性,也就是说,能看但是不能修改

       console.log(str)
       console.log(str.length);

字符串的属性 重点

原字符串 永不改变
      1. length 属性
        + 表示字符串的长度, 该字符串有多少字符组成
        + 是一个 只读 的属性
        + 读:
          => 语法: 字符串.length
          => 得到: 该字符串有多少字符组成
          
          

      2. 索引属性
        + 字符串也是按照索引排列的, 索引: 从 0 开始, 依次 +1
        + 是一个只读属性
        + 读:
          => 语法: 字符串[索引]
          => 得到: 该索引位置的字符, 或者 undefined

      3. 遍历
        + 因为字符串也是按照索引排列
        + 可以使用循环遍历字符串

字符串的常用方法

 字符串常用方法
        + 通用语法: 字符串.方法名()
        + 注意: 所有的字符串常用方法都会不改变原始字符串, 而是以返回值形式给出结果

      1. charAt()
        + 语法: 字符串.charAt(索引)
        + 返回值: 该索引位置的字符
          => 如果没有该索引位置, 返回的是 空字符串

      2. charCodeAt()
        + 语法: 字符串.charCodeAt(索引)
        + 返回值: 该索引位置字符的 unicode 编码
          => 如果没有该索引位置, 返回的是 NaN

      3. toUpperCase()
        + 语法: 字符串.toUpperCase()
        + 返回值: 将原始字符串内的所有字母转换成大写

      4. toLowerCase()
        + 语法: 字符串.toLowerCase()
        + 返回值: 将原始字符串内的所有字母转换成小写

      5. substr()
        + 语法: 字符串.substr(开始索引, 多少个) 
            => 类似数组的方法:splice(开始的索引,多少个);
        + 返回值: 截取出来的部分字符串

      6. substring()
        + 语法: 字符串.substring(开始索引, 结束索引)
        + 特点: 包前不包后 [开始索引,结束索引)
        + 返回值: 截取出来的部分字符串

      7. slice()
        + 语法: 字符串.slice(开始索引, 结束索引)
        + 特点: 包前不包后, 填写负整数
        + 返回值: 截取出来的部分字符串

      8. split()
        + 语法: 字符串.split('分隔符')
        + 返回值: 是一个数组
          => 按照分隔符把字符串分开成为几段内容

      9. concat()
        + 语法: 字符串.concat(字符串1, 字符串2, ...)
        + 返回值: 拼接好的字符串

      10. indexOf()
        + 语法: 字符串.indexOf(查找的字符, 开始索引)
        + 返回值:
          => 如果原始字符串内有该字符串片段, 那么是该字符串片段第一次出现的首字母索引位置
          => 如果原始字符串内没有该字符串片段, 那么是 -1

      11. lastIndexOf()
        + 语法: 字符串.lastIndexOf(字符串片段, 开始索引)
        + 返回值:
          => 如果原始字符串内有该字符串片段, 那么是该字符串片段第一次出现的首字母索引位置
          => 如果原始字符串内没有该字符串片段, 那么是 -1

      12. includes()
        + 语法: 字符串.includes(字符串片段)
        + 作用: 该字符串中是否包含该字符串片段
        + 返回值: 一个布尔值
          => true 说明有该字符串片段
          => false 说明没有该字符串片段

      13. startsWith()
        + 语法: 字符串.startsWith(字符串片段)
        + 作用: 判断该字符串是否以该字符串片段开头
        + 返回值: 一个布尔值
          => true 说明以该字符串片段开头
          => false 说明不以该字符串片段开头

      14. endsWith()
        + 语法: 字符串.endsWith(字符串片段)
        + 作用: 判断该字符串是否以该字符串片段结尾
        + 返回值: 一个布尔值
          => true 说明以该字符串片段结尾
          => false 说明不以该字符串片段结尾

      15. trim()
        + 语法: 字符串.trim()
        + 作用: 去除字符串首尾空白
        + 返回值: 去除首尾空白后的字符串

      16. trimStart() / trimLeft()
        + 语法:
          => 字符串.trimStart()
          => 字符串.trimLeft()
        + 返回值: 去除开始位置空白以后的字符串

      17. trimEnd() / trimRight()
        + 语法:
          => 字符串.trimEnd()
          => 字符串.trimRight()
        + 返回值: 去除结束位置空白以后的字符串

      18. repalce()
        + 语法: 字符串.replace(换下字符, 换上字符)
        + 作用: 替换原始字符串内的片段
        + 注意: 只能替换一个
        + 返回值: 替换好的字符串

拓展 字符集

  
 计算机是不认识任何文字的 ,他只认识 0和1
 
 我们认识的每一个汉字,在计算机存储的时候,都有一个对应的边骂,计算机看到的是边骂,通过边骂展示出来的一个图片
 我们看到图片后认为这是一个汉字
 
    
 
 unicode
    ASCII  编码 内部就是对应的 大小写字母 + 数字 +标点符号
 
     
    
  国内有一个人发明了一个进制编码(国标码GBK)
 
    
 
      Unicode(万国码)  涵盖了世界大部分国家的文字   utf-8
    
         

## 定时器与倒计时器

  1.定时器
        setInterval(function(){
            // 定时器每次执行的时候,要执行的代码
            console.log('当前定时器,每1秒,执行一次')
        },2)

  2.倒计时器
        setTimeout(function(){
        console.log('执行')
        },300)

返回值:
            含义:表明当前页面有多个定时器或者倒计时器
            作用:停止当前定时器或者倒计时器
        关闭定时器的注意事项
        关闭的时候,有两个方法clearTimeout/clearTnterval; 可以混用
         var  fh = setTimeout(function(){
             console.log('倒计时器执行')
         },0)

         console.log(fh)
         关闭倒计时器
        clearTimeout(fh)

        var id = setInterval(function(){
            console.log('你好')
        },2000)
        clearInterval(fh)

        setInterval(function(){
            console.log('当前定时器,每1秒执行一次')
        },1)
        setTimeout(function(){
            console.log('五秒后执行')
        },5000)

定时器

  1. 开启定时器

  1. 延时定时器

语法  setTimeout(函数,数字);
	  -> 一段时间后要执行的代码
	  -> 多少时间  注意单位是毫秒
  1. 间歇定时器

语法  setInterval(函数,数字);
	  -> 每间隔多少时间执行的代码
	  -> 多少时间  注意单位是毫秒
  1. 两种定时器的返回值是什么

不区分什么定时器  
就是个数字  表示你在这个页面是第几个定时器 
作用 为了关闭 定时器 
  1. 关闭定时器

> 不区分定时器的种类 只要给到正确的定时器返回值 那么就知道关闭哪一个

clearTimeout(定时器的返回值);

clearInterval(定时器的返回值);

代码的异步与同步

 console.log('开始')
        setTimeout(function(){
            console.log('倒计时开始')
        },1000)
        console.log('结束')

JS中任务分为同步任务和异步任务

目前我们接触到定时器与倒计时器都属于异步任务,其他代码都是同步代码

JS中执行任务,会将所有的同步任务执行完毕,等所有同步任务执行完毕,再开始执行异步任务

拓展 进制转化

1.进制转换(了解)

=> 十进制转换成其他进制

十进制的数字.toString(其他进制)

=> 其他进制转换成十进制

parseInt(数字,将数字视为X进制的数字,然后转换成十进制)

2.保留小数(掌握)

=>要保留小数的数字.tofixed(要保留几位小数)

采用四舍五入的方式,并且返回的是一个字符串

1.进制转换

var num = 100

console.log(num.toString(2))

console.log(parseInt(100,2))

2.保留小数

var num = 123.45678

var num1 = 123.451

var num2 =123

console.log(num.toFixed(2))

console.log(num1.toFixed(2))

console.log(num2.toFixed(2))

拓展 严格模式

严格模式:严格模式: 其实就是因为JS初期的不严谨,后续特意推出了一个严谨的版本,我们叫做严格模式

在JS中默认是关闭的, 如果要打开 需要在JS 开始的位置 ,书写一个字符串'user strict'

在严格模式中,变量必须定义

函数的参数名不能重复

数学方法

Math.方法();
  1. random();

双色球 点名器 石头剪刀布
语法:Math.random();
作用:获取随机数字 
返回值: 0~1之间的小数 [0,1) 包含0但是不包含1
  1. round();

语法:Math.round();
作用:四射五入取整
返回值: 取整后的结果
  1. ceil(); 比它大的最小整数

语法:Math.ceil();
作用:向上取整
  1. floor(); 比它小的最大整数

语法:Math.floor();
作用:向下取整
  1. abs();

语法:Math.abs();
作用:绝对值
返回值:在数轴上点到原点的距离
  1. pow();

语法:Math.pow(底数,指数);Math.pow(谁,的多少次方);
作用:取幂运算
  1. sqrt();

语法:Math.sqrt(数字);
作用:求数字的算数平方根
  1. max();

语法:Math.max(数字1,数字2,...数字n);
作用:若干数字的最大值
  1. min();

语法:Math.min(数字1,数字2,...数字n);
作用:若干数字的最小值
  1. PI

语法: Math.PI; 不写()
作用: 一个近似π的值 

随机数

公式:Math.floor(Math.random()*个数+起始值)

日期对象

也是js的一个复杂数据类型 Date 存储时间相关的信息

创建时间对象

var 变量名 = new Date();   //先有它 
// 当前终端的时间 

创建指定日期的时间对象 
参数为数字
	传递一个数字 
		数字表示的是毫秒   1秒= 1000毫秒
		时间戳 1970年的1月1日 0时0分0秒 到此时此刻的秒数
        10位 秒
        13位数 毫秒
		不同的语言长度可能不一样 
		
	传递多个数字 
		第一个 年
		第二个 月 (0~11)
		第三个 日 
		第四个 时
		第四个 分
		第四个 秒
		第四个 毫秒
参数为字符串的时候:
		'YYYY-MM-DD HH:mm:ss'
		'YYYY/MM/DD HH:mm:ss'
		年月日 时分秒之间有空格 
		这样写  1 1月 12 12月
  1. 获取 get

1. getFullYear()
	语法: 时间对象.getFullYear();
	返回值: 该事件对象内容的年份信息  2023

2. getMonth();
	语法: 时间对象.getMonth();
	返回值: 该事件对象内容的月份信息  0 1月   11 12月

3. getDate();
	语法: 时间对象.getDate();
	返回值: 该事件对象内容的日期信息
4. getDay();
	语法: 时间对象.getDay();
	返回值: 该事件对象内容的星期信息  0 周天  6 周六
5.  getHours();
	语法: 时间对象.getHours();
	返回值: 该事件对象内容的小时信息  24小时值
6.  getMinutes();
	语法: 时间对象.getMinutes();
	返回值: 该事件对象内容的分钟信息  
7.  getSeconds();
	语法: 时间对象.getSeconds();
	返回值: 该事件对象内容的秒信息  
8.  getMilliseconds();
	语法: 时间对象.getMilliseconds();
	返回值: 该事件对象内容的毫秒信息  
9.  getTime();
	语法: 时间对象.getTime();  时间戳 
	返回值: 拿到的是毫秒数  
	
	时间戳 是1970年的1月1日0时0分秒到现在的秒数 
	getTime()拿到的是毫秒数 
  1. 设置 set

 设置相关

      1. setFullYear()
        + 语法: 时间对象.setFullYear(年份信息)
        + 作用: 修改该时间对象内的 年份信息

      2. setMonth()
        + 语法: 时间对象.setMonth(月份信息)
        + 作用: 修改该时间对象内的 月份信息
        + 注意: 0 表示 1 月, 11 表示 12 月

      3. setDate()
        + 语法: 时间对象.setDate(日期信息)
        + 作用: 修改该时间对象内的 日期信息

      4. setHours()
        + 语法: 时间对象.setHours(小时信息)
        + 作用: 修改该时间对象内的 小时信息

      5. setMinutes()
        + 语法: 时间对象.setMinutes(分钟信息)
        + 作用: 修改该时间对象内的 分钟信息

      6. setSeconds()
        + 语法: 时间对象.setSeconds(秒钟信息)
        + 作用: 修改该时间对象内的 秒钟信息

      7. setMilliseconds()
        + 语法: 时间对象.setMilliseconds(毫秒信息)
        + 作用: 修改该时间对象内的 毫秒信息

      8. setTime()
        + 语法: 时间对象.setTime(时间戳信息)
        + 作用: 使用时间戳信息直接定位时间对象

BOM

BOM: 浏览器对象模型,给我们提供了一些操作浏览器的功能

  • 获取浏览器的尺寸 可视窗口尺寸

  1. window.innerWidth

  1. window.innerHeight

结果是: 包含滚动条在内的尺寸

  • 浏览器的弹出层

  1. 提示框

window.alert(); => 没有返回值

  1. 询问框

window.confirm();

在提示框的基础上 + 取消按钮

返回值

如果用户点击确定 true

如果用户点击取消 false

提醒用户

  1. 输入框

window.prompt();

如果用户点击确定 那么返回值就是 输入的文本 结果一定字符串

如果用户点击取消 那么返回值就是null

共同点:

阻止程序的继续执行 直到用户操作位置

  • 浏览器的常见事件

  • 依赖浏览器的行为而触发的时间

  • 1.load

  • 语法: window.onload = function(){ 执行的代码}

  • 执行的时机: 当页面上所有的外部资源 html css 图片 js 视频 都执行完了

才执行它大括号里边的

  • 一般你把script标签写在head中 并且你想获取body中的标签

  • 这个时候就需要这个事件

  • 2.resize

  • 当页面的尺寸放生改变的是 触发js代码的执行

  • 语法: window.onresize(function(){})

  • 不管宽高

  • 3.scroll

  • 语法:window.onscroll(function(){})

  • 当页面的滚动条发生改变的时候 触发 js代码的执行

  • 不管横 竖

  • 浏览器地址栏

  • href 属性

  • 读写

  • window.location.href

  • 获取这个页面地址看中完成的url地址

  • window.location.href = '地址';

  • 跳转页面

  • reload属性

  • 重新加载页面所有的内容

  • 语法: window.location.reload();

  • 不要放在 打开页面就能执行的位置

浏览器卷去的高度 宽度

语法:	
	高度:
	1. document.documentElement.scrollTop
	如果页面上写了<!DOCTYPE html> 用第一种
	2. document.body.scrollTop
	如果页面上 没有写它 用下面那种 
	
	兼容 
		利用 逻辑运算符  || 解决问题 
		var scrolltop = document.documentElement.scrollTop || document.body.scrollTop;
	宽度:
	1. document.documentElement.scrollLeft
	如果页面上写了<!DOCTYPE html> 用第一种
	2. document.body.scrollLeft
	如果页面上 没有写它 用下面那种 
	
	兼容 
		利用 逻辑运算符  || 解决问题 
		var scrollleft = document.documentElement.scrollLeft || document.body.scrollLeft;
	

浏览器历史记录

history
  1. 回退 back

  1. window.history.back()

  1. 前进 forward

  1. window.history.forward()

  1. 跳转 go

  1. window.history.go(参数)

正整数 前进

0 刷新 还是到自己 = 刷新网页

负整数 后退

浏览器滚动条定位

专门用来对浏览器滚动条进行定位的
语法:
	第一种
	window.scrollTo(x,y);
	
	x 横向卷去的尺寸 
	y 纵向卷去的尺寸
	注意:必须传两个数字 一个数字 报错 
		 只能进行瞬间定位 
	第二种 
	window.scrollTo({left:yyy,top:xxx});
	注意: 可以只写一个键
		  可以只针对一个方向定位 
		  对象中还可以加一个behavior 键 值写 smooth 表示 平滑滚动 
		  
		 		top: 1980, // 纵向卷去的高度
                left: 200, // 横向

BOM本地存储

  • localStorage

  • 浏览器本地存储 持久存储 (只要没有强磁场 没有格式化数据一直在)

  • 特点:

  • 一旦存进去 永久在

  • 一个页面存的 另外的页面也能用 支持跨页面通讯

  • 只能存基本数据类型 不能存复杂数据类型

  • 复杂数据类型转成json即可

  • 操作

  • 增 set

  • window.localStorage.setItem(key,value);

  • 删 remove

  • window.localStorage.removeItem(key); // 删除一个键值对

  • window.localStorage.clear();

  • 改 重新设置

  • window.localStorage.setItem(已经存在的可以,value);

  • 查 get

  • window.localStorage.getItem(key);

  • 如果没有这个key 返回null

  • 有过有这个key 返回key对应的value

  • sessionStorage

  • session 会话

  • 浏览器临时存储 存取的内容会自动消失

### 特点

  1. 只能存字符串

  1. 必须是本页面的跳转才可以通讯 直接访问拿不到

比如 直接访问file:///C:/www/2203/day17/test2.html 拿不到

但是 从file:///C:/www/2203/day17/06%E6%B5%8F%E8%A7%88%E5%99%A8%E4%BC%9A%E8%AF%9D%E5%AD%98%E5%82%A8.html 跳转到的

file:///C:/www/2203/day17/test2.html 这个时候 就可以拿到了

  1. 同一个域名下 能拿到数据

window.sessionStorage.setItem(key,value);
window.sessionStorage.removeItem(key);
window.sessionStorage.clear();

#### 改

window.sessionStorage.setItem(已经存在的key,value);
window.sessionStorage.getItem(key);

总结:

同一域名

比如 http://www.baidu.com/1.htmlhttp://www.baidu.com/2.html

对于同一个域名下的不同网页,可以公用一个localStorage,不同域名下的

localStorage相互隔离,不通用

同一域名 不同网页

session 不能直接访问 ,必须是跳转过去的才可以

比如 直接访问test2获取不到 但是 运行test1 然后跳转到了test2 然后就能访问了

  • cookie

现在的ip 是ipv4 0~255.0~255.0~255.0~255
192.168 局域网ip
172.16 局域网ip
10.0 局域网ip
127.0.0.1 每个电脑有的一个ip
剩下的叫做公网ip
256 256256*256 除了一些保留的 特殊用的 36亿多一点
有个特点 早就耗光了
为了能上网 好多人公用一个ip
比如 100人公用一个ip去买票 杨关瑞第一次访问了 但是第二次再访问 服务器不知道他是杨关瑞
为了解决这个问题
杨关瑞第一次访问 于是领到一个饼干 (通行证),以后的每次访问都带着这个饼干 然后服务器就知道你是谁了
这个发饼干 验证饼干的问题 浏览器自动做的 不需要程序员
  • 登录用

  1. 输入域名 www.91.com 回车

  1. 将域名通过dns解析成ip地址 给到浏览器

  1. 浏览器受到请求

  1. 用户输入用户名

  1. 服务器判断是否有这个用户名 如果没有 提示拥护还没有注册

  1. 如果有这个用户名,用户继续输入密码

  1. 验证密码是否正确

  1. 如果密码不对继续输入

  1. 密码正确 登录成功

  1. 如果登录成功 会自动的往用户的浏览器输入 一个只属于你个人的身份信息

下一次 用户访问这个网页 , 会验证用户带过来的cookie 如果cookie 中有

身份信息 那么说明你已经登录了 如果没有 提示你登录

		 ### cookie 

1.只能存 字符串 有固定的格式

=> key =value;key1=value1;key2=value2

  1. 大小 限制 4k

  1. 有时效性

  1. 默认 是只要关了页面 就失效 支持手动调整时间

  1. 不单独存在 依赖于服务器的

  1. 本地打开的页面不能操作cookie

  1. file:///C:/www/2203/day17/%E9%A1%B5%E9%9D%A2%E9%80%9A%E8%AE%AF%E4%B8%93%E9%A2%98/num2.html 本地打开 不能操作cookie

  1. http://127.0.0.1:5500/day17/页面通讯专题/num2.html

这种事模拟服务打开,可以操作cookie

open with live server 插件 就是用来模拟服务器的方式打开页面

  1. 浏览器到服务器 自动携带 不用程序员操作携带

  1. 前端 必须是js 后端任何语言都支持cookie

  1. 依赖域名

  1. 那个域名存的 就哪个域名用

 		2. 不能夸域名访问  
设置cookie
  1. 不设置过期时间

document.cookie= 'key=value;key1=value1'; // 只能把key加进去
  1. 设置过期时间

document.cookie= 'key=value;expires=时间对象'
不管你设置的是北京时间还是俄罗斯时间 通通看做世界标准时间 
比如你穿北京时间16:43 作为过期时间  
但是会把它当做 世界标准时间来看 
0:43  最后实际上  北京时间 0:43 

我们在传值的时候 要注意 当前时间 往前调8 小时
比如30s后过期
 当前时间 往前调8 小时 然后往后调30s 就可以了 
 getTime() 拿到的是毫秒  所以需要乘以1000 
 事件对象.getTime()-1000*3600*8+1000*30
 
 
获取cookie
// document.write(document.cookie);
        /* age=18; person; person={"name":"kunkun","age":21}; name=龙龙; __utmz=96992031.1664163839.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=96992031.441332779.1664163839.1664177098.1667548558.4; _pk_id.100001.dc78=417d1a4773d972d4.1664163839.4.1667549106.1664178223. */
        // 是一个字符串 需要切割  
        // 需要切两次  

        // document.cookie = 'lian=yyds';
        // document.cookie = 'xiaoxiao=kangbazi';
        // console.log(document.cookie);
        // function getCookie(){
        //     var cookie = document.cookie;
        //     var obj  = {}
        //     var arr = cookie.split('; ');
        //     arr.forEach(function(item){
        //         // item 是 类似于 age=18
        //         // 需要二次切割 
        //         var arr2 = item.split('=');
        //         obj[arr2[0]] = arr2[1];
        //     })
        //     return obj;   
        // }

        // var res = getCookie();
		//{person:{"name":"kunkun","age":21}}
        // console.log(res['person']);

dom操作属性

操作属性 尽量不要动 类名和样式
下面的加入我已经获取到了元素

原生属性的操作

读	
	语法:元素.属性名
	得到:属性名对应的值
写
	语法:元素.属性名 = 属性值
	修改属性的值 

原生属性中还有几个特殊的 布尔属性 
	checked  
	selected 
	disabled
	读 拿到的是一个布尔值 
	写 设置布尔值就可以了 

自定义属性的操作

可以操作原生 一般不用它来操作原生属性
注意事项
不管你设置的是什么类型的数据 ,最终的得到的一定是字符串
尽量不要用这种方法操作 原生属性和h5自带属性
增
	元素.setAttribute(属性名,属性值);
删 
	元素.removeAttribute(属性名);
查
	元素.getAttribute(属性名);

h5自定义属性

data-user-name = '张三'
data-  开头的一定是自定义属性
data-后面的才是 属性名
= 后边的就是 属性值 

每个标签出生自带一个属性 叫dataset  类似于对象的数据结构  
这个dataset 包含所有的data-开头的属性 
dataset 就是个大箱子 里边存放所有的data-属性 

元素.dataset.userName 

DOM操作类名

  1. className

语法:元素.className

得到:得到完整的类名字符串

语法:元素.className = '值'

覆盖原来的类名的值

追加:

元素.className += ' 值' // 追加的时候 值的前面要加空格

  1. classList

  1. 每个标签出生自带一个属性 classList 包含所有的类名

追加:

语法:元素.classList.add(类名);

删除:

语法:元素.classList.remove(类名);

切换:

语法:元素.classList.toggle(类名);

原先如果有这个类名 就删除

原先没有就增加

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值