js_02

数组的概念

数组可以把一组相关的数据一起存放,并提供方便的访问(获取)方式。
-数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。数组是一种将一组数据存储在单个变量名下的优雅方式。

数组的定义

数组是一个有序的列表,可以在数组中存放任意的数据,并且数组的长度可以动态的调整。

创建数组的两种方式

  <script>
       
        //  利用new 创建数组
        var arr = new Array(); // 创建了一个空的数组
        // 利用数组字面量创建数组 []
        var arr = []; // 创建了一个空的数组
        var arr1 = [1, 2, 'pyk', true];
        //  我们数组里面的数据一定用逗号分隔
        //  数组里面的数据 比如1,2, 我们称为数组元素
        //  获取数组元素  格式 数组名[索引号]  索引号从 0开始 
        console.log(arr1);//输出全部数组内容
        console.log(arr1[2]); // pyk
        console.log(arr1[3]); // true
        var arr2 = ['迪丽热巴', '古丽扎娜', '佟丽丫丫'];
        console.log(arr2[0]);
        console.log(arr2[1]);
        console.log(arr2[2]);
        console.log(arr2[3]); // 因为没有这个数组元素 所以输出的结果是 undefined
    </script>

获取数组元素

数组的取值

    // 格式:数组名[下标]	下标又称索引
    // 功能:获取数组对应下标的那个值,如果下标不存在,则返回undefined。
    var arr = ['red',, 'green', 'blue'];
    arr[0];	// red
    arr[2]; // blue
    arr[3]; // 这个数组的最大下标为2,因此返回undefined

遍历数组

遍历:遍及所有,对数组的每一个元素都访问一次就叫遍历。

数组遍历的基本语法:

    <script>
        // 遍历数组:就是把数组的元素从头到尾访问一次
        var arr = ['red', 'green', 'blue'];
        for (var i = 0; i < 3; i++) {
            console.log(arr[i]);
        }
        // 1. 因为我们的数组索引号从0开始 ,所以 i 必须从 0开始  i < 3
        // 2. 输出的时候 arr[i]  i 计数器当索引号来用
    </script>
<script>
    // 1. 求数组 [2,6,1,7, 4] 里面所有元素的和以及平均值。
    // (1)声明一个求和变量 sum。
    // (2)遍历这个数组,把里面每个数组元素加到 sum 里面。
    // (3)用求和变量 sum 除以数组的长度就可以得到数组的平均值。
    var arr = [2, 6, 1, 7, 4];
    var sum = 0;
    var average = 0;
    for (var i = 0; i < arr.length; i++) {
        sum += arr[i]; // 我们加的是数组元素 arr[i] 不是计数器 i
    }
    average = sum / arr.length;
    console.log(sum, average); // 想要输出多个变量,用逗号分隔即可
</script>
 <script>
    // 求数组[2,6,1,77,52,25,7]中的最大值
    // 声明一个保存最大元素的变量 max。
    // 默认最大值可以取数组中的第一个元素。
    // 遍历这个数组,把里面每个数组元素和 max 相比较。
    // 如果这个数组元素大于max 就把这个数组元素存到 max 里面,否则继续下一轮比较。
    // 最后输出这个 max
    var arr = [2, 6, 1, 77, 52, 25, 7, 99];
    var max = arr[0];
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    console.log('该数组里面的最大值是:' + max);
</script>
<script>
    // 将数组 ['red', 'green', 'blue', 'pink'] 转换为字符串,并且用 | 或其他符号分割
    // 1.需要一个新变量用于存放转换完的字符串 str。
    // 2.遍历原来的数组,分别把里面数据取出来,加到字符串里面。
    // 3.同时在后面多加一个分隔符
    var arr = ['red', 'green', 'blue', 'pink'];
    var str = '';
    var sep = '*';
    for (var i = 0; i < arr.length; i++) {
        str += arr[i] + sep;
    }
    console.log(str);
</script>



   

