数组的创建访问

  <script>
    // 1.数组(Array): 就是一组数据的集合 存储在单个变量下的优雅方式
    // 2. 利用new 创建数组
    var arr = new Array(); // 创建了一个空数组
    // 3. 利用数组字面量创建数组 []
    var arr = []; // 创建了一个空的数组
    var arr1 = [1,2,'pink老师',true];
    // 4. 我们数组里面的数据一定用逗号分隔
    // 5. 数组里面的数据 比如1,2 我们称为数组元素
    // 6. 获取数组元素 格式 数组名[索引号] 索引号从0开始
    console.log(arr1);
    console.log(arr1[2]); // pink老师
    console.log(arr[3]); // true
    var arr2 = ['迪丽热巴','古力娜扎','佟丽娅呀'];
    console.log(arr2[0]);
    console.log(arr2[1]);
    console.log(arr2[2]);
    console.log(arr2[3]); // 因为没有这个数组元素 所以输出的结果是 undefined
  </script>

遍历数组

遍历: 就是把数组中的每个元素从头到尾都访问一次

  <script>
    // 遍历数组;就是把数组的元素从头访问一次
    var arr = ['red','green','blue'];
    for (var i = 0; i < 3;i++) {
      console.log(arr[i]);
    }
    // 数组长度 数组名 .length
    console.log(arr.length);
    for (var i = 0;i < arr.length;i++)
    console.log(arr[i]);
    // 1.因为我们的数组索引号从0开始,所以 i 必须从 0开始 i < 3
    // 2.输出的时候 arr[i] i 计数器当索引号使用
    // 3. arr.length 动态监测数组元素的个数
  </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];
      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.同时在后面多加一个分隔符
    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>

数组新增元素

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

数组存放1~10个值

  <script>
      // 新建一个数组,里面存放10个整数 (1~10)
      // 核心原理: 使用循环来追加数组。
      // 1、声明一个空数组 arr。
      // 2、循环中的计数器 i 可以作为数组元素存入。
      // 3、由于数组的索引号是从0开始的, 因此计数器从 0 开始更合适,存入的数组元素要+1。
      var arr = [];
      for (var i = 0;i < 100;i++) {
        // arr = i; 不要直接给数组名赋值 否则以前的元素都没了
        arr[i] = i + 1;
      }
      console.log(arr);
  </script>

筛选数组方法

  <script>
      // 将数组 [2,0,6,1,77,0,52,0,25,7] 中大于等于 10 的元素选出来,放入新数组。
      // 1、声明一个新的数组用于存放新数据newArr。
      // 2、遍历原来的旧数组,找出大于等于 10 的元素。
      // 3、依次追加给新数组 newArr。
      // 方法一
      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);

      // 方法二
      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'];
    var newArr = [];
    for (var i = arr.length -1;i >= 0;i--) {
      newArr[newArr.length] = arr[i]
    }
    console.log(newArr)
  </script>

复习交换两个变量值

  <script>
    // 交换两个变量
    var num1 = 'pink';
    var num2 = 'yellow';
    var temp;
    temp = num1;
    num1 = num2;
    num2 = temp;
    console.log(num1,num2)
  </script>

冒泡排序

冒泡排序:是一种算法,把一系列的数据按照一定的顺序进行排列显示(从小到大或从大到小)

  <script>
      // 冒泡排序
      var arr = [4,1,2,3,5];
      for (var i = 0;i <= arr.length - 1;i++) { // 外层循环管趟数
        for (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;
          }
        }
      }
      console.log(arr)
  </script>

函数的使用

函数:就是封装了一段可被重复调用执行的代码块。通过此代码块可以实现大量代码的重复使用。

  <script>
      // 函数使用分为两步; 声明函数 和 调用函数
      // 1. 声明函数
      // function 函数名() {
      //     // 函数体  
      // }
      function sayHi() {
        console.log('hi~~');
      }
      // (1) function 声明函数的关键字 全部小写
      // (2) 函数是做某件事情,函数名一般是动词 sayHi
      // (3) 函数不调用自己不执行
      // 2. 调用函数 函数名();
      sayHi();
      // 调用函数的时候千万不要忘记加小括号
  </script>

