[前端学习] JavaScript 笔记 (二)

一、分支语句

  1. if分支语句
    if分支语句有三种:单分支、双分支、多分支。
      // 单分支语句
      if (条件) {
        // 括号中‘条件’的值都会转为布尔值,
        // 数字中除了'0'都为真,字符串中除了空字符串''都为真
        '条件''真(true)'执行的代码
      }
      // 双分支语句
      if (条件) {
        满足'条件'执行
      } else {
        不满足'条件'执行
      }
      // 多分支语句
      if (条件一) {
        满足'条件一'执行
      } else if (条件二) {
        不满足'条件一'但满足'条件二'执行
      } else if (条件三) {
        不满足'条件一和二',但满足'条件三'执行
      } else if (条件n) {
        前面的'条件n-1'都不满足,满足'条件n'执行
      } else {
        前面'n个条件'都不满足执行
      }
    
  2. 三元运算符
    是比“if双分支”更简单的写法,常用来取值
    语法:条件 ? 满足条件执行 : 不满足条件执行
      let a = 3;
      let b = 0;
      b = a < 5 ? a : 5; // 此时b的值等于a的值为3
    
  3. switch语句
    switch...case...语句一般用于等值判断,不适合于区间判断;
    switch...case...语句一般需要配合break关键字使用,没有break会造成case穿透。
      switch (数据) {
       // 找到与'数据'全等(===)的case值,并执行相应的代码,然后遇到break跳出switch语句,若没有遇到全等的case则会找到最后执行default中的代码
       // 若在找到了全等的case值,但是代码执行过程中没有遇到break关键字,则代码执行完之后会继续往下执行,直到遇到break或switch语句的结尾(case穿透)
       case1:
         满足值1执行的代码
         break
       case2:
         满足值2执行的代码
         break
       ...
       case 值n:
         满足值n执行的代码
         break
       default:
         不符合上面所有值的默认执行代码
         break
      }
    
  4. if和switch
    • 共同点
      • 都能实现多分支选择,实现多选一;
      • 大部分情况下可以互换。
    • 区别
      • switch...case...语句通常处理case为比较确定值的情况,而if...else...语句更加灵活,通常用于范围判断;
      • switch语句进行判断后直接执行到程序的语句,效率更高,而if语句有几种判断条件就得判断多少次;
      • switch判断时一定是全等(===),且需要注意配合break避免case穿透。
    • 当分支比较少时,if...else语句执行效率更高;分支较多时,switch语句执行效率更高,且结构更清晰。

二、循环语句

循环本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。
循环三要素:变量起始值,变量变化量,终止条件(没有终止条件循环会一直执行,造成死循环)

  1. while循环
    在满足条件期间,重复执行某些代码,直到不再满足条件。
      while (条件) {
        要重复执行的代码(循环体)
      }
      // 重复输出10个javascript
      // 起始值为1
      let i = 1; 
      // 终止条件,当'i'满足'i <= 10'时,执行循环体,当'i > 10'时(终止条件)结束循环。 
      while (i <= 10) {  
        document.write('Javascript');
        i++;  // 变量变化量,每执行一次'i'就自增一
      }
    
  2. for循环
    在for循环中,一般情况下把声明起始值、循环条件、变化值写到一起,是最常用的循环方式。
      for (变量起始值; 循环条件; 变量变化量) {
        循环体
      }
      // for循环的执行顺序是:1.变量起始值 --> 2.循环条件判断 --> 3.满足执行循环体(不满足退出循环不再执行下一步) --> 4.变量变化 --> 重复步骤2、3、4
      // 重复输出10个javascript
      for (let i = 1; i<= 10; i++) { // 当'i > 10'时退出循环
        document.write('Javascript');
      }
      // 循环嵌套打印乘法表,形式为 i * j = m, 为
      for(let i = 1; i <= 9; i++) { // 行的值
        for (let j = 1; j <= i; j++) {  // 列的值
          document.write(j + 'x' + i + '=' + j * i + ' ');
        }
        document.write('<br>');
      }
    
  3. 循环退出
    • break:退出循环,不再执行循环;
    • continue:结束本次循环,继续执行下次循环。
  let i = 1, j = 1;
  // 使用while打印 10 以内的奇数
  while (i <= 10) {
    if (i % 2 === 0) {  // 如果能被2整除就执行
      i++;  // 变量变化
      continue;   // 跳出本次循环
    }
    console.log(i);
    i++;
  }   // 最后依次打印‘1,3,5,7,9’
  // 使用for打印 10 以内的奇数
  for (j; j <= 10; j++) {
    if (j % 2 === 0) {  // 如果能被2整除就执行
      continue;   // 跳出本次循环
    }
    console.log(j);
  }   // 最后依次打印‘1,3,5,7,9’
  
  while (true) {
    let m = parseInt(prompt('请输入一个比10大的3的倍数'));
    if (m > 10 && m % 3 === 0) {
      break;  // 输入正确结束整个循环,不再弹出输入框
    }
  }
  for (let n = 1; n<= 10; n++) {
    if (n === 7) {
      break;   // 当遇到7的时候结束循环
    }
    console.log(n)
  }   // 最后依次打印‘1,2,3,4,5, 6’