```javascript
数组中新增元素
<script>
        // 1. 新增数组元素 修改length长度 
        var arr = ['red', 'green', 'blue'];
        console.log(arr.length);
        arr.length = 5; // 把我们数组的长度修改为了 5  里面应该有5个元素 
        console.log(arr);
        console.log(arr[3]); // undefined
        console.log(arr[4]); // undefined

        // 2. 新增数组元素 修改索引号 追加数组元素
        var arr1 = ['red', 'green', 'blue'];
        arr1[3] = 'pink';
        console.log(arr1);
        arr1[4] = 'hotpink';
        console.log(arr1);
        arr1[0] = 'yellow'; // 这里是替换原来的数组元素
        console.log(arr1);
        arr1 = '有点意思';
        console.log(arr1); // 不要直接给 数组名赋值 否则里面的数组元素都没有了
    </script>
    <script>
        // 将数组 [2, 0, 6, 1, 77, 0, 52, 0, 25, 7] 中大于等于 10 的元素选出来,放入新数组。
        // 1、声明一个新的数组用于存放新数据newArr。
        // 2、遍历原来的旧数组, 找出大于等于 10 的元素。
        // 3、依次追加给新数组 newArr。
        // 方法1
        var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
        var newArr = [];
        var j = 0;
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] >= 10) {
                // 新数组索引号应该从0开始 依次递增
                newArr[j] = arr[i];
                j++;
            }
        }
        console.log(newArr);
        // 方法2 
        var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
        var newArr = [];
        // 刚开始 newArr.length 就是 0
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] >= 10) {
                // 新数组索引号应该从0开始 依次递增
                newArr[newArr.length] = arr[i];
            }
        }
        console.log(newArr);
    </script>
    <script>
        // 将数组[2, 0, 6, 1, 77, 0, 52, 0, 25, 7]中的 0 去掉后,形成一个不包含 0 的新数组。
        // 1、需要一个新数组用于存放筛选之后的数据。
        // 2、遍历原来的数组, 把不是 0 的数据添加到新数组里面(此时要注意采用数组名 + 索引的格式接收数据)。
        // 3、新数组里面的个数, 用 length 不断累加。
        var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
        var newArr = [];
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] != 0) {
                newArr[newArr.length] = arr[i];
            }
        }
        console.log(newArr);
    </script>
     <script>
        // 将数组 ['red', 'green', 'blue', 'pink', 'purple'] 的内容反过来存放
        // 1、声明一个新数组 newArr
        // 2、把旧数组索引号第4个取过来(arr.length - 1),给新数组索引号第0个元素 (newArr.length)
        // 3、我们采取 递减的方式  i--
        var arr = ['red', 'green', 'blue', 'pink', 'purple', 'hotpink'];
        var newArr = [];
        for (var i = arr.length - 1; i >= 0; i--) {
            newArr[newArr.length] = arr[i]
        }
        console.log(newArr);
    </script>
      <script>
        // 将数组 ['red', 'green', 'blue', 'pink', 'purple'] 的内容反过来存放
        // 1、声明一个新数组 newArr
        // 2、把旧数组索引号第4个取过来(arr.length - 1),给新数组索引号第0个元素 (newArr.length)
        // 3、我们采取 递减的方式  i--
        var arr = ['red', 'green', 'blue', 'pink', 'purple', 'hotpink'];
        var newArr = [];
        for (var i = arr.length - 1; i >= 0; i--) {
            newArr[newArr.length] = arr[i]
        }
        console.log(newArr);
    </script>
    <script>
        // 冒泡排序
        // var arr = [5, 4, 3, 2, 1];
        var arr = [4, 1, 2, 3, 5];
        for (var i = 0; i <= arr.length - 1; i++) { // 外层循环管趟数 
            for (var j = 0; j <= arr.length - i - 1; j++) { // 里面的循环管 每一趟的交换次数
                // 内部交换2个变量的值 前一个和后面一个数组元素相比较
                if (arr[j] < arr[j + 1]) {
                    var temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }

            }
        }
        console.log(arr);
    </script>
    
    -  注意:
  - 此处数组的长度是数组元素的个数 ,不要和数组的索引号混淆。
- 当我们数组里面的元素个数发生了变化,这个 length 属性跟着一起变化
  - 数组的length属性可以被修改:
- 如果设置的length属性值大于数组的元素个数,则会在数组末尾出现空白元素;
  - 如果设置的length属性值小于数组的元素个数,则会把超过该值的数组元素删除

函数

什么是函数
把一段相对独立的具有特定功能的代码块封装起来,形成一个独立实体,就是函数,起个名字(函数名),在后续开发中可以反复调用
函数的作用就是封装一段代码,将来可以重复使用**

函数的定义

- 函数声明

    function 函数名(){
      // 函数体
    }

- 函数表达式

    var fn = function() {
      // 函数体
    }

- 特点:
  函数声明的时候,函数体并不会执行,只要当函数被调用的时候才会执行。
 

函数的调用

    函数名();

- 特点:
  函数体只有在调用的时候才会执行,调用需要()进行调用。
  可以调用多次(重复使用)
代码示例:

    // 声明函数
    function sayHi() {
      console.log("吃了没?");
    }
    // 调用函数
    sayHi();
    
    // 求1-100之间所有数的和
    function getSum() {
      var sum = 0;
      for (var  i = 0; i < 100; i++) {
        sum += i;
      }
      console.log(sum);
    }
    // 调用
    getSum();

函数的参数

- 为什么要有参数

    function getSum() {
      var sum = 0;
      for (var i = 1; i <= 100; i++) {
        sum += i;
      }
      console.log();
    }
    
    // 虽然上面代码可以重复调用,但是只能计算1-100之间的值
    // 如果想要计算n-m之间所有数的和,应该怎么办呢?

- 语法:

    // 函数内部是一个封闭的环境,可以通过参数的方式,把外部的值传递给函数内部
    // 带参数的函数声明
    function 函数名(形参1, 形参2, 形参...){
      // 函数体
    }
    
    // 带参数的函数调用
    函数名(实参1, 实参2, 实参3);

- 形参和实参

- 形参:函数定义时设置接收调用时传入
- 实参:函数调用时传入小括号内的真实数据

    var x = 5, y = 6;
    fn(x,y); 
    function fn(a, b) {
      console.log(a + b);
    }
    //x,y实参,有具体的值。函数执行的时候会把x,y复制一份给函数内部的a和b,函数内部的值是复制的新值,无法修改外部的x,y
 1. 调用的时候实参值是传递给形参的
2. 形参简单理解为:不用声明的变量
3. 实参和形参的多个参数之间用逗号(,)分隔

在这里插入图片描述
函数形参和实参数量不匹配时
在这里插入图片描述

函数的返回值

当函数执行完的时候,并不是所有时候都要把结果打印。我们期望函数给我一些反馈(比如计算的结果返回进行后续的运算),这个时候可以让函数返回一些东西。也就是返回值。函数通过return返回一个返回值

返回值语法:

    //声明一个带返回值的函数
    function 函数名(形参1, 形参2, 形参...){
      //函数体
      return 返回值;
    }
    
    //可以通过变量来接收这个返回值
    var 变量 = 函数名(实参1, 实参2, 实参3);

函数的调用结果就是返回值,因此我们可以直接对函数调用结果进行操作。

返回值详解:

    如果函数没有显示的使用 return语句 ,那么函数有默认的返回值:undefined

    如果函数使用 return语句,那么跟再return后面的值,就成了函数的返回值

    如果函数使用 return语句,但是return后面没有任何值,那么函数的返回值也是:undefined

    函数使用return语句后,这个函数会在执行完 return 语句之后停止并立即退出,也就是说return后面的所有其他代码都不会再执行。

    

    推荐的做法是要么让函数始终都返回一个值,要么永远都不要返回值。
    break ,continue ,return 的区别

- break :结束当前的循环体(如 forwhile- continue :跳出本次循环,继续执行下次循环(如 forwhile- return :不仅可以退出循环,还能够返回 return 语句中的值,同时还可以结束当前的函数体内的代码

arguments的使用

当不确定有多少个参数传递的时候,可以用 arguments 来获取。JavaScript 中,arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个 arguments 对象,arguments 对象中存储了传递的所有实参。arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:
具有 length 属性
按索引方式储存数据
不具有数组的 push , pop 等方法
注意:在函数内部使用该对象,用此对象获取函数调用时传的实参。

 <script>
        // arguments 的使用  只有函数才有 arguments对象  而且是每个函数都内置好了这个arguments
        function fn() {
            // console.log(arguments); // 里面存储了所有传递过来的实参  arguments = [1,2,3]
            // console.log(arguments.length);
            // console.log(arguments[2]);
            // 我们可以按照数组的方式遍历arguments
            for (var i = 0; i < arguments.length; i++) {
                console.log(arguments[i]);

            }
        }
        fn(1, 2, 3);
        fn(1, 2, 3, 4, 5);
        // 伪数组 并不是真正意义上的数组
        // 1. 具有数组的 length 属性
        // 2. 按照索引的方式进行存储的
        // 3. 它没有真正数组的一些方法 pop()  push() 等等
    </script>
    <script>
        // 利用函数求任意个数的最大值
        function getMax() { // arguments = [1,2,3]
            var max = arguments[0];
            for (var i = 1; i < arguments.length; i++) {
                if (arguments[i] > max) {
                    max = arguments[i];
                }
            }
            return max;
        }
        console.log(getMax(1, 2, 3));
        console.log(getMax(1, 2, 3, 4, 5));
        console.log(getMax(11, 2, 34, 444, 5, 100));
    </script>
     <script>
        // 利用函数翻转任意数组 reverse 翻转
        function reverse(arr) {
            var newArr = [];
            for (var i = arr.length - 1; i >= 0; i--) {
                newArr[newArr.length] = arr[i];
            }
            return newArr;
        }
        var arr1 = reverse([1, 3, 4, 6, 9]);
        console.log(arr1);
        var arr2 = reverse(['red', 'pink', 'blue']);
        console.log(arr2);
    </script>
     <script>
        // 利用函数冒泡排序 sort 排序
        function sort(arr) {
            for (var i = 0; i < arr.length - 1; i++) {
                for (var j = 0; j < arr.length - i - 1; j++) {
                    if (arr[j] > arr[j + 1]) {
                        var temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
            return arr;
        }
        var arr1 = sort([1, 4, 2, 9]);
        console.log(arr1);
        var arr2 = sort([11, 7, 22, 999]);
        console.log(arr2);
    </script>
    <script>
        // 利用函数判断闰年
        function isRunYear(year) {
            // 如果是闰年我们返回 true  否则 返回 false 
            var flag = false;
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                flag = true;
            }
            return flag;
        }
        console.log(isRunYear(2000));
        console.log(isRunYear(1999));
    </script>

匿名函数

匿名函数:没有名字的函数
匿名函数如何使用:
将匿名函数赋值给一个变量,这样就可以通过变量进行调用
匿名函数自调用

自调用函数
匿名函数不能通过直接调用来执行,因此可以通过匿名函数的自调用的方式来执行

 (function () {
      alert(123);
    })();

函数是一种数据类型

function fn() {}
console.log(typeof fn);

- 函数作为参数

因为函数也是一种类型,可以把函数作为两一个函数的参数,在两一个函数中调用

<script>
        // 用户输入年份,输出当前年份2月份的天数
        function backDay() {
            var year = prompt('请您输入年份:');
            if (isRunYear(year)) { // 调用函数需要加小括号
                alert('当前年份是闰年2月份有29天');
            } else {
                alert('当前年份是平年2月份有28天');
            }
        }
        backDay();


        // 判断是否为闰年的函数
        function isRunYear(year) {
            // 如果是闰年我们返回 true  否则 返回 false 
            var flag = false;
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                flag = true;
            }
            return flag;
        }
    </script>

- 函数做为返回值

因为函数是一种类型,所以可以把函数可以作为返回值从函数内部返回,这种用法在后面很常见。

    function fn(b) {
      var a = 10;
      return function () {
        alert(a+b);
      }
    }
    fn(15)();

代码规范

    1.命名规范	
    2.变量规范   
    	var name = 'zs';	
    3.注释规范
    	// 这里是注释
    4.空格规范
    5.换行规范
    	var arr = [1, 2, 3, 4];
    	if (a > b) {
          
    	}
    	for(var i = 0; i < 10; i++) {
          
    	}
    	function fn() {
          
    	}
    

作用域

通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
JavaScript(es6前)中的作用域有两种:
全局作用域
局部作用域(函数作用域)

1.2 全局作用域
作用于所有代码执行的环境(整个 script 标签内部)或者一个独立的 js 文件。
1.3 局部作用域
作用于函数内的代码环境,就是局部作用域。 因为跟函数有关系,所以也称为函数作用域。

1.4 JS没有块级作用域
-块作用域由 { } 包括。
在其他编程语言中(如 java、c#等),在 if 语句、循环语句中创建的变量,仅仅只能在本 if 语句、本循环语句中使用,如下面的Java代码:

 <script>
        // 1.JavaScript作用域 : 就是代码名字(变量)在某个范围内起作用和效果 目的是为了提高程序的可靠性更重要的是减少命名冲突
        // 2. js的作用域(es6)之前 : 全局作用域   局部作用域 
        // 3. 全局作用域: 整个script标签 或者是一个单独的js文件
        var num = 10;
        var num = 30;
        console.log(num);//30

        // 4. 局部作用域(函数作用域) 在函数内部就是局部作用域 这个代码的名字只在函数内部起效果和作用
        function fn() {
            // 局部作用域
           var num=20
            console.log(num);//20

        }
        fn();
        console.log(num);//30
    </script>

2 - 变量的作用域

在JavaScript中,根据作用域的不同,变量可以分为两种:
全局变量
局部变量

- 全局变量

在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。
全局变量在代码的任何位置都可以使用
在全局作用域下 var 声明的变量 是全局变量
特殊情况下,在函数内不使用 var 声明的变量也是全局变量(不建议使用)

- 局部变量

在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)

局部变量只能在该函数内部使用
在函数内部 var 声明的变量是局部变量
函数的形参实际上就是局部变量

2.3 全局变量和局部变量的区别
全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间

 <script>
        // 变量的作用域: 根据作用域的不同我们变量分为全局变量和局部变量
        // 1. 全局变量: 在全局作用域下的变量 在全局下都可以使用
        // 注意 如果在函数内部 没有声明直接赋值的变量也属于全局变量
        var num = 10; // num就是一个全局变量
        console.log(num);

        function fn() {
            console.log(num);

        }
        fn();
        // console.log(aru);

        // 2. 局部变量   在局部作用域下的变量   后者在函数内部的变量就是 局部变量
        // 注意: 函数的形参也可以看做是局部变量
        function fun(aru) {
            var num1 = 10; // num1就是局部变量 只能在函数内部使用
            num2 = 20;
        }
        fun();
        // console.log(num1);
        // console.log(num2);
        // 3. 从执行效率来看全局变量和局部变量
        // (1) 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
        // (2) 局部变量 当我们程序执行完毕就会销毁, 比较节约内存资源
    </script>

变量的作用域

<script>
        // 变量的作用域: 根据作用域的不同我们变量分为全局变量和局部变量
        // 1. 全局变量: 在全局作用域下的变量 在全局下都可以使用
        // 注意 如果在函数内部 没有声明直接赋值的变量也属于全局变量
        var num = 10; // num就是一个全局变量
        console.log(num);

        function fn() {
            console.log(num);//10

        }
        fn();
        // console.log(aru);

        // 2. 局部变量   在局部作用域下的变量   后者在函数内部的变量就是 局部变量
        // 注意: 函数的形参也可以看做是局部变量
        function fun(aru) {
            var num2 = 10; // num1就是局部变量 只能在函数内部使用
            num2 = 20;  //全局变量
            console.log(num2)//20
        }
        fun();
        // console.log(num1);
        // console.log(num2);
        // 3. 从执行效率来看全局变量和局部变量
        // (1) 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
        // (2) 局部变量 当我们程序执行完毕就会销毁, 比较节约内存资源
    </script>

块级作用域

任何一对花括号({和})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。

在es5之前没有块级作用域的的概念,只有函数作用域,现阶段可以认为JavaScript没有块级作用域

 <script>
        // js中没有块级作用域  js的作用域: 全局作用域  局部作用域  现阶段我们js 没有 块级作用域
        // 我们js 也是在 es6 的时候新增的块级作用域
        // 块级作用域 {}   if {}  for {}
        if (3 < 5) {
            var num = 10;
        }
        console.log(num);//10
    </script>

作用域链

只要是代码都一个作用域中,写在函数内部的局部作用域,未写在任何函数内部即在全局作用域中;如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域;根据在[内部函数可以访问外部函数变量]的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链

 <script>
        // 作用域链  : 内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 这种结构我们称为作用域链   就近原则
        var num = 10;

        function fn() { // 外部函数
            var num = 20;

            function fun() { // 内部函数
                console.log(num);

            }
            fun();
        }
        fn();
    </script>

案例:

<script>
        // 案例1 : 结果是几?
        function f1() {
            var num = 123;

            function f2() {
                var num = 0;
                console.log(num); // 站在目标出发,一层一层的往外查找
            }
            f2();
        }
        var num = 456;
        f1();
        // 案例2 :结果是几?
        var a = 1;

        function fn1() {
            var a = 2;
            var b = '22';
            fn2();

            function fn2() {
                var a = 3;
                fn3();

                function fn3() {
                    var a = 4;
                    console.log(a); //a的值 ?
                    console.log(b); //b的值 ?
                }
            }
        }
        fn1();
    </script>

预解析

JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析和代码执行。
- 预解析:在当前作用域下, JS 代码执行之前,浏览器会默认把带有 var 和 function 声明的变量在内存中进行提前声明或者定义。
代码执行: 从上到下执行JS语句。
预解析会把变量和函数的声明在代码执行之前执行完成。

预解析过程:

1. 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
2. 把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
3. 先提升var,在提升function

JavaScript的执行过程

       预解析也叫做变量、函数提升。
    变量提升(变量预解析): 变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升。

    console.log(num);  // 结果是多少?
    var num = 10;      // ?

    结果:undefined
    
    注意:**变量提升只提升声明,不提升赋值**


4.3 函数预解析

    函数提升: 函数的声明会被提升到当前作用域的最上面,但是不会调用函数。

    fn();
    function fn() {
        console.log('打印');
    }

    结果:控制台打印字符串 --- ”打印“ 
    
    注意:函数声明代表函数整体,所以函数提升后,函数名代表整个函数,但是函数并没有被调用!	

4.4 函数表达式声明函数问题

    函数表达式创建函数,会执行变量提升,此时接收函数的变量名无法正确的调用:

    fn();
    var  fn = function() {
        console.log('想不到吧');
    }

    结果:报错提示 ”fn is not a function"
    
    解释:该段代码执行之前,会做变量声明提升,fn在提升之后的值是undefined;而fn调用是在fn被赋值为函数体之前,此时fn的值是undefined,所以无法正确调用



全局解析规则

变量提升
-变量提升
定义变量的时候,变量的声明会被提升到作用域的最上面,变量的赋值不会提升。
-函数提升
JavaScript解析器首先会把当前作用域的函数声明提前到整个作用域的最前面

对象

对象字面量

使用对象字面量创建对象:

    	就是花括号 { } 里面包含了表达这个具体事物(对象)的属性和方法;{ } 里面采取键值对的形式表示 

- 键:相当于属性名
- 值:相当于属性值,可以是任意类型的值(数字类型、字符串类型、布尔类型,函数类型等)

字面量:11 'abc'  true  [] {}var o = {
      name: 'zs,
      age: 18,
      sex: true,
      sayHi: function () {
        console.log(this.name);
      }
    };
    - 访问对象的属性
  - 对象里面的属性调用 : 对象.属性名 ,这个小点 . 就理解为“ 的 ”  
  - 对象里面属性的另一种调用方式 : 对象[‘属性名’],注意方括号里面的属性必须加引号      
    示例代码如下:
        console.log(star.name)     // 调用名字属性
        console.log(star['name'])  // 调用名字属性
- 调用对象的方法
  - 对象里面的方法调用:对象.方法名() ,注意这个方法名字后面一定加括号 
    示例代码如下:
        star.sayHi();              // 调用 sayHi 方法,注意,一定不要忘记带后面的括号
- 变量、属性、函数、方法总结
  属性是对象的一部分,而变量不是对象的一部分,变量是单独存储数据的容器
- 变量:单独声明赋值,单独存在
- 属性:对象里面的变量称为属性,不需要声明,用来描述该对象的特征

- new Object()创建对象
- 创建空对象
      var andy = new Obect();
  通过内置构造函数Object创建对象,此时andy变量已经保存了创建出来的空对象
- 给空对象添加属性和方法
  - 通过对象操作属性和方法的方式,来为对象增加属性和方法
注意:

- Object() :第一个字母大写   
- new Object() :需要 new 关键字
- 使用的格式:对象.属性 =;     

var person = new Object();
  person.name = 'lisi';
  person.age = 35;
  person.job = 'actor';
  person.sayHi = function(){
  console.log('Hello,everyBody');
}
- 工厂函数创建对象
function createPerson(name, age, job) {
  var person = new Object();
  person.name = name;
  person.age = age;
  person.job = job;
  person.sayHi = function(){
    console.log('Hello,everyBody');
  }
  return person;
}
var p1 = createPerson('张三', 22, 'actor');
- 自定义构造函数
构造函数

- 构造函数:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

   function Person(name,age,job){
      this.name = name;
      this.age = age;
      this.job = job;
      this.sayHi = function(){
      	console.log('Hello,everyBody');
      }
    }
    var p1 = new Person('张三', 22, 'actor');

new关键字

构造函数 ,是一种特殊的函数。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
1.构造函数用于创建一类对象,首字母要大写。
2. 构造函数要和new一起使用才有意义。
new在执行时会做四件事情
new会在内存中创建一个新的空对象
new 会让this指向这个新的对象
执行构造函数 目的:给这个新对象加属性和方法
new会返回这个新对象

this详解

JavaScript中的this指向问题,有时候会让人难以捉摸,随着学习的深入,我们可以逐渐了解
现在我们需要掌握函数内部的this几个特点
1. 函数在定义的时候this是不确定的,只有在调用的时候才可以确定
2. 一般函数直接执行,内部this指向全局window
3. 函数作为一个对象的方法,被该对象所调用,那么this指向的是该对象
4. 构造函数中的this其实是一个隐式对象,类似一个初始化的模型,所有方法和属性都挂载到了这个隐式对象身上,后续通过new关键字来调用,从而实现实例化

对象的使用

遍历对象的属性
    for...in 语句用于对数组或者对象的属性进行循环操作。
    
    其语法如下:
    

    for (变量 in 对象名字) {
        // 在此执行代码
    }

    语法中的变量是自定义的,它需要符合命名规范,通常我们会将这个变量写为 k 或者 key。
    

    for (var k in obj) {
        console.log(k);      // 这里的 k 是属性名
        console.log(obj[k]); // 这里的 obj[k] 是属性值
    }

删除对象的属性
function fun() { 
  this.name = 'mm';
}
var obj = new fun(); 
console.log(obj.name); // mm 
delete obj.name;
console.log(obj.name); // undefined

简单类型和复杂类型的区别

简单类型和复杂类型的区别

基本类型又叫做值类型,复杂类型又叫做引用类型

值类型:简单数据类型,基本数据类型,在存储时,变量中存储的是值本身,因此叫做值类型。

引用类型:复杂数据类型,在存储是,变量中存储的仅仅是地址(引用),因此叫做引用数据类型。

  • 堆和栈
    堆栈空间分配区别:
      1、栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;
      2、堆(操作系统): 存储复杂类型(对象),一般由程序员分配释放, 若程序员不释放,由垃圾回收机制回收,分配方式倒是类似于链表。

内置对象

1.1 内置对象
JavaScript 中的对象分为3种:自定义对象 、内置对象、 浏览器对象
前面两种对象是JS 基础 内容,属于 ECMAScript; 第三个浏览器对象属于 JS 独有的, JS API 讲解内置对象就是指 JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法),内置对象最大的优点就是帮助我们快速开发
JavaScript 提供了多个内置对象:Math、 Date 、Array、String等

MDN
Mozilla 开发者网络(MDN)提供有关开放网络技术(Open Web)的信息,包括 HTML、CSS 和万维网及 HTML5 应用的 API。

Math对象

Math对象不是构造函数,它具有数学常数和函数的属性和方法,都是以静态成员的方式提供
跟数学相关的运算来找Math中的成员(求绝对值,取整)

	 // Math数学对象 不是一个构造函数 ,所以我们不需要new 来调用 而是直接使用里面的属性和方法即可
        console.log(Math.PI); // 一个属性 圆周率
        console.log(Math.max(1, 99, 3)); // 99
        console.log(Math.max(-1, -10)); // -1
        console.log(Math.max(1, 99, 'pink老师')); // NaN
        console.log(Math.max()); // -Infinity

          // 1.绝对值方法
        console.log(Math.abs(1)); // 1
        console.log(Math.abs(-1)); // 1
        console.log(Math.abs('-1')); // 隐式转换 会把字符串型 -1 转换为数字型
        console.log(Math.abs('pink')); // NaN 

        // 2.三个取整方法
        // (1) Math.floor()   地板 向下取整  往最小了取值
        console.log(Math.floor(1.1)); // 1
        console.log(Math.floor(1.9)); // 1
        // (2) Math.ceil()   ceil 天花板 向上取整  往最大了取值
        console.log(Math.ceil(1.1)); // 2
        console.log(Math.ceil(1.9)); // 2
        // (3) Math.round()   四舍五入  其他数字都是四舍五入,但是 .5 特殊 它往大了取  
        console.log(Math.round(1.1)); // 1
        console.log(Math.round(1.5)); // 2
        console.log(Math.round(1.9)); // 2
        console.log(Math.round(-1.1)); // -1
        console.log(Math.round(-1.5)); // 这个结果是 -1
 <script>
        // 利用对象封装自己的数学对象  里面有 PI 最大值和最小值
        var myMath = {
            PI: 3.141592653,
            max: function() {
                var max = arguments[0];
                for (var i = 1; i < arguments.length; i++) {
                    if (arguments[i] > max) {
                        max = arguments[i];
                    }
                }
                return max;
            },
            min: function() {
                var min = arguments[0];
                for (var i = 1; i < arguments.length; i++) {
                    if (arguments[i] < min) {
                        min = arguments[i];
                    }
                }
                return min;
            }
        }
        console.log(myMath.PI);
        console.log(myMath.max(1, 5, 9));
        console.log(myMath.min(1, 5, 9));
    </script>
      <script>
        // 1.Math对象随机数方法   random() 返回一个随机的小数  0 =< x < 1
        // 2. 这个方法里面不跟参数
        // 3. 代码验证 
        console.log(Math.random());
        // 4. 我们想要得到两个数之间的随机整数 并且 包含这2个整数
        // Math.floor(Math.random() * (max - min + 1)) + min;
        function getRandom(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }
        console.log(getRandom(1, 10));
        // 5. 随机点名  
        var arr = ['张三', '张三丰', '张三疯子', '李四', '李思思', 'pink老师'];
        // console.log(arr[0]);
        console.log(arr[getRandom(0, arr.length - 1)]);
    </script>
    
<script>
        // 猜数字游戏
        // 1.随机生成一个1~10 的整数  我们需要用到 Math.random() 方法。
        // 2.需要一直猜到正确为止,所以需要一直循环。
        // 3.while 循环更简单
        // 4.核心算法:使用 if  else if 多分支语句来判断大于、小于、等于。
        function getRandom(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }
        var random = getRandom(1, 10);
        while (true) { // 死循环
            var num = prompt('你来猜? 输入1~10之间的一个数字');
            if (num > random) {
                alert('你猜大了');
            } else if (num < random) {
                alert('你猜小了');
            } else {
                alert('你好帅哦,猜对了');
                break; // 退出整个循环结束程序
            }

        }
        // 要求用户猜 1~50之间的一个数字 但是只有 10次猜的机会
    </script>
    

Date对象

创建 Date 实例用来处理日期和时间。Date 对象基于197011日(世界标准时间)起的毫秒数。
Date 对象和 Math 对象不一样,Date是一个构造函数,所以使用时需要实例化后才能使用其中具体方法和属性。Date 实例用来处理日期和时间

- 使用Date实例化日期对象
  - 获取当前时间必须实例化:
      var now = new Date();
  - 获取指定时间的日期对象
      var future = new Date('2019/5/1');
  注意:如果创建实例时并未传入参数,则得到的日期对象是当前时间对应的日期对象


    // 获取当前时间,UTC世界时间,距1970年1月1日(世界标准时间)起的毫秒数
    var now = new Date();
    console.log(now.valueOf());	// 获取距1970年1月1日(世界标准时间)起的毫秒数
    
    Date构造函数的参数
    1. 毫秒数 1498099000356		new Date(1498099000356)
    2. 日期格式字符串  '2015-5-1'	 new Date('2015-5-1')
    3. 年、月、日……				  new Date(2015, 4, 1)   // 月份从0开始

- 获取日期的毫秒形式

  var now = new Date();
    // valueOf用于获取对象的原始值
    console.log(date.valueOf())	
    
    // HTML5中提供的方法,有兼容性问题
    var now = Date.now();	
    
    // 不支持HTML5的浏览器,可以用下面这种方式
    var now = + new Date();			// 调用 Date对象的valueOf() 

- 日期格式化方法

<script>
        // 格式化日期 年月日 
        var date = new Date();
        console.log(date.getFullYear()); // 返回当前日期的年  2019
        console.log(date.getMonth() + 1); // 月份 返回的月份小1个月   记得月份+1 呦
        console.log(date.getDate()); // 返回的是 几号
        console.log(date.getDay()); // 3  周一返回的是 1 周六返回的是 6 但是 周日返回的是 0
        // 我们写一个 2019年 5月 1日 星期三
        var year = date.getFullYear();
        var month = date.getMonth() + 1;
        var dates = date.getDate();
        var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
        var day = date.getDay();
        console.log('今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day]);
    </script>
     <script>
        // 格式化日期 时分秒
        var date = new Date();
        console.log(date.getHours()); // 时
        console.log(date.getMinutes()); // 分
        console.log(date.getSeconds()); // 秒
        // 要求封装一个函数返回当前的时分秒 格式 08:08:08
        function getTimer() {
            var time = new Date();
            var h = time.getHours();
            h = h < 10 ? '0' + h : h;
            var m = time.getMinutes();
            m = m < 10 ? '0' + m : m;
            var s = time.getSeconds();
            s = s < 10 ? '0' + s : s;
            return h + ':' + m + ':' + s;
        }
        console.log(getTimer());
    </script>
    <script>
        // 倒计时效果
        // 1.核心算法:输入的时间减去现在的时间就是剩余的时间,即倒计时 ,但是不能拿着时分秒相减,比如 05 分减去25分,结果会是负数的。
        // 2.用时间戳来做。用户输入时间总的毫秒数减去现在时间的总的毫秒数,得到的就是剩余时间的毫秒数。
        // 3.把剩余时间总的毫秒数转换为天、时、分、秒 (时间戳转换为时分秒)
        // 转换公式如下: 
        //  d = parseInt(总秒数/ 60/60 /24);    //  计算天数
        //  h = parseInt(总秒数/ 60/60 %24)   //   计算小时
        //  m = parseInt(总秒数 /60 %60 );     //   计算分数
        //  s = parseInt(总秒数%60);            //   计算当前秒数
        function countDown(time) {
            var nowTime = +new Date(); // 返回的是当前时间总的毫秒数
            var inputTime = +new Date(time); // 返回的是用户输入时间总的毫秒数
            var times = (inputTime - nowTime) / 1000; // times是剩余时间总的秒数 
            var d = parseInt(times / 60 / 60 / 24); // 天
            d = d < 10 ? '0' + d : d;
            var h = parseInt(times / 60 / 60 % 24); //时
            h = h < 10 ? '0' + h : h;
            var m = parseInt(times / 60 % 60); // 分
            m = m < 10 ? '0' + m : m;
            var s = parseInt(times % 60); // 当前的秒
            s = s < 10 ? '0' + s : s;
            return d + '天' + h + '时' + m + '分' + s + '秒';
        }
        console.log(countDown('2019-5-1 18:00:00'));
        var date = new Date();
        console.log(date);
    </script>

```javascript
获取日期指定部分

 


    getTime()  	  // 返回毫秒数和valueOf()结果一样,valueOf()内部调用的    
    getMilliseconds() 
    getSeconds()  // 返回0-59
    getMinutes()  // 返回0-59
    getHours()    // 返回0-23
    getDay()      // 返回星期几 0周日   6周6
    getDate()     // 返回当前月的第几天
    getMonth()    // 返回月份,***从0开始***
    getFullYear() //返回4位的年份  如 2016

