js基础知识

154 阅读9分钟
1.5-undefined与null区别
  • undefined : 未定义。 当变量只声明,但是没有赋值。此时默认值是undefined
  • null : 有定义。 定义的值是空值。
  • 相同点 : (1)值相等 (2)转布尔类型都是false
  • 不同点 : (1)数据类型不同 (2)转number类型值不同
逻辑非(!)

逻辑非操作符会遵循如下规则:

  • 如果操作数是对象,则返回false
  • 如果操作数是空字符串,则返回true
  • 如果操作数是非空字符串,则返回false
  • 如果操作数是数值0,则返回true
  • 如果操作数是非0数值,则返回false
  • 如果操作数是null,则返回true
  • 如果操作数是NaN,则返回true
  • 如果操作数是undefined,则返回true
console.log(!false);   // true
console.log(!"blue");  // false
console.log(!0);       // true
console.log(!NaN);     // true
console.log(!"");      // true
console.log(!12345);   // false
复制代码

拓展 逻辑非操作符可以用于把任意值转换为布尔值。同时使用两个叹号(!!),相当于调用了转型函数Boolean()。

console.log(!!"blue"); // true
console.log(!!0);      // false
console.log(!!NaN);    // false
console.log(!!"");     // false
console.log(!!12345);  // true
复制代码
逻辑与(&&)
  1. 如果&&两边的操作数都是布尔值,则只有两个值都为true的时候才返回true,其余情况都返回false
  2. 如果有操作数不是布尔值,则逻辑与并不一定返回布尔值,而是遵循如下规则:
  • 如果第一个操作数是对象,则返回第二个操作数
  • 如果第二个操作数是对象,则只有第一个操作数求值为true才会返回该对象
  • 如果两个操作数都是对象,则返回第二个操作数
  • 如果有一个操作数是null,则返回null
  • 如果有一个操作数是NaN,则返回NaN
  • 如果有一个操作数是undefined,则返回undefined

逻辑与操作符是一种短路操作符,对逻辑与操作符来说,如果第一个操作数是false,那么无论第二个操作数是什么值,结果也不可能等于true。

逻辑或(||)
  1. 如果||两边的操作数都是布尔值,则只有两个值都为false的时候才返回false,其余情况都返回true
  2. 如果有操作数不是布尔值,则逻辑与并不一定返回布尔值,而是遵循如下规则:
  • 如果第一个操作数是对象,则返回第一个操作数
  • 如果第一个操作数求值为false,则返回第二个操作数
  • 如果两个操作数都是对象,则返回第一个操作数
  • 如果有一个操作数是null,则返回null
  • 如果有一个操作数是NaN,则返回NaN
  • 如果有一个操作数是undefined,则返回undefined

逻辑或操作符也具有短路的特性。只不过对逻辑或而言,第一个操作数求值为true,第二个操作数就不会再被求值了。

流程控制-分支语句

1.1-语句与表达式

简单概括: 有运算符参与的就是表达式,没有运算符参与的就是语句

  • 1.表达式 : 由运算符组成的式子, 一定会有运算结果 (运算)
  • 2.语句 : 让js编译器执行某个命令,做什么事情 (执行)
  • 3.分支语句 循环语句
1.2-if单分支结构
  1. if结构语法:if(条件 true/false){ 条件成立时需要执行的代码 }
  2. if结构补充说明:
  • (1).大括号中可以是任何代码,不限数量
  • (2).如果大括号中代码有且只有一行,则可以省略大括号。这种写法代码不规范,不是老司机的作风

3.注意点:小括号中的条件可以是哪些呢

  • (1)关系表达式:结果一定是布尔类型
  • (2)布尔类型的值:true和false
  • (3)其他表达式和值:都会先转换成布尔类型再判断真和假
1.3-if-else if-else多分支结构
        语法
                if(条件1){
                    条件1成立时需要执行的代码
                }else if(条件2){
                    条件2成立时需要执行的代码
                }else if(条件3){
                    条件2成立时需要执行的代码
                }
                .....
                else{
                    如果前面所有条件都不满足,则执行else代码
                }