函数的封装是把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口

利用函数求1~100累加和

  <script>
      function getSum() {
        var sum = 0;
        for (var i = 1;i <= 100;i++) {
          sum += i;
        }
        console.log(sum);
      }
      
      getSum();
  </script>

函数的参数

  <script>
      // 1.函数可以重复相同的代码
      function cook() {
        console.log('酸辣土豆丝');

      }
      cook();
      cook();
      // 2.我们可以利用函数的参数实现函数重复不同的代码
      // function 函数名(形参1,形参2...) { // 在声明函数的小括号里面的是 形参 (形式上的参数)
    
      // }
      // 函数名(实参1,实参2...); // 在函数调用的小括号里面是实参(实际的参数)
      // 3. 形参和实参的执行过程
      function cook(aru) {
        console.log(aru);
      }

      cook('酸辣土豆丝');
      cook('大肘子');
      // 4. 函数的参数可以有,也可以没有个数不限
  </script>

利用函数求任意两个数的和以及累加和

  <script>
      // 1. 利用函数求任意两个数的和
      function getSum(num1,num2) {
        console.log(num1 + num2);
      }

      getSum(1,3);
      getSum(3,8);

      // 2. 利用函数求任意两个数之间的和
      function getSums(start,end) {
        var sum = 0;
        for (var i = start;i <= end;i++) {
          sum += i;
        }
        console.log(sum);
      }
      getSums(1,100);
      // 3. 注意点
      // (1) 多个参数之间用逗号隔开
      // (2) 形参可以看作不用声明的变量
  </script>

函数形参和实参匹配问题

  <script>
      // 函数形参实参个数匹配
      function getSum(num1,num2) {
        console.log(num1 + num2);

      }
      // 1.如果实参的个数和形参的个数一致 则正常输出结果
      getSum(1,2);
      // 2.如果实参的个数多余形参的个数 会取到形参的个数
      getSum(1,2,3);
      // 3.如果实参的个数小于形参的个数 多余的形参定义为undefined 最终的结果就是 NaN
      // 形参可以看作是不用声明的变量 num2 是一个变量但是没有接收值 结果就是undefined
      getSum(1); // NaN
      // 建议 我们尽量让实参的个数和形参相匹配
  </script>

函数的返回值return

  <script>
      // 1.函数是做某件事或者实现某种功能
      function cook(aru) {
        console.log(aru);
      }
      cook('大肘子');
      // 2. 函数的返回值格式
      // function 函数名() {
      //     return 需要返回的结果;  
      // }
      // 函数名();
      // (1) 我们函数只是实现某种功能,最终的结果需要返回给函数的调用者 函数名() 通过return 实现的
      // (2) 只要函数遇到return 就把后面的结果 返回给函数的调用者 函数名() = return后面的结果
      // 3. 代码验证
      function getResult() {
        return 666;
      }

      getResult(); // getResult() = 666
      console.log(getResult());

      // 4.求任意两个数的和
      function getSum(num1,num2) {
        return num1 + num2;
      }
      console.log(getSum(1,2));

      // 5.利用函数求两个数的最大值
      function getMax(num1,num2) {
        if (num1 > num2) {
          return num1;
        } else {
          return num2;
        }
      }
      // return num1 > num2 ? num1:num2; 三元运算符计算
      console.log(getMax(1,3))

      // 6. 利用函数求任意一个数组中的最大值
      function getArrMax(arr) {
        var max = arr[0];
        for(var i = 0;i <= arr.length;i++) {
          if (arr[i] > max) {
            max = arr[i];
          }
        }
        return max;
      }
      // getArrMax([5,2,99,101,67,77]); // 实参是一个数组送过去
      // 在我们实际开发里面,我们经常用一个变量来接受 函数的返回结果 使用更简单
      var re = getArrMax([5,2,99,101,67,77]);
      console.log(re);
  </script>
  • return终止函数并且只能返回一个值
  • 返回的结果是最后一个值(数组是一个值)