案例

  • 写一个函数,格式化日期对象,返回yyyy-MM-dd HH:mm:ss的形式
function formatDate(d) {
  //如果date不是日期对象,返回
  if (!date instanceof Date) {
    return;
  }
  var year = d.getFullYear(),
      month = d.getMonth() + 1, 
      date = d.getDate(), 
      hour = d.getHours(), 
      minute = d.getMinutes(), 
      second = d.getSeconds();
  month = month < 10 ? '0' + month : month;
  date = date < 10 ? '0' + date : date;
  hour = hour < 10 ? '0' + hour : hour;
  minute = minute < 10 ? '0' + minute:minute;
  second = second < 10 ? '0' + second:second;
  return year + '-' + month + '-' + date + ' ' + hour + ':' + minute + ':' + second;
}

- 计算时间差,返回相差的天/时/分/秒

function getInterval(start, end) {
  var day, hour, minute, second, interval;
  interval = end - start;
  interval /= 1000;
  day = Math.round(interval / 60 /60 / 24);
  hour = Math.round(interval / 60 /60 % 24);
  minute = Math.round(interval / 60 % 60);
  second = Math.round(interval % 60);
  return {
    day: day,
    hour: hour,
    minute: minute,
    second: second
  }
}

Array对象

new Array()

- 示例代码如下:
      var arr = new Array();
  	注意:上面代码中arr创建出的是一个空数组,如果需要使用构造函数Array创建非空数组,可以在创建数组时传入参数
  	参数传递规则如下:
  - 如果只传入一个参数,则参数规定了数组的长度
  - 如果传入了多个参数,则参数称为数组的元素

    // 1. 使用构造函数创建数组对象
    // 创建了一个空数组
    var arr = new Array();
    // 创建了一个数组,里面存放了3个字符串
    var arr = new Array('zs', 'ls', 'ww');
    // 创建了一个数组,里面存放了4个数字
    var arr = new Array(1, 2, 3, 4);
    
    
    // 2. 使用字面量创建数组对象
    var arr = [1, 2, 3];
    
    // 获取数组中元素的个数
    console.log(arr.length);