注意点
    (1)多分支所有的大括号代码最多只会执行一个,只有当前面的条件不满足,才会进入后面的条件判断
    (2)多分支一定要以if开头,后面else if可以多个,结尾else可以省略 -->
1.-4三元表达式
         三元运算符语法
                * 三元运算符: `?:`
                * 三元表达式:`表达式?代码1:代码2`
                  * 1.如果表达式成立则执行代码1,否则执行代码2
               //如果代码1 和 代码2 不能产生结果,则三元表达式的结果是undefined
               let res = 1 > 0 ? alert("哈哈") : alert("呵呵");
               let res = 1 > 0 ? alert("哈哈") : let res = 1 > 10 ? alert("1") : alert("2")
               console.log(res); //undefined
1.5-switch-case分支结构(固定值)
      let subject = +prompt(
        '请输入您想要选择的学科 1-前端  2-java 3-UI 4-新媒体'
      )
      switch(表达式){
        case1:
            表达式的结果 === 值1,需要执行的代码
            break;
        case2:
            表达式的结果 === 值2,需要执行的代码
            break;
        case3:
            表达式的结果 === 值3,需要执行的代码
            break;
        .......
        default:
            表达式的结果和上面所有的case后面的值都不全等,则会执行这里的代码
            break;
    }
     注意事项
     * 1.表达式的结果要和值一定是全等的关系===
     * 2.break作用:结束该switch语句,所以一般情况下要加上,如果不加上则会发生穿透
     * 穿透:从上一个case代码快执行到下一个case代码快
     * break关键字的作用就是防止穿透
     * 3.default语句可以写在任何地方,也可以省略,但是一般写在最后,这是一种代码规范

流程控制-循环语句

1.1-while 循环
     循环结构:代码重复执行

    while循环语法 
    while( 条件 true/false ){
        循环体:需要重复执行的代码
    }

   执行规则
    1.判断条件是否成立
        1.1 true : 则执行循环体代码
        1.2 false : 循环结束,执行大括号后面的代码
    2.重复步骤1
    //例子
    //1.声明变量记录循环次数(循环变量)
     let num = 1;
    //2.循环条件
    while (num <= 10) {
    console.log("班长爱坤哥")
     //3.循环变量自增
    num++;
    }

     console.log("班长完事了") 
1.2-for 循环
      for循环: 1.声明循环变量  2.循环条件  3.循环变量自增 写在一个小括号中,代码更加简洁易读
     语法:
         for(语句1;语句2;语句3){
             循环体:需要重复执行的代码
         }
     
     执行规则
         1. 执行语句1(声明循环变量)
         2. 判断语句2结果是否成立(循环条件)
             2.1 true : 执行循环体
                 * 2.1.1 执行语句3(循环变量自增)
             2.2 false: 循环结束,执行大括号后面的代码
         3. 重复步骤2 
1.3-break 与 continue 关键字
  continue : 结束本次循环体,立即进入下一次循环判断
  * continue关键字只能用于循环语句
  break: 结束整个循环语句,立即执行大括号后面的代码
   * break关键字可以用于 循环语句 + switch-case 

数组

1:数组的语法
  • 1-1数组名 let arr=[]声明
  • 1-2数组元素 元素1,元素2,[]里面的是元素
  • 1-3数组取值 数组名[下标]
  • 1-4数组长度 arr.length
  • 1-5数组遍历 for (let i=0;i<arr.length;i++){ arr[i] }
2:数组查询
  • 数组取值(查) 数组名[下标]
  • 数组取值
  • 如果下标存在,则获取 元素值
  • 如果下标不存在,则获取 undefined
3:数组修改
  • 数组赋值(改) 数组名[下标] = 值
  • 数组赋值 // arr[0] = 70修改第一个元素为70
  • 如果声明时没有 5,而arr[5]=70,,则新增一个元素
4:数组新增
  • 数组新增有两个方法
  • 数组名.push(元素) : 一个或多个元素,添加到末尾
  • 数组名.unshift(元素) : 一个或多个元素,添加到开头