函数返回值注意事项

  <script>
      // 函数返回值注意事项
      // 1. return 终止函数
      function getSum(num1,num2) {
        return num1 + num2; // return 后面的代码不会被执行
        alert('我是不会被执行的哦!')
      }
      console.log(getSum(1,2));
      // 2.return 只能返回一个值
      function fn(num1,num2) { 
          return num1,num2; // 返回的结果是最后一个值
      }
      console.log(fn(1,2));
      
      // 3. 我们求任意两个数的 加减乘除结果
      function getResult(num1,num2) {
        return [num1+ num2,num1 - num2,num1 * num2,num1 / num2];
      }
      var re = getResult(1,2); // 返回的是一个数组
      console.log(re);

      // 4.我们的函数如果有return 则返回的是 return 后面的值,如果函数没有return 则返回undefined
      function fun1() {
        return 666;
      }
      console.log(fun1()); // 返回 666
      function fun2() {

      }
      console.log(fun2()); // 函数返回的结果是undefined
  </script>

arguments使用

  <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 = 0;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(1,2,34,444,5,100));

      // 利用函数封装的方法,翻转任意一个数组 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);

      // 利用函数冒泡排序
      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);

      // 判断闰年(闰年:能被4整除,并且不能被100整除,或者能被400整除)
      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>

函数可以调用另外一个函数

  <script>
      // 函数是可以相互调用的
      function fn1() {
        console.log(11);
        fn2(); // 在fn1 函数里面调用了 fn2函数
      }
      fn1();

      function fn2() {
        console.log(22);
      }

      // 案例:用户输入年份,输出当前年份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>

函数的两种声明方式

  <script>
      // 函数中2种声明方式
      // 1.利用函数关键字自定义函数(命名函数)
      function fn() {

      }
      fn();
      // 2.函数表达式(匿名函数)
      // var 变量名 = function(){};
      var fun = function() {
        console.log('我是函数表达式');
        console.log(aru);
      }
      fun('pink老师');
      // (1) fun是变量名 不是函数名
      // (2) 函数表达式声明方式和声明变量差不多,只不过变量里面存的是值 而函数表达式里面存的是函数
      // (3) 函数表达式也可以进行传递参数
      
    </script>

JavaScript作用域

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

      fn();
    </script>

全局变量和局部变量

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

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

      // 2.局部变量 在局部作用域下的变量 后者在函数内部的变量就是 局部变量
      // 注意:函数的形参也可以看作是局部变量
      function fun() {
        var num1 = 10; // num1就是局部变量 只能在函数内部使用
        num2 = 20;
      }
      fun();
      // console.log(num1);
      console.log(num2);

      // 3. 从执行效率来看全局变量和局部变量
      // (1) 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
      // (2) 局部变量 当我们程序执行完毕就会销毁,比较节约内存资源
  </script>
  • JvaScript没有块级作用域

作用域链

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

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

  </script>

预解析

  <script>
      // 1问
      // console.log(num);

      // 2问
      console.log(num); // undefined 坑1
      var num = 10;
      // var sum; 
      // console.log(num);
      // num = 10;

      
      // 3问
      fn();

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

      // 4问
      fun(); // 报错 坑2
      var fun = function() {
        console.log(22);
      }

      // 1. 我们js引擎运行js 分为两步: 预解析 代码执行
      // (1). 预解析 js引擎会把js里面所有的var还有function提升到当前作用域的最前面
      // (2). 代码执行 按照代码书写的顺序从上往下执行
      // 2. 预解析分为 变量预解析(变量提升) 和 函数预解析(函数提升)
      // (1) 变量提升 就是把所有的变量声明提升到当前的作用域最前面,不提升赋值操作
      // (2) 函数提升 就是把所有的函数声明提升到当前作用域的最前面,不调用函数
    </script>

预解析案例

  <script>
      // 案例4
      f1();
      console.log(c);
      console.log(b);
      console.log(a);

      function f1() {
        var a = b = c = 9;
        console.log(a);
        console.log(b);
        console.log(c);
      }

      // 解析
      function f1() {
        var a;
        // var a = b = c = 9;
        a = b = c = 9;
        // 相当于var a = 9; b = 9; c = 9; b和c 直接复制 没有var声明,当全局变量看
        // 集体声明var a = 9, b = 9, c = 9;
        console.log(a);
        console.log(b);
        console.log(c);
      }
      f1();
      console.log(c);
      console.log(b);
      console.log(a);

  </script>