- 检测一个对象是否是数组
  - instanceof可以判断一个对象是否是某个构造函数的实例
        var arr = [1, 23];
        var obj = {};
        console.log(arr instanceof Array); // true
        console.log(obj instanceof Array); // false
- Array.isArray()     HTML5中提供的方法,有兼容性问题
  函数的参数,如果要求是一个数组的话,可以用这种方式来进行判断
  - toString()		把数组转换成字符串,逗号分隔每一项
  - valueOf()         返回数组对象本身
- 数组常用方法
  演示:push()、shift()、unshift()、reverse()、sort()、splice()、indexOf()
  <script>
        // 添加删除数组元素方法
        // 1. push() 在我们数组的末尾 添加一个或者多个数组元素   push  推
        var arr = [1, 2, 3];
        // arr.push(4, 'pink');
        console.log(arr.push(4, 'pink'));

        console.log(arr);
        // (1) push 是可以给数组追加新的元素
        // (2) push() 参数直接写 数组元素就可以了
        // (3) push完毕之后,返回的结果是 新数组的长度 
        // (4) 原数组也会发生变化
        // 2. unshift 在我们数组的开头 添加一个或者多个数组元素
        console.log(arr.unshift('red', 'purple'));

        console.log(arr);
        // (1) unshift是可以给数组前面追加新的元素
        // (2) unshift() 参数直接写 数组元素就可以了
        // (3) unshift完毕之后,返回的结果是 新数组的长度 
        // (4) 原数组也会发生变化

        // 3. pop() 它可以删除数组的最后一个元素  
        console.log(arr.pop());
        console.log(arr);
        // (1) pop是可以删除数组的最后一个元素 记住一次只能删除一个元素
        // (2) pop() 没有参数
        // (3) pop完毕之后,返回的结果是 删除的那个元素 
        // (4) 原数组也会发生变化
        // 4. shift() 它可以删除数组的第一个元素  
        console.log(arr.shift());
        console.log(arr);
        // (1) shift是可以删除数组的第一个元素 记住一次只能删除一个元素
        // (2) shift() 没有参数
        // (3) shift完毕之后,返回的结果是 删除的那个元素 
        // (4) 原数组也会发生变化
    </script>
     <script>
        // 有一个包含工资的数组[1500, 1200, 2000, 2100, 1800],要求把数组中工资超过2000的删除,剩余的放到新数组里面
        var arr = [1500, 1200, 2000, 2100, 1800];
        var newArr = [];
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] < 2000) {
                // newArr[newArr.length] = arr[i];
                newArr.push(arr[i]);
            }
        }
        console.log(newArr);
    </script>
    <script>
        // 数组排序
        // 1. 翻转数组
        var arr = ['pink', 'red', 'blue'];
        arr.reverse();
        console.log(arr);

        // 2. 数组排序(冒泡排序)
        var arr1 = [13, 4, 77, 1, 7];
        arr1.sort(function(a, b) {
            //  return a - b; 升序的顺序排列
            return b - a; // 降序的顺序排列
        });
        console.log(arr1);
    </script>
     <script>
        // 返回数组元素索引号方法  indexOf(数组元素)  作用就是返回该数组元素的索引号 从前面开始查找
        // 它只返回第一个满足条件的索引号 
        // 它如果在该数组里面找不到元素,则返回的是 -1  
        // var arr = ['red', 'green', 'blue', 'pink', 'blue'];
        var arr = ['red', 'green', 'pink'];
        console.log(arr.indexOf('blue'));
        // 返回数组元素索引号方法  lastIndexOf(数组元素)  作用就是返回该数组元素的索引号 从后面开始查找
        var arr = ['red', 'green', 'blue', 'pink', 'blue'];

        console.log(arr.lastIndexOf('blue')); // 4
    </script>
    <script>
        // 数组去重 ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'] 要求去除数组中重复的元素。
        // 1.目标: 把旧数组里面不重复的元素选取出来放到新数组中, 重复的元素只保留一个, 放到新数组中去重。
        // 2.核心算法: 我们遍历旧数组, 然后拿着旧数组元素去查询新数组, 如果该元素在新数组里面没有出现过, 我们就添加, 否则不添加。
        // 3.我们怎么知道该元素没有存在? 利用 新数组.indexOf(数组元素) 如果返回时 - 1 就说明 新数组里面没有改元素
        // 封装一个 去重的函数 unique 独一无二的 
        function unique(arr) {
            var newArr = [];
            for (var i = 0; i < arr.length; i++) {
                if (newArr.indexOf(arr[i]) === -1) {
                    newArr.push(arr[i]);
                }
            }
            return newArr;
        }
        // var demo = unique(['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'])
        var demo = unique(['blue', 'green', 'blue'])
        console.log(demo);
    </script>
    <script>
        // 数组转换为字符串 
        // 1. toString() 将我们的数组转换为字符串
        var arr = [1, 2, 3];
        console.log(arr.toString()); // 1,2,3
        // 2. join(分隔符) 
        var arr1 = ['green', 'blue', 'pink'];
        console.log(arr1.join()); // green,blue,pink
        console.log(arr1.join('-')); // green-blue-pink
        console.log(arr1.join('&')); // green&blue&pink
    </script>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:join方法如果不传入参数,则按照 “ , ”拼接元素