5:数组删除
  • 数组的删除
  • (1)数组名.pop:删除最后面一个元素
  • (2)数组名.shift:删除最前面一个元素
  • (3)数组名.splice(下标,数量):从'下标'开始删除'数量'个元素
6.数组应用
6-1数组求和
  (1)声明一个变量存储结果
  (2)遍历数组中每一个元素
  (3)累加
  
  function getsum(arr1) {
    let sum1 = 0
    for (let i = 0; i < arr1.length; i++) {
        sum1 += arr1[i]
    }
    
6.2-求数组最大元素与最小元素
  (1).声明变量默认为第一个元素
  (2).遍历数组
  (3).依次比较大小,然后赋值
  
   function getsum(arr) {
    let sum = arr[0]
    for (let i = 1; i < arr.length; i++) {
        if (sum < arr[i]) {
            sum = arr[i]
        }
    }
    return sum
}
let sum1 = getsum([1, 2, 12, 23, 34, 5, 6])
console.log(sum1)

6.3-筛选数组
  (1).声明空数组
  (2)遍历旧数组,找出符合条件的数
  (3).添加到新数组中
  
      let arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
      let newArr = [];
      for (let i = 0; i < arr.length; i++) {
        if (arr[i] !== 0) {
          newArr.push(arr[i]);
        }
      }

函数

1.函数的介绍

函数是一个封箱的代码块,复用时调用即可 function 函数名(){函数体}

1-1.声明函数:

      声明函数只是把代码存起来,不会执行函数体
     // function 函数名() { 
     // 函数体代码: 需要存储的一段代码 
     // }

1-2.调用函数 : 执行函数体代码

函数名()

2.传参
  • 函数名(形参){函数体}
  • 函数名(实参)
  • 实参相形参传数据
3.逻辑中断
  • 逻辑或|| 一真则真 找真,左边式子为true,得到左边式子的值,同理右边
  • 逻辑与&& 一假则假 找假,左边式子为false,得到左边式子的值,同理右边
4.返回值

return返回函数里面的数据给调用者

  • (1)return是结束函数的
  • (2)return可以不给,默认值是undefined
  • (3)return可以给但不赋值,则返回值也是undefined
5.函数工作原理
  • (1)传参,实参给形参赋值的过程,调用者->函数
  • (2)函数操作函数体
  • (3)return返回值给调用者
6.开关思路
  • (1)声明一个开关变量(一般默认为true)
  • (2)遍历数组,判断每一个元素是否满足条件,遇到不满足修改开关 变量为false
         遇到满足的不用修改,因为默认就是true 
         变量值 function isAllTrue(arr){ 
         let res = true
           for(let i = 0;i< arr.length;i++){
              if( arr[i] < 0){
              res = false break
              }
           }
            return res
         } 
7.作用域
  1.js变量作用域: 变量可以使用的区域
  作用:避免变量污染(变量名相同导致代码冲突) s三种作用域
  
  2.1 全局作用域(全局变量) : 在函数外面let的变量 
  2.2 局部作用域(局部变量) : 在函数里面let的变量
  2.3 快级作用域(快级变量) : 在分支或循环大括号中let的变量 
  
  3.作用域链(就近原则,先在自己域里面的,没有就找上一级)
  
  let num = 10//0级
   function fn1(){//fn1本身还是0级的,只是里面函数体是1级
       //1级
       let num = 20
       console.log(num)//20

       function fn2(){
           //2级
           let num = 30
           console.log(num)//30
       }    
       fn2()
   }

   fn1()
   console.log( num )//10 -->
8.匿名函数
  • 1.匿名函数 : 没有函数名的函数
  • 2.匿名函数作用 : 开辟局部作用域,避免全局变量污染
  • 3.小细节: 匿名函数自执行的时候,上一个语句分号不能省略
         ;(function(){ 
            let num = 10//局部变量
            console.log('111') 
            })() 

对象

1.对象介绍
  • 1.对象是什么 : 对象是一种复杂数据类型
  • 2.对象作用 :以键值对方式存储多个数据
  • 3.对象与数组异同点
    • 相同点:都是复杂数据类型,都可以存储多个数据
    • 不同点: 存储方式不同 数组: 有序存储 对象: 无序存储(键值对)
2.对象语法
    1. 声明对象 let 对象名{属性名:属性值,}
    1. 取值语法 log(对象名.属性名)

注意点:对象中的属性值是什么数据类型, 取出来的时候就可以使用这个类型的所有语法

3.对象操作
  • 1.查询属性:
       查询对象属性两种语法
            点语法       obj.属性名
             []语法       obj['属性名']    obj[ 变量名 ]
            注意点:  如果[]里面有'',则解析是属性名
                   如果[]里面没有'',则解析是变量名
       查询对象特点 
            如果属性名存在,则获取属性值 
            如果属性名不存在,则获取undefined 
  • 2.修改 新增(赋值)属性:
        对象名.属性名   = 值
            对象名['属性名'] = 值(两种写法一样)
           注意点:(1)如果已经存在的属性赋值,则是修改
                    (2)如果不存在的属性赋值,则是新增
  • 3.删除对象属性

    delete 对象名.属性名

4.对象遍历
    遍历对象 : 
    特殊的for-in循环  (专用于遍历对象)
      for(let key in 对象名){
        对象名[key]
      } 
5. 引用类型 与 值类型 区别
   1.值类型(简单数据类型) : string number boolean undefined null
     栈中存储数据,赋值拷贝的也是数据,修改拷贝后的数据对原数据‘没有影响’
     let 只能在栈里开辟空间

   2.引用类型(复杂数据类型) : array function object
      [],function,{}可以开辟堆空间
      栈中存储地址,数据存在堆中。赋值拷贝的是地址,修改拷贝后的数据对元素‘有影响’
      在比较时,比较的是地址,而不是数值
      [1,2,3]==[1,2,3] false
      [1,2,3][1]==[1,2,3][1] true 

js高级复习

原型对象

1.面向对象

  • 面向对象:是一种只注重结果的思维方式
  • 面向过程:注重过程
  • 两者的关系:面向对象的本质是面向过程的一种封装

2.内置对象

1.内置对象api
  • 内置对象api : js作者写好的对象的一些方法
  • 内置对象 : js作者提前写好的对象,直接拿来使用即可
  • api : 是预先定义的函数

2.array对象

3.string对象

4.原型对象

  • 概念:当我们创建函数的时候,系统会自动帮你创建一个与之对应的对象,称之为原型对象
  • 作用:解决变量污染,但是这个对象本身也会造成污染

5.原型对象关系

prototype : 属于构造函数,指向原型对象

  • 作用:解决内存浪费+变量污染

proto : 属于实例对象,指向原型对象

  • 作用: 实例对象 访问 原型对象的成员

constructor : 属于原型对象,指向构造函数

  • 作用: 可以让实例对象知道自己是被谁创建的
      (1) 构造函数
         function person(name,age){
         this.name=name
         this.age=age
         }
         
      (2)原型对象
       person.prototype=function(){
       this.eat=eat
       }
      
      (3)实例对象
       let p1=new person(name,age)
       let p2=new person(name,age) 
     
       //检测构造函数、原型对象、实例对象三者之间关系: 两行代码
       console.log(p1.__proto__.constructor === Person)
        //true (你爹是你爹,你妈的老公是你爹)
       console.log(p1.__proto__ === Person.prototype) 
       //true (你妈是你妈)

   (4) 静态与实例成员
       静态成员:属于函数的成员
       实例成员:属于实例对象的成员
       获取对象所有的属性值:
       Object.value(对象名)
       let obj={}
       Object.value(obj)
       Object.key(obj) 

5. 对各种条件使用逻辑运算符

如果你想减少嵌套 if…else 或 switch case,你可以简单地使用基本的逻辑运算符AND/OR

function doSomething(arg1){ 
    arg1 = arg1 || 10; 
// 如果尚未设置,则将 arg1 设置为 10 作为默认值
return arg1;
}

let foo = 10;  
foo === 10 && doSomething(); 
// is the same thing as if (foo == 10) then doSomething();
// 输出: 10

foo === 5 || doSomething();
// is the same thing as if (foo != 5) then doSomething();
// 输出: 10
复制代码