对象

  • 对象是一个具体的事物 在JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组.函数等。 对象是由属性和方法组成的。 属性:事物的特征,在对象中用属性来表示(常用名词) 方法:事物的行为,在对象中用方法来表示(常用动词)

利用对象字面量创建对象

  <script>
      // 三种方法(object)
      // 一、利用字面量创建对象 {}
      // 对象字面量:就是花括号 {} 里面包含了表达这个具体事物(对象)的属性和方法
      // var obj = {}; // 创建了一个空的对象
      var obj = {
        uname: '张三丰',
        age: 18,
        sex: '男',
        sayHi: function() {
          console.log('hi~');
        }
      }
      // (1) 里面的属性或者方法我们采取键值对的形式 健 属性名: 值 属性值
      // (2) 多个属性或者方法中间用逗号隔开的
      // (3) 方法冒号后面跟的是一个匿名函数
      // 2. 使用对象
      // (1).调用对象的属性 我们采取对象名.属性名 这个.我们理解为的
      console.log(obj.uname);
      // (2). 调用属性还有一种方法 对象名['属性名']
      console.log(obj['age']);
      // (3).调用对象的方法 sayHi 对象名.方法名()  千万别忘记添加小括号
      obj.sayHi();
    </script>

变量属性函数方法的区别

  <script>
      // 变量、属性、函数、方法的区别
      // 变量和属性的相同点 都是用来存储数据的
      var num = 10;
      var obj = {
        age: 18,
        fn: function() {

        }
      }
      function fu() {

      }
      console.log(obj.age);
      //console.log(age);

      // 变量 单独声明并赋值 使用的时候直接写变量名
      // 属性 在对象里面的不需要声明 使用的时候必须是 对象.属性
      // 2.函数和方法的相同点 都是实现某种功能 做某件事
      // 函数是单独声明 并且调用的 函数名() 单独存在的
      // 方法 在对象里面 调用的时候 对象.方法()
  </script>

利用new Object创建对象

  <script>
      // 利用 new Object 创建对象
      var obj = new Object(); // 创建了一个空的对象
      obj.uname = '张三丰';
      obj.age = 18;
      obj.sex = '男';
      obj.sayHi = function() {
        console.log('hi~');
      }
      // (1) 我们是利用 等号 = 赋值的方法 添加对象的属性和方法
      // (2) 每个属性和方法之间用分号结束
      console.log(obj.uname);
      console.log(obj['sex']);
      obj.sayHi();
  </script>

构造函数创建对象

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

  <script>
      // 为什么需要使用构造函数
      // 就是因为我们前面两种创建对象的方式一次只能创建一个对象
      // 因此可以利用函数方法 重复这些相同的代码 则将这个函数称为 构造函数
      // 又因为这个函数不一样,里面封装的不是普通代码,而是 对象
      // 构造函数 就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面

      // 创建四大天王的对象 相同的属性:名字 年龄 性别  相同的方法:唱歌
      // function 构造函数名() {
      //   this.属性 = 值;
      //   this.方法 = function () {}
      // }
      // new 构造函数名();

      function Star(uname,age,sex) {
        this.name = uname;
        this.age = age;
        this.sex = sex;
        this.sing = function(sang) {
          console.log(sang);
        }
      }
      
      var ldh = new Star('刘德华',19,'男'); // 调用函数返回的是一个对象
      // console.log(typeof ldh)
      console.log(ldh.name);
      console.log(ldh['sex']);
      ldh.sing('冰雨');

      var zxy = new Star('张学友',19,'男');
      console.log(zxy.name);
      console.log(zxy.age);
      zxy.sing('李香兰');

      // 1.构造函数的名字首字母大写(规范)
      // 2.构造函数不需要return就可以返回结果
      // 3.我们调用构造函数 必须使用 new
      // 4.我们只要new Star() 调用函数就可以创建一个对象 ldh {}
      // 5.我们的属性和方法前面必须添加this
  </script>