三、数组

数组(Array)是一种可以按顺序保存数据的数据类型(属于对象中的一种)。是有序的数据集合,可以使用一个变量管理多个数据,非常方便。

  1. 数组的声明
    • 使用字面量声明:let 数组名 = [数据1, 数据2, ..., 数据n]
    • 使用new Array构造函数声明:let 数组名 = new Array(数据1, 数据2, ..., 数据n)
  2. 数组使用
    • 数组中的每个数据都叫做数组元素;
    • 数组可以存储任意类型的数据;
    • 数组是有序的,每一个数据都有一个编号,也叫数组的下标或是索引号,从0开始,使用时按照数组名[下标]
    • 数组中数据的个数也就是数组的长度,可通过属性length获得。
  3. 操作数组
    • 修改某个元素:通过数组的下标给指定元素重新赋值
    • 新增元素:
      • 数组.push()将一个或多个元素添加到数组的末尾,并返回该数组的新长度;
      • 数组.unshift()将一个或多个元素添加到数组的开头,并返回该数组的新长度。
    • 删除元素
      • 数组.pop()删除末尾元素,并返回该元素的值;
      • 数组.shift()删除开头元素,并返回该数组的新长度;
      • 数组.splice(start, delCount)删除指定位置元素,参数start表示下标为start的开始删除(起始位置),delCount表示需要删除的元素个数。
        //  修改元素
        let arr = ['苹果', '菠萝', '梨'];
        console.log(arr[0]); // 输出:苹果
        arr[0] = '香蕉';  // 修改第一个元素
        console.log(arr[0]); // 输出:香蕉
      
        let arrA = ['red']
        // 末尾新增元素,数组.push()方法
        arrA.push('blue');
        arrA.push('yellow', 'green');
        console.log(arrA); // 输出:['red', 'blue', 'yellow', 'green']
        // 开头新增元素,数组.push()方法
        arrA.unshift('蓝');
        arrA.unshift('黄', '绿');
        console.log(arrA); // 输出:['黄', '绿', '蓝', 'red', 'blue', 'yellow', 'green']
      
        // 删除末尾元素,数组.pop()方法
        arrA.pop();
        console.log(arrA); // 输出:['黄', '绿', '蓝', 'red', 'blue', 'yellow']
        // 删除开头元素,数组.shift()方法
        arrA.shift();
        console.log(arrA); // 输出:['绿', '蓝', 'red', 'blue', 'yellow']
        // 删除指定位置元素,数组.splice()方法
        arrA.splice(2, 1);  // 从下标为2的元素开始删除1个元素
        console.log(arrA); // 输出:['绿', '蓝', 'blue', 'yellow']
      
  4. 遍历数组
    用for循环遍历数组
      let arr = [1, 2, 3, 4, '五', '六']
      for (let i = 0; i < arr.length; i++) {
        console.log(i);
      }
      //  求数组[1, 2, 1, 5, 8, 9, 4, 6]中的最大值
      let arrA = [1, 2, 1, 5, 8, 9, 4, 6];
      let max = arrA[0];  // 假设数组中最大的是数组中的第一个
      for (let i = 1; i < arrA.length; i++) { // 遍历数组
        if (max < arrA[i]) {
          max = arrA[i];  // 如果数组元素比max大则更新max值
        }
      }
      console.log(`最大值是:${max}`);
    
      // 冒泡排序:是一种简单的算法。一次比较两个相邻元素,得到的结果就按从小到大(从大到小)排列,直到最后两个数比较完成,称为一轮排序。
      //  一个长度为5的数组,需要经过四轮排序才能得到一个全部按从小到大(从大到小)排列的数组结果。
      // 对于数组arrA进行冒泡排序
      for (let i = 0; i < arrA.length - 1; i++) {  // 外层循环控制比较轮数,一共比较'arrA.length-1'轮
        for (let j = 0; j < arrA.length - 1 - i; j++) {  // 内层循环控制每一轮比较次数,每一轮比较'arrA.length-1-i'次(在一轮排序中,一次比较会将最大(小)的数放在末尾,所以下一轮比较次数将会少一)。
          if (arrA[j] > arrA[j + 1]) { // 如果前一个元素大于后一个元素,则交换位置
            let temp = arrA[j];
            arrA[j] = arrA[j + 1];
            arrA[j + 1] = temp;
          }
        }
      }
      console.log(arrA);  // 输出:[1, 1, 2, 4, 5, 6, 8, 9]
    