在这里插入图片描述

 <script>
        // Math数学对象 不是一个构造函数 ,所以我们不需要new 来调用 而是直接使用里面的属性和方法即可
        console.log(Math.PI); // 一个属性 圆周率
        console.log(Math.max(1, 99, 3)); // 99
        console.log(Math.max(-1, -10)); // -1
        console.log(Math.max(1, 99, 'pink老师')); // NaN
        console.log(Math.max()); // -Infinity
    </script>
    <script>
        // 利用对象封装自己的数学对象  里面有 PI 最大值和最小值
        var myMath = {
            PI: 3.141592653,
            max: function() {
                var max = arguments[0];
                for (var i = 1; i < arguments.length; i++) {
                    if (arguments[i] > max) {
                        max = arguments[i];
                    }
                }
                return max;
            },
            min: function() {
                var min = arguments[0];
                for (var i = 1; i < arguments.length; i++) {
                    if (arguments[i] < min) {
                        min = arguments[i];
                    }
                }
                return min;
            }
        }
        console.log(myMath.PI);
        console.log(myMath.max(1, 5, 9));
        console.log(myMath.min(1, 5, 9));
    </script>
     <script>
        // 1.绝对值方法
        console.log(Math.abs(1)); // 1
        console.log(Math.abs(-1)); // 1
        console.log(Math.abs('-1')); // 隐式转换 会把字符串型 -1 转换为数字型
        console.log(Math.abs('pink')); // NaN 

        // 2.三个取整方法
        // (1) Math.floor()   地板 向下取整  往最小了取值
        console.log(Math.floor(1.1)); // 1
        console.log(Math.floor(1.9)); // 1
        // (2) Math.ceil()   ceil 天花板 向上取整  往最大了取值
        console.log(Math.ceil(1.1)); // 2
        console.log(Math.ceil(1.9)); // 2
        // (3) Math.round()   四舍五入  其他数字都是四舍五入,但是 .5 特殊 它往大了取  
        console.log(Math.round(1.1)); // 1
        console.log(Math.round(1.5)); // 2
        console.log(Math.round(1.9)); // 2
        console.log(Math.round(-1.1)); // -1
        console.log(Math.round(-1.5)); // 这个结果是 -1
    </script>
    script>
        // 1.Math对象随机数方法   random() 返回一个随机的小数  0 =< x < 1
        // 2. 这个方法里面不跟参数
        // 3. 代码验证 
        console.log(Math.random());
        // 4. 我们想要得到两个数之间的随机整数 并且 包含这2个整数
        // Math.floor(Math.random() * (max - min + 1)) + min;
        function getRandom(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }
        console.log(getRandom(1, 10));
        // 5. 随机点名  
        var arr = ['张三', '张三丰', '张三疯子', '李四', '李思思', 'pink老师'];
        // console.log(arr[0]);
        console.log(arr[getRandom(0, arr.length - 1)]);
    </script>