构造函数,如Stars(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class) 创建对象,如new Stars(),特指某一个通过 new 关键字创建对象的过程我们也称为对象实例化

new关键字执行过程和遍历对象

  <script>
      // new 关键字执行过程
      // 1. new 构造函数可以在内存中创建了一个空的对象
      // 2. this 就会指向刚才创建的空对象
      // 3. 执行构造函数里面的代码,给这个空对象添加属性和代码
      // 4. 返回这个对象
      function Star(uname,age,sex) {
        this.uname = uname;
        this.age =age;
        this.sing = function(sang) {
          console.log(sang);
        }
      }
      var ldh = new Star('刘德华',18,'男');

      // 遍历对象
      var obj = {
        name: 'pink老师',
        age: 18,
        sex: '男',
        fn: function() {

        }
      }
      console.log(obj.name);
      console.log(obj.age);
      console.log(obj.sex);

      // for in 遍历我们的对象
      for (变量 in 对象) {

      }

      // 我们使用 for in 里面的变量 我们喜欢写 k 或者 key
      for (var k in obj) {
        console.log(k); // k 变量 输出 得到的是属性名
        console.log(obj[k]); // obj[k] 得到的是属性值
      }
  </script>

内置对象

JavaScript中的对象分为3种:自定义对象、内置对象、浏览器对象 内置对象就是指 JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方注) 内置对象最大的优点就是帮助我们快速开发 JavaScript提供了多个内置对象:Math、 Date 、Array、String等

学会查阅MDN文档

学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过查文档学习,可以通过MDN/W3C来查询。

  1. 查阅该方法的功能
  2. 查看里面参数的意义和类型
  3. 查看返回值的意义和类型
  4. 通过 demo 进行测试

数学对象Math最大值方法

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

      console.log(Math.max()); // -Infinity
  </script>

封装自己的数学对象

  <script>
      // 利用对象封装自己的数学对象 里面有PI最大值和最小值
      var myMath = {
        PI: 3.1415926,
        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.max(1,5,9));
  </script>

Math绝对值和三个取整方法

  <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.celi()  ceil 天花板 向上取整 往最大了取值
      console.log(Math.ceil(1.1)); // 2
      console.log(Math.ceil(1.9)); // 2
      // (3) Math.round() 四舍五入 其他数字都是四舍五入,但是.5特殊 它往大了取
      console.log(Math.ceil(1.1)); // 1
      console.log(Math.ceil(1.5)); // 2
      console.log(Math.ceil(1.9)); // 2
      console.log(Math.ceil(-1.1)); // -1
      console.log(Math.ceil(-1.5)); // -1

  </script>

Math随机数方法

  <script>
      // Math对象随机数方法 random() 返回一个随机的小数 0 <= x < 1
      // 2.这个方法里面不跟参数
      // 3.代码验证
      console.log(Math.random());
      // 4.我们想要得到两个数之间的随机整数 并且 包含这2个数
      // Math.floor(Math.random() * (max - min + 1)) + min;
      function getRandomInt(min, max) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值
      }
      console.log(getRandomInt(1,10));

      // 5.随机点名  
      var arr = ['张三','张三丰','张三丰子','李四','李思思','pink老师'];
      // console.log(arr[0]);
      console.log(arr[getRandomInt(0,arr,length - 1)]);
  </script>

猜数字游戏

  <script>
      // 随机生成一个1~10的整数 我们需要用到Math.random()方法
      // 需要一直猜到正确为止,所以一直循环
      // 用 while 循环合适更简单
      // 核心算法:使用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; // 退出整个循环结束程序
          }
      }

  </script>

Date日期对象的使用

  • Date 对象和 Math 对象不一样,他是一个构造函数,所以我们需要实例化后才能使用
  • Date实例用来处理日期和时间
  <script>
      // Date() 日期对象 是一个构造函数 必须使用new 来调用创建我们的日期对象
      var arr = new Array();  // 创建一个数组对象
      var obj = new Object(); // 创建了一个对象实例
      // 1.使用Date
      var date = new Date();
      console.log(date);

      // 2.参数常用的写法 数字型 2019,10,01 或者是 字符串型 '2019-10-1 8:8:8'
      var date1 = new Date(2019,10,1);
      console.log(date1); // 返回的是11月 并不是10月

      var date2 = new Date('2019-10-1 8:8:8');
      console.log(date2);
  </script>