四、函数

函数(function)是被设置及为执行特定任务的代码块。函数可以把具有相同或相似逻辑的代码包裹起来,通过函数调用执行这些被包裹起来的代码逻辑,这样有利于精简代码方便复用。比如alert()、prompt()、console.log()都是一些封装好的js函数。

  1. 函数基本使用
    函数需要先使用function关键字声明,函数名之后需要小括号(),函数体需要用大括号{}包裹起来。在使用函数时,通过函数名()调用,可以一次声明多次调用。
    函数命名规范
    • 和变量命名基本一致;
    • 尽量小驼峰式命名法(如:getUser());
    • 前缀应该为动词;
    • 常用动词:can、has、is、get、set、load
    // 函数声明
    function 函数名() {
      函数体
    }
    // 函数调用,函数不调用自己不执行
    函数名()
    
  2. 函数的参数
    将需要传入的参数写在声明时函数名后面的括号中,需要几个参数写几个,参数之间用逗号隔开,function 函数名(参数1, 参数2, ..., 参数n)。调用函数时将实际的值写在调用时的括号中,函数名(参数值1, 参数值2, ..., 参数值n)
    • 在声明时写在括号里的参数称为形参(形式上的参数);
    • 在调用函数时写在括号里的称为实参(实际上的参数);
    • 形参可以理解为是函数内声明的变量,实参是给这个变量赋值;
    • 开发者尽量保存形参和实参个数一致;
    • alert('警告')、parseInt('5')本质上都是函数调用的传参;
    • 当用户不传入实参时,也可以在函数声明时给形参设置默认值function 函数名(参数 = 值)
    // 函数声明
    function 函数名(参数列表) {
      函数体(在函数体中使用参数列表中的参数)
    }
    function getSquare(num) {
      document.write(num * num);
    }
    function getSum(num1, num2) {
      document.write(num1 + num2);
    }
    function getSum1(num1 = 0, num2 = 0) {
      document.write(num1 + num2)
    }
    // 调用
    getSum(1, 2); // 输出:3
    getSum(); // 输出:NaN
    getSum1(); // 输出:0
    
  3. 函数返回值
    在有些情况下,需要在特定的情况使用函数处理值并得到一个结果,这种时候需要函数返回一个值。比如parseInt('5')的返回值是数字5。
    • 将需要返回的数据使用return关键字返回,return 数据
    • 在函数中,执行了return则会立即结束当前函数,后面的代码不再执行,所以返回的数据不要换行写。
    • 对于有返回值的某些函数,可以使用变量存放返回值。
    • 函数可以没有return返回值,这种情况默认返回值为undefined
      function getSum(num1, num2) {
        let sum =  num1 + num2;
      }
      function getSum1(num1 = 0, num2 = 0) {
        return
      }
      // 调用
      console.log(getSum(1, 2));  // 输出:undefined
      console.log(getSum1()); // 输出:undefined
    
  4. 作用域
    通常来说,一段程序代码中所用到的变量并不总是有效/可用的,而限定这个变量的可用性的代码范围就是这个变量的作用域。
    作用域的使用提高了程序逻辑的局部性,增强程序的可靠性,减少变量冲突。
    • 全局作用域:作用于所有代码执行的环境(整个script标签内部或独立的js文件),在此作用域下声明的变量叫做全局变量
    • 局部作用域(函数作用域):作用于函数内的代码环境,在此作用域下声明的变量叫做局部变量
    • 全局变量在全局(代码的任何位置)下都可以使用;全局作用域中无法访问到局部作用域中的变量。
    • 如果在函数内部不声明变量,直接赋值,也被看做全局变量,但强烈不推荐。
    • 函数的形参可以看作是局部变量。
    • 局部变量只能在函数内部使用,在局部作用域中可以访问到全局变量。
    • 在访问变量时按就近原则,从离得最近的一层作用域往上找。
  5. 匿名函数
    函数可分为具名函数(function 函数名() {})和匿名函数(function () {})。
    匿名函数无法直接使用,使用方式为:函数表达式,立即执行函数。
    • 函数表达式:将匿名函数赋值给一个变量,通过变量名进行调用,称为函数表达式。
    • 立即执行函数:避免全局变量的污染,形式(函数整体)(形参)
      // 函数表达式
      let fn = function () {
        函数体
      }
      fn(); // 调用函数,必须先声明后调用(具名函数可以在任意地方调用)
    
      // 立即执行函数
      // (立即执行函数中第一个小括号内也可以写具名函数)
      (function () {
        let num = 10
      })(); // 多个立即执行函数之间要用分号隔开
      (function () {
        let num = 20
      })();
    
  6. 函数注意点
    • 两个函数名相同的函数,后面的会覆盖前面的;
    • 在JS中,实参的个数和形参可以不一样,按顺序依次给形参传值。多余的实参不参与运算,多余的形参自动填充为undefined
    • 函数的结束用returnbreak无法结束函数,可以结束循环和switch。