案例

  • 将一个字符串数组输出为|分割的形式,比如“刘备|张飞|关羽”。使用两种方式实现
    function myJoin(array, seperator) {
      seperator = seperator || ',';
      array = array || [];
      if (array.length == 0){
        return '';
      }
      var str = array[0];
      for (var i = 1; i < array.length; i++) {
        str += seperator + array[i];
      }
      return str;
    }
    var array = [6, 3, 5, 6, 7, 8, 0];
    console.log(myJoin(array, '-'));
    
    console.log(array.join('-'))

- 将一个字符串数组的元素的顺序进行反转。["a", "b", "c", "d"] -> [ "d","c","b","a"]。使用两种种方式实现。提示:第i个和第length-i-1个进行交换

    function myReverse(arr) {
      if (!arr || arr.length == 0) {
        return [];
      }
      for (var i = 0; i < arr.length / 2; i++) {
        var tmp = arr[i];
        arr[i] = arr[this.length - i - 1];
        arr[arr.length - i - 1] = tmp;
      }
      return arr;
    }
    
    var array = ['a', 'b', 'c'];
    console.log(myReverse(array));
    
    console.log(array.reverse());

- 工资的数组[1500, 1200, 2000, 2100, 1800],把工资超过2000的删除

    // 方式1
    var array =  [1500,1200,2000,2100,1800];
    var tmpArray = [];
    for (var i = 0; i < array.length; i++) {
      if(array[i] < 2000) {
        tmpArray.push(array[i]);
      }
    }
    console.log(tmpArray);
    // 方式2
    var array =  [1500, 1200, 2000, 2100, 1800];
    array = array.filter(function (item, index) {
      if (item < 2000) {
        return true;
      }
      return false;
    });
    console.log(array);