格式化日期年月日星期

  <script>
      // 格式化日期 年月日
      var date = new Date();
      console.log(date.getFullYear()); // 返回当前日期的年 2023
      console.log(date.getMonth()); // 月份6 返回的月份小一个月0-11 记得月份+1呦
      console.log(date.getDate()); // 返回的是 几号
      console.log(date.getDay()); // 2 周一返回的是1 周六返回的是6 周日返回的是0
      // 我们写一个2023年 7月 4日 星期三
      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 getTime() {
        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(getTime());
  </script>

Date总的毫秒数(时间戳)

  <script>
      // 获得Date总的毫秒数(时间戳) 不是当前时间的毫秒数 而是距离1970年1月1号过了多少毫秒数
      // 1.通过 valueOf() getTime()
       var date = new Date();
       console.log(date.valueOf()); // 就是我们现在时间距离 1970.1.1总的毫秒数
       console.log(date.getTime());

       // 2.简单写法(最常用的写法)
       var date1 = +new Date(); // +new Date() 返回的就是总的毫秒数
       console.log(date1);

       // 3.H5 新增的 获得总的毫秒数
       console.log(Date.now());
  </script>

倒计时

  1. 核心算法:输入的时间减去现在的时间就是剩余的时间,即倒计时,但是不能拿着时分秒相减,比如05 分减去25分,结果会是负数的。
  2. 用时间戳来做。用户输入时间总的毫秒数减去现在时间的总的毫秒数,得到的就是剩余时间的毫秒数。
  3. 把剩余时间总的毫秒数转换为天、时、分、秒(时间戳转换为时分秒)转换公式如下: d = parselnt(总秒数/60/60/24); // 计算天数 h = parselnt(总秒数/60/60%24); // 计算小时 m = parselnt(总秒数/60 %60); // 计算分数 s = parselnt(总秒数%60); //计算当前秒数
  <script>
      // 倒计时
      function conutDown(time) {
        var nowTime = +new Date(); // 返回的是当前时间总的毫秒数
        var inputTiem = +new Date(time); // 返回的是用户输入事件总的毫秒数
        var times = (inputTiem - nowTime) / 1000; // time是剩余时间总的秒数
        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(conutDown('2023-5-1 18:00:00'));
      var date = new Date();
      console.log(date);

  </script>

数组创建的两种方式

  <script>
      // 创建数组的两种方式
      // 1.利用数组字面量
      var arr = [1, 2, 3];
      console.log(arr[0]);

      // 2.利用new Array()
      // var arr1 = new Array(); // 创建了一个空的数组
      // var arr1 = new Array(2); // 这个2 表示数组的长度为 2 里面有2个空的数组元素
      var arr1 = new Array(2,3) // 等价于 [2,3] 这样写表示 里面有2个数组元素 是 2和3
      console.log(arr1);
  </script>

检测是否为数组两种方式

  <script>
      // 翻转数组 
      function reverse(arr) {
        if (arr instanceof Array) {
          var newArr = [];
          for (var i = arr.length - 1;i >= 0;i--) {
            newArr[newArr.length] = arr[i];
          }
          return newArr;
        } else {
          return ' error 这个参数要求必须是数组格式[1,2,3]'
        }
      }
      console.log(reverse([1,2,3]));
      console.log(reverse(1,2,3));
      // 检测是否为数组
      // (1) instanceof 运算符 它可以用来检测是否为数组
      var arr = [];
      var obj = {};
      console.log(arr instanceof Array);
      console.log(obj instanceof Array);  

      // (2) Array.isArray(参数); H5里面新增的方法
      console.log(Array.isArray(arr));
      console.log(Array.isArray(obj));
  </script>

添加、删除数组元素

  <script>
      // 添加数组元素方法
      // 1. push() 在我们数组的末尾 添加一个或者多个数组元素 push 推
      var arr = [1,2,3];
      arr.push(4,'pink');
      console.log(arr);
      // (1) push 可以给数组追加新的元素
      // (2) push() 参数直接写 数组元素
      // (3) push完毕之后,返回的结果是 新数组的长度
      // (4) 原数组也会发生变化

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

      // 删除数组元素方法
      // 3. pop() 它可以删除数组最后一个元素
      arr.pop();
      console.log(arr);
      // (1) pop是可以删除数组的最后一个元素 记住一次只能删除一个元素
      // (2) pop() 没有参数
      // (3) pop完毕之后,返回的结果是 删除的那个元素
      // (4) 原数组也会发生变化

      // 4. shift() 它可以删除数组的第一个元素
      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);

      // 返回数组元素索引号方法 indexOf(数组元素) 返回该数组元素的索引号
      // 他只返回第一个满足条件的索引号,若没有则返回-1
      var arr = ['red','green','blue','pink','blue'];
      console.log(arr.indexOf('blue'));
      console.log(arr.lastIndexOf('blue')); // lastIndexOf 从后面往前开始查找
  </script>

数组去重案例

目标:把旧数组里面不重复的元素选取出来放到新数组中,重复的元素只保留一个,放到新数组中去重 核心算法:我们遍历旧数组,然后拿着旧数组元素去查询新数组,如果该元素在新数组里面没有出现过,我们就添加,否则不添加。

  <script>
      // 数组去重 ['c','a','z','a','x','a','x','c','b'] 要求去除数组中重复的元素。
      // 利用 新数组.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']);
      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(arr.join()); // green,blue,pink
      console.log(arr1.join('-')); // green-blue-pink
  </script>

基本包装类型、字符串不可变

基本包装类型就是把简单数据类型包类成为复杂数据类型,这样基本数据类型就有了属性和方法

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

      // 字符串不可变性
      // 指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间
      var str = 'andy';
      console.log(str);
      str = 'red';
      console.log(str);
      // 因为我们字符串的不可变所以不要大量的拼接字符串
      var str = '';
      for (var i = 1;i <= 100;i++) {
        str += i;

      }
      console.log(str);
  </script>

根据字符返回位置和字符

  <script>
      // 字符串对象 根据字符串返回位置 str.indexOf('要查找的字符',[起始的位置])
      var str = '改革春风吹满地,春天来了';
      console.log(str.indexOf('春'));
      console.log(str.indexOf('春',3)); // 从索引号是3的位置开始往后查找

      // 求某个字符出现的位置以及次数
      // 查找字符串"abcoefoxyozzopp"中所有o出现的位置以及次数
      // 核心算法:先查找第一个o出现的位置 
      // 然后 只要indexOf 返回的结果不是 -1 就继续往后查找
      // 因为indexOf 只能查找到第一个,所以后面的查找,一定是当前索引加1,从而继续查找
      var str = "abcoefoxyozzopp"
      var index = str.indexOf('o');
      var num = 0;
      // console.log(index);
      while(index !== -1) {
        console.log(index);
        num++;
        index = str.indexOf('o',index + 1);
      }
      console.log('o出现的次数是:' + num);

      // 根据位置返回字符(重点)
      // 1. charAt(index) 根据位置返回字符
      var str = 'andy';
      console.log(str.charAt(3));
      // 遍历所有字符
      for (var i = 0;i < str.length;i++) {
        console.log(str.charAt(i));
      }

      // 2.charCode(index) 返回相应索引号的字符ASCII值 
      // 目的:判断用户按下了哪个键
      console.log(str.charCodeAt(0)); // 97
      // 3. str[index] H5新增的
      console.log(str[0]);


      // 判断一个字符串"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>

简单数据类型和复杂数据类型导读

简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。

  • 值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型 string , number , boolean , undefined , null 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型通过 new 关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等
  <script>
      // 简单数据类型 null 返回的是一个空的对象 object
      var timer = null;
      console.log(typeof timer);
      // 如果有个变量我们以后打算存储为对象,暂时没想好放啥,这个时候就给 null
      // 1.简单数据类型 是存放在栈里面  里面直接开辟一个空间存放的是值
  </script>

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