五、逻辑中断

逻辑中断就是逻辑运算符中的短路,只存在于&&||中,当满足一定条件时,右边的代码不执行。

  • &&的左边为false就短路,即右边的不再执行;
  • ||的左边为true就短路,即右边的不再执行;
  • 无论是&&还是||,运算结果都是最后被执行的表达式,如console.log(2 && 1)输出1console.log(2 || 1)输出2

六、转换为布尔型

  1. 显式转换
    • Boolean(需转换的值)空字符串('')、0、undefined、null、false、NaN转换为布尔型后都为false,其余为true
  2. 隐式转换
    • 有字符串的加法,'' + 1的结果是'1'
    • 减法(只能用于数字),会使空字符串''转换为0
    • null经过数字转换后变为0
    • undefined经过数字转换后变为NaN

七、对象

对象(object)也是Javascript中的数据类型。可以理解为使一种无序的数据集合,可详细地描述某个事物。对象中的值有属性和方法两种,以键值对的形式(属性名: 属性值方法名: 函数)存在,多个键值对中间用逗号隔开。

  1. 对象的声明
      // 方法一(常用)
      let 对象名 = {};
      let 对象名 = {
        属性名: 方法,
        方法名: 函数
      }// 方法二
      let 对象名 = new Object();
    
  2. 对象的属性
    数据描述性的信息称为属性,如人的姓名、身高、年龄等,一般是名词性的。
    • 属性都是成对出现的,包括属性名和属性值,中间用英文冒号(:)隔开,多个属性之间用英文逗号隔开(,)。
    • 属性就是依附在对象上的变量(外面是变量,对象内是属性)。
    • 属性名可以使用引号""、'',一般情况下可省略,除非遇到特殊符号如空格、中横线等。
  3. 对象的操作
    • 访问对象:通过对象名.属性名对象名['属性名']访问对象;
    • 修改对象属性值:通过对象名.属性名 = 新值即可修改;
    • 新增对象属性值:通过对象名.新属性名 = 值即可新增;
    • 删除属性:通过delete 对象名.属性名即可删除
      // 声明一个对象
      let user = {
        username: '张三',
        age: '18'
      }
      console.log(user);  // 输出:{username: '张三', age: '18'}
      // 访问对象
      // “对象名.属性名”的属性名不加引号
      // “对象名['属性名']”中的属性名必须加引号,单双引号都可以
      console.log(user.username)  // 输出:张三
      console.log(user['age'])  // 输出:18
      // 修改属性,访问属性并重新赋值
      user.name = '李四';
      console.log(user) // 输出:{username: '李四', age: '18'}
      // 新增属性,和修改一样,只要被赋值的属性名在原来的对象中不存在,则会新增一个新属性
      user.gender = '男';
      console.log(user) // 输出:{username: '李四', age: '18', gender: '男'}
      // 删除属性
      delete user.age;
      console.log(user);  // 输出:{username: '李四', gender: '男'}
    
  4. 对象的方法
    数据行为性的信息称为方法,一般是动词性的,其本质是函数。
    • 对象中的方法由方法名和函数构成,中间用英文冒号(:)隔开。
    • 方法是依附在对象中的函数。
    • 方法名可以使用引号""、'',一般情况下可省略,除非遇到特殊符号如空格、中横线等。
      let obj = {
        uname: '张三',
        printSum: function (num1, num2) {
          console.log(num1 + num2)
        }
      }
      // 调用对象的方法:对象名.方法名()
      obj.printSum(20, 30); // 输出:50
    
  5. 遍历对象
    对象没有像数组一样的length属性,它的长度是无法确定的,对象里面是无序的键值对,没有像数组一样的下标,无法像数组那样使用for循环遍历。
    • 遍历对象使用for (变量名 in 对象)。这种方法也可以遍历数组,但不推荐。
    • for (变量名 in 对象)中的变量在循环过程中依次代表对象的属性名。
    • 由于是使用变量代表属性名,所以必须使用对象名[变量名]获得对象的属性值。
      let user = {
        username: '张三',
        age: '18',
        gender: '男',
      }
      // 遍历对象
      for (let key in user) {
        console.log(key)  // 依次输出:username、age、gender
        // 由于使用key是变量,所以要用方括号访问属性
        console.log(user[key])  // 依次输出:'张三'、'18'、'男'
        console.log(user.key)  // 依次输出:undefined、undefined、undefined;
      }
    
  6. 内置对象
    JavaScript内部提供的对象,包含各种属性和方法给开发者调用。如document.write(),console.log()
    常用内置对象 —— 数学对象(Math),拥有一些数学常数属性和数学函数方法。
      // Math中的一些属性
      console.log(Math.PI); // 圆周率,3.141592653589793
      console.log(Math.E); // 欧拉常数,也是自然对数的底数,2.718281828459045
      // Math中的一些方法
      console.log(Math.random()); // 生成一个 0 到 1 之间的随机数(包括 0 不包括 1)
      console.log(Math.ceil(1.1)); // 向上取整,2
      console.log(Math.floor(1.9)); // 向下取整,1
      console.log(Math.round(1.5)); // 四舍五入,2
      console.log(Math.abs(-1)); // 绝对值,1
      console.log(Math.max(1, 2, 3)); // 最大值,3
      console.log(Math.min(1, 2, 3)); // 最小值,1
      console.log(Math.pow(2, 3)); // 幂运算,8
      console.log(Math.sqrt(4)); // 开平方,2
    
      // 使用 Math.random() 生成一定范围内的随机数
      // 生成 m 到 n 之间的随机数
      Math.floor(Math.random() * (n - m + 1) + m);
      // 生成一个 1 到 10 之间的随机数
      console.log(Math.floor(Math.random() * 10) + 1);
      // 生成一个 5 到 10 之间的随机数
      console.log(Math.floor(Math.random() * 6) + 5);
    