- ["c", "a", "z", "a", "x", "a"]找到数组中每一个a出现的位置

    var array =  ['c', 'a', 'z', 'a', 'x', 'a'];
    do {
      var index = array.indexOf('a',index + 1);
      if (index != -1){
        console.log(index);
      }
    } while (index > 0);

- 编写一个方法去掉一个数组的重复元素

    var array =  ['c', 'a', 'z', 'a', 'x', 'a'];
    function clear() {
      var o = {};
      for (var i = 0; i < array.length; i++) {
        var item = array[i];
        if (o[item]) {
          o[item]++;
        }else{
          o[item] = 1;
        }
      }
      var tmpArray = [];
      for(var key in o) {
        if (o[key] == 1) {
          tmpArray.push(key);
        }else{
          if(tmpArray.indexOf(key) == -1){
            tmpArray.push(key);
          }
        }
      }
      returm tmpArray;
    }
    
    console.log(clear(array));

基本包装类型

为了方便操作基本数据类型,JavaScript还提供了三个特殊的引用类型:String/Number/Boolean
<script>
        // 基本包装类型
        var str = 'andy';
        console.log(str.length);
        // 对象 才有 属性和方法   复杂数据类型才有 属性和方法 
        // 简单数据类型为什么会有length 属性呢? 
        // 基本包装类型:  就是把简单数据类型 包装成为了 复杂数据类型 
        // (1) 把简单数据类型包装为复杂数据类型 
        var temp = new String('andy');
        // (2) 把临时变量的值 给 str
        str = temp;
        // (3) 销毁这个临时变量
        temp = null;
    </script>

    // 下面代码的问题?
    // s1是基本类型,基本类型是没有方法的
    var s1 = 'zhangsan';
    var s2 = s1.substring(5);
    
    // 当调用s1.substring(5)的时候,先把s1包装成String类型的临时对象,再调用substring方法,最后销毁临时对象, 相当于:
    var s1 = new String('zhangsan');
    var s2 = s1.substring(5);
    s1 = null;

    // 创建基本包装类型的对象
    var num = 18;  				//数值,基本类型
    var num = Number('18'); 	//类型转换
    var num = new Number(18); 	//基本包装类型,对象
    // Number和Boolean基本包装类型基本不用,使用的话可能会引起歧义。例如:
    var b1 = new Boolean(false);
    var b2 = b1 && true;		// 结果是什么