八、基本数据类型和引用数据类型

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

  • 值类型:简单/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型。如:string、number、boolean、undefined、null
  • 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型。通过new关键字创建的对象(系统对象、自定义对象)都是引用数据类型,如Object、Array、Date等。
  1. 堆栈空间分配区别
  • 栈:由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。简单数据类型存放到栈里面。
  • 堆:存储复杂数据类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。引用数据类型存放到堆里面。
  1. 复杂类型的地址分配
  • 引用类型(复杂数据类型):通过new关键字创建的对象(系统对象、自定义对象)都是引用数据类型,如Object、Array、Date等。
  • 引用数据变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中。
  // 简单数据类型,直接存放值
  let num1 = 10; 
  let num2 = num1; // 将num1的值赋值给了num2,此时num1和num2的值是相同的
  num2 = 20;  // num1和num2的值各自存放在一个独立的空间,修改时互不影响。
  console.log(num1, num2);  // 输出:10 20
  
  // 复杂数据类型,存放地址
  let obj1 = {age: 18};
  let obj2 = obj1;  // 将obj1的地址赋值给了obj2,所以此时obj1和obj2存的地址是一样的
  obj2.age = 20;
  // 由于obj1和obj2存的地址是一样,所以指向的堆中的实例对象是同一个
  // 当通过obj2对实例对象进行修改后,obj1再次指向对象实例时是同一个经过修改的结果
  console.log(obj1.age, obj2.age)  // 输出:20 20
  • 26
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值