String对象

- 字符串的不可变

    var str = 'abc';
    str = 'hello';
    // 当重新给str赋值的时候,常量'abc'不会被修改,依然在内存中
    // 重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变
    // 由于字符串的不可变,在大量拼接字符串的时候会有效率问题

- 创建字符串对象

    var str = new String('Hello World');
    
    // 获取字符串中字符的个数
    console.log(str.length);

- 字符串对象的常用方法
  字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串

    // 1 字符方法
    charAt()    	//获取指定位置处字符
    charCodeAt()  	//获取指定位置处字符的ASCII码
    str[0]   		//HTML5,IE8+支持 和charAt()等效
    // 2 字符串操作方法
    concat()   		//拼接字符串,等效于+,+更常用
    slice()    		//从start位置开始,截取到end位置,end取不到
    substring() 	//从start位置开始,截取到end位置,end取不到
    substr()   		//从start位置开始,截取length个字符
    // 3 位置方法
    indexOf()   	//返回指定内容在元字符串中的位置
    lastIndexOf() 	//从后往前找,只找第一个匹配的
    // 4 去除空白   
    trim()  		//只能去除字符串前后的空白
    // 5 大小写转换方法
    to(Locale)UpperCase() 	//转换大写
    to(Locale)LowerCase() 	//转换小写
    // 6 其它
    search()
    replace()
    split()
    fromCharCode()
    // String.fromCharCode(101, 102, 103);	 //把ASCII码转换成字符串

案例

- 截取字符串"我爱中华人民共和国",中的"中华"

    var s = "我爱中华人民共和国";
    s = s.substr(2,2);
    console.log(s);

- "abcoefoxyozzopp"查找字符串中所有o出现的位置

    var s = 'abcoefoxyozzopp';
    var array = [];
    do {
      var index = s.indexOf('o', index + 1);
      if (index != -1) {
        array.push(index);
      }
    } while (index > -1);
    console.log(array);

- 把字符串中所有的o替换成!

    var s = 'abcoefoxyozzopp';
    do {
      s = s.replace('o', '');
    } while (s.indexOf('o') > -1);
    console.log(s);
    
    console.log(s.replace(/o/ig, ''));

- 判断一个字符串中出现次数最多的字符,统计这个次数

    var s = 'abcoefoxyozzopp';
    var o = {};
    
    for (var i = 0; i < s.length; i++) {
      var item = s.charAt(i);
      if (o[item]) {
        o[item] ++;
      }else{
        o[item] = 1;
      }
    }
    
    var max = 0;
    var char ;
    for(var key in o) {
      if (max < o[key]) {
        max = o[key];
        char = key;
      }
    }
    
    console.log(max);
    console.log(char);
    <script>
        // 有一个对象 来判断是否有该属性 对象['属性名']
        var o = {
            age: 18
        }
        if (o['sex']) {
            console.log('里面有该属性');

        } else {
            console.log('没有该属性');

        }

        //  判断一个字符串 'abcoefoxyozzopp' 中出现次数最多的字符,并统计其次数。
        // o.a = 1
        // o.b = 1
        // o.c = 1
        // o.o = 4
        // 核心算法:利用 charAt() 遍历这个字符串
        // 把每个字符都存储给对象, 如果对象没有该属性,就为1,如果存在了就 +1
        // 遍历对象,得到最大值和该字符
        var str = 'abcoefoxyozzopp';
        var o = {};
        for (var i = 0; i < str.length; i++) {
            var chars = str.charAt(i); // chars 是 字符串的每一个字符
            if (o[chars]) { // o[chars] 得到的是属性值
                o[chars]++;
            } else {
                o[chars] = 1;
            }
        }
        console.log(o);
        // 2. 遍历对象
        var max = 0;
        var ch = '';
        for (var k in o) {
            // k 得到是 属性名
            // o[k] 得到的是属性值
            if (o[k] > max) {
                max = o[k];
                ch = k;
            }
        }
        console.log(max);
        console.log('最多的字符是' + ch);
    </script>
    <script>
        // 字符串操作方法
        // 1. concat('字符串1','字符串2'....)
        var str = 'andy';
        console.log(str.concat('red'));

        // 2. substr('截取的起始位置', '截取几个字符');
        var str1 = '改革春风吹满地';
        console.log(str1.substr(2, 2)); // 第一个2 是索引号的2 从第几个开始  第二个2 是取几个字符
    </script>
    <script>
        // 1. 替换字符 replace('被替换的字符', '替换为的字符')  它只会替换第一个字符
        var str = 'andyandy';
        console.log(str.replace('a', 'b'));
        // 有一个字符串 'abcoefoxyozzopp'  要求把里面所有的 o 替换为 *
        var str1 = 'abcoefoxyozzopp';
        while (str1.indexOf('o') !== -1) {
            str1 = str1.replace('o', '*');
        }
        console.log(str1);

        // 2. 字符转换为数组 split('分隔符')    前面我们学过 join 把数组转换为字符串
        var str2 = 'red, pink, blue';
        console.log(str2.split(','));
        var str3 = 'red&pink&blue';
        console.log(str3.split('&'));
    </script>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值