Cherish's Notebook
切换到深色模式
菜单
Wiki--浏览次数--访问次数--跳出率--平均停留

JS学习

三件套第三套学习

2.基础语法

2.1 js的使用基本介绍

2.1.1 js组成

  1. js是编程语言,html和css不是编程语言,是标记语言

js组成:ECMAScript(JavaScript语言基础)和Web APIs(由DOM页面文档对象模型和BOM浏览器对象模型)

  1. JavaScript 程序不能独立运行,它需要被嵌入 HTML 中,然后浏览器才能执行 JavaScript 代码

2.1.2 js书写位置

  1. 内部 JavaScript

  1. 外部 JavaScript

  1. 内联 JavaScript

2.1.3 JavaScript注释

alt+shift+a一定要记住!

2.1.4 JavaScript结束符

21.1.5 JavaScript 输入输出语法

  1. 输出语法:

①document.write('要出的内容')

向body内输出内容;

如果输出的内容写的是标签,也会被解析cheng

②alert('要出的内容')

页面弹出警告对话框

③console.log('控制台打印')

控制台输出语法,程序员调试使用

输入log就行,自动生成:

  1. 输入语法:

21.1.6 字面量

在计算机科学中,字面量(literal)是在计算机中描述 事/物

例如:18 是一个数字字面量;'pink' 是一个字符串字面量

2.2 变量

  1. 变量声明

let 变量名

  • 声明变量有两部分组成:声明关键字 变量名(也叫标识符)
  • let 即关键字 (let: 允许、许可、让、要),所谓关键字是系统提供的专门用来声明(定义)变量的词语
  1. 变量赋值
CODE
let age
age=18
  1. 连这些(变量的初始化):let age=18
  2. 更新变量

  1. 声明多个变量

  1. 变量命名规则与规范

遵守小驼峰!

  1. 变量拓展-let和var的区别

2.3 数组

CODE
let arr = []

2.4 常量

const — 类似于 let ,但是变量的值无法被修改

2.5 数据类型

  1. js是一门弱数据类型的语言,只要是数字就是数字型语言
  2. 算数运算符:

  1. 数字类型(Number)

JavaScript 中的正数、负数、小数等 统一称为 数字类型

  1. 字符串类型(string)

反引号也是可以使用的

➕:数字相加,字符相连,只要有字符串就可以与其他进行相加

例如:document.write("我今年"+age+"岁")

  1. 模板字符串

类似于python的字符串格式化

  1. 布尔类型

true 和 false

  1. 未定义类型(underfined)

表示没有赋值

未定义类型是比较特殊的类型,只有一个值undefined

只声明变量,不赋值的情况下,变量的默认值为 undefined,一般很少【直接】为某个变量赋值为 undefined

  1. null(空类型)

JavaScript 中的 null 仅仅是一个代表“无”、“空”或“值未知”的特殊值

赋值了,但是内容为空

CODE
typeof null
输出的是'object',是一个对象数据类型
  1. 控制台检测数据类型

  1. 类型转换

prompt输入的内容都是字符串字面量,还有html时的表单(input啥的输入的也是字符串字面量)

转换方式:隐式转换和显示转换

①隐式转换

  • 号两边只要有一个是字符串,都会把另外一个转成字符串
  • 除了+以外的算术运算符 比如 - * / 等都会把数据转成数字类型(只要有数字就会把另一个转化成数字字面变量)
  • 加号作为正号解析可以转换成数字型:console.log(+'123')不再是字符串类型,是数字类型为123
  • 任何数据和字符串相加结果都是字符串

②显示转换

在输入的时候要用好隐式转换,简单写起来

let num = +prompt(’请输入数字:‘)

  parseInt与parseFloat是只取前边的数字,如果前边有字母,是无法进行识别后边的数字的,会显示NaN,表示错误

console.log(parseInt('12.333px'))

输出为:12

console.log(parseInt('a'a'a12.333px'))

输出:NaN

2.6 运算符

2.6.1 赋值运算符

2.6.2 一元运算符

众多的 JavaScript 的运算符可以根据所需表达式的个数,分为一元运算符、二元运算符、三元运算符,就看需要几个数来操作,例如+需要两个数才能相加,所以叫做二元运算符,正负号的话就是一元运算符

两者的区别:

前置先自加;后置后加,代码执行完之后再加

2.6.3 比较运算符

比较运算符也有隐式转换

console.log(2 == '2')输出为true,只判断值,==含有隐式转换,前边是数字字面量的情况下,会将字符串转化为数字字面量

console.log(2==='2')输出false,===全等,会判断值和数据类型,需要全部一样才为true

要使用三等,开发的时候

NaN不等于任何人,包括它自己

小数在进行运算的时候它会先把自己转化为整数,然后最后再除以放大的数变回原来:例如:0.5+0.2:它是0.5*10+0.2*10=7

7/10=0.7

最后:0.5+0.2=0.7

字符串比较,比较的是字符对应的ASCII码

2.6.4 逻辑运算符

上述题目选D

与真2假1;或真1假2

2.6.5 运算符优先级

先算逻辑与,后算逻辑或

2.7 语句

表达式:是可以被求值的代码,会有结果给我们

语句:语句是可以被执行的代码,例如prompt()

因为表达式可被求值,所以它可以写在赋值语句的右侧。

而语句不一定有值,所以比如 alert() for和break 等语句就不能被用于赋值。

2.7.1 分支语句

2.7.1.1 if分支语句

if语句单行简单的话,可以不写{},写在一行就行

  1. 单分支语句

除了0,所有数字都为真

CODE
if(0) {
    let a=1
    alert(typeof a)
}
不输出,括号为假
  1. 双分支语句

  1. 多分支语句

2.7.1.2 三元运算符

2.7.1.3 switch语句

如果不写break,在匹配成功之后,输出完这个匹配内容后,switch语句就失效了,他会把后边的内容也全部输出

2.7.2 循环语句

2.7.2.1 断点演示

2.7.2.2 while循环

2.7.2.3 for循环

for(;;) {

}

表示无限循环

2.7.2.4 循环的退出

2.8 数组

2.8.1 基础认识

2.8.2 操作数组

  1. 添加元素

console.log(arr.push('green'))

输出结果:为新数组的长度

push用的非常多,一定要记住

  1. 删除元素

2.8.3 根据数据生成柱形图

CODE
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .box {
            display: flex;
            width: 700px;
            height: 300px;
            border-left: 1px solid pink;
            border-bottom: 1px solid pink;
            margin: 50px auto;
            justify-content: space-around;
            align-items: flex-end;
            text-align: center;
        }

        .box>div {
            display: flex;
            width: 50px;
            background-color: pink;
            flex-direction: column;
            justify-content: space-between;
        }

        .box div span {

            margin-top: -20px;
        }

        .box div h4 {
            margin-bottom: -35px;
            width: 70px;
            margin-left: -10px;
        }
    </style>
</head>

<body>

    <script>
        // 1. 四次弹框效果
        // 声明一个新的数组
        let arr = []
        for (let i = 1; i <= 4; i++) {
            // let num = prompt(`请输入第${i}季度的数据:`)
            // arr.push(num)
            arr.push(prompt(`请输入第${i}季度的数据:`))
            // push记得加小括号,不是等号赋值的形式
        }
        // console.log(arr)  ['123','135','345','234']
        // 盒子开头
        document.write(` <div class="box">`)

        // 盒子中间 利用循环的形式  跟数组有关系
        for (let i = 0; i < arr.length; i++) {
            document.write(`
              <div style="height: ${arr[i]}px;">
                <span>${arr[i]}</span>
                <h4>第${i + 1}季度</h4>
              </div>          
            `)
        }
        // 盒子结尾
        document.write(` </div>`)
    </script>
</body>

</html>

2.8.4 冒泡排序

CODE
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    let arr = [5, 4, 3, 2, 1]
    for (let i = 0; i < arr.length - 1; i++) {
      for (let j = 0; j < arr.length - i - 1; j++) {
        // 开始交换,但是前提 第一个数大于第二个数才会进行交换
        if (arr[j] > arr[j + 1]) {
          // 交换两个变量
          let tmp = arr[j]
          arr[j] = arr[j + 1]
          arr[j + 1] = tmp
        }
      }
    }
    document.write(arr)
  </script>
</body>

</html>

实际开发中我们使用的是函数:sort(),默认按照升序

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

// 1.升序排列写法

arr.sort(function (a, b) {

return a - b

})

console.log(arr) // [1, 2, 3, 4, 5]

// 降序排列写法

arr.sort(function (a, b) {

return b - a

})

console.log(arr) // [5, 4, 3, 2, 1]

2.9 函数

()是调用的意思,为了区分哪个函数,所以前边加上函数名,因此函数的调用:函数名()

函数的声明用function

函数里边可以嵌套函数

2.9.1 函数传参

  • 形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
  • 实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
  • 形参可以理解为是在这个函数内声明的变量(比如 num1 = 10)实参可以理解为是给这个变量赋值
  • 开发中尽量保持形参和实参个数一致
  • 我们曾经使用过的 alert('打印'), parseInt('11'), Number('11') 本质上都是函数调用的传参
  • 形参只在函数中有用,所以不需要进行声明这个变量

可以给形参初始值,此时函数调用的时候,不放实参这个函数也可以使用,不会报错;默认值只会在缺少实参参数传递时 才会被执行,所以有参数会优先执行传递过来的实参, 否则默认为undefined

2.9.2 函数的返回值

  • 在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用
  • return 后面代码不会再被执行,会立即结束当前函数,所以 return 后面的数据不要换行写,return要写在函数的最下边
  • return函数可以没有 return,这种情况函数默认返回值为 undefined
  • 返回多个值时使用数组,让它返回数组,就能将多个值返回
  • 断点调试:进入函数内部看执行过程F11

2.9.3 参数个数不同情况

CODE
    function fn(a, b) {
      console.log(a + b);
    }
    fn(1, 2, 3)输出3,最后一个参数没人接,不要
    fn(1)输出NaN,第二个值undefined,1+undefined=NaN,计算错误

2.9.4 作用域

  • 一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的 作用域
  • 作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突
  • 分为全局作用域和局部作用域;全局作用域的变量叫作全局变量,局部作用域的变量叫作局部变量,也称为函数作用域,函数内部有效
  • 函数内部可以直接所使用全局变量
  • 如果函数内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐,但是需要先调用函数才可以输出函数内部的变量

例如:

CODE
    function fun() {
      num = 10
    }
    fun()
    console.log(num)
   会输出10,如果不调用函数,直接就报错,尽量不要用这种方法,如果此时我在函数的上方写了
   let num=20,则num的值会被覆盖,这样值就乱了,这样是不对的!
  • 函数内部的形参可以看做是局部变量
  • 不同作用域变量可以重名;相同作用域变量不可以重名

变量访问原则: 在能够访问到的情况下 先局部, 局部没有在找全局

2.9.5 匿名函数

函数可以分为具名函数和匿名函数

匿名函数是指没有名字的函数,它是无法直接使用的,使用的两种方式:

  1. 函数表达式

里边也可以写参数

具名函数调用位置可以随意调整;

匿名函数函数表达式形式只能在声明后才可以使用

  1. 立即执行函数

直接执行函数,不需要再调用!!!本质它已经调用了

写法:两个小括号,然后在第一个小括号中写function

(function () {})();

不要落下最后的;

立即执行函数必须要加;

分号写前写后都没问题

写前:

(function() {})()

;(function () {})();

写后:

(function() {})();

(function () {})();

可以这样理解:最后一个小括号实质是调用前边的函数,为了保证前边的函数正常进行又给其套了一层括号,最后括号里边的数为实参,function后面的参数为形参

还有一种写法:

(function(){}());

或者:

!function(){}();

立即执行函数有时候也是可以加名字的:

(function flexible(window,document) {}(window,document));

省一些调用方法

2.9.6 逻辑中断!!!

这样就不用非得给x,y初始化了

代码执行时先看左边

例如:console.log(false && 3+5)

&&逻辑与遇假则假,当执行左边为假时就不执行右边了,所以输出false

&&都是真时,就返回最后一个真值

console.log(11 && 22)

输出22

逻辑与:遇真则真

例如:

let age=1

console.log(11 || age++)

不执行后边的age++,先执行左边11为真,就是真,就直接结束语句了,输出11

console.log(11 || 22)

||逻辑或遇到真就直接输出,输出结果为11

||如果都是假的话,就取最后一个假的值了

2.9.7 转换为Boolean型

显示转换:

记忆‘’ 、0、undefined、null、false、NaN 转换为布尔值后都是false, 其余则为 true

空字符串为假,其他字符串全为真

隐式转换:

隐式转换:

null+3=3

undefined+3=NaN

null==undefined 输出true,他两个都当0看

null===undefined 输出false

undefined做任何操作都是NaN

NaN不等于NaN,NaN表示计算错误

2.10 对象

2.10.1 对象的介绍

对象也是一种数据类型,里边的数据是无序的

对象由属性和方法组成

2.10.2 对象属性

  1. 查询对象

对象名.属性 goods.uname

属性名中带有字符串时采用:对象名['属性名'] goods['uname']

不带字符串的属性名也可以使用 对象名['属性名']

[]语法里面的值如果不添加引号 默认会当成变量解析

总结:点后面的属性名一定不要加引号;[] 里面的属性名一定加引号(单引双引都🆗)

  1. 重新赋值

对象名.属性=新值

  1. 增加新数据

对象名.属性=新值

  1. 删除对象中的属性

delete 对象名.属性

2.10.3 对象方法

后边跟的是匿名函数

对象外面的叫函数;对象内部的叫方法

2.10.4 遍历对象

理解为加括号的python字典遍历

k是字符串类型

用for in可以实现对数组的遍历工作,但是k为字符串,我们在遍历的时候需要用到数组的下标,下表是数组字面量,不应该为字符串,所以我们不要使用for in来遍历字典,正常for循环遍历就可以

CODE
   let arr = [1, 2, 3]
    for (let k in arr) {
      console.log(k)
      console.log(arr[k])
    }

数字型控制台输出颜色偏蓝,字符串型控制台打印是黑色的

for in 用来遍历对象 k这个写啥也行,习惯使用key或k

for in 得到的k是属性名

k是字符串,不可以进行pink.k,这是不对的,k是带引号的属性名,点k的话,对象中就没有这个属性名了,所以得到的是undefined,无法准确遍历

2.10.5 遍历数组对象、

数组中放对象信息

CODE
<script>
    let students = [
      { name: '小明', age: 18, gender: '男', hometown: '河北省' },
      { name: '小红', age: 19, gender: '女', hometown: '河南省' },
      { name: '小刚', age: 17, gender: '男', hometown: '山西省' },
      { name: '小丽', age: 18, gender: '女', hometown: '山东省' }
    ]
    for (let i = 0; i < students.length; i++) {
      for (let k in students[i]) {
        console.log(`输出第${i + 1}个同学的${k}:${students[i][k]}`)
        //输出每个人的名字:
        //console.log(students[i].name)
      }
    }
  </script>

2.10.6 内置对象

JavaScript内部提供的对象,包含各种属性和方法给开发者调用,例如document.write()

  1. 数学对象Math

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global\_Objects/Math

联想:parseInt转换为整数型,与floor相似,输入小数的数字,只取最小值

两者区别是parseInt可以传入字符串,会去掉后边的字符串,只留前边的数字

数组不可以使用Math中的max,min来求最大值与最小值

null是一个空对象,可以认为:null类似于let obj={}

null属于对象数据类型

  1. 生成任意范围随机数

这里加1是想取到右边的部分,因为它是左闭右开,第一个是[0,11),永远取不到11

乘以几就取不到几

取数组中的随机元素:

let arr = ['red', 'green', 'blue']

let random = Math.floor(Math.random() * arr.length)

console.log(arr[random])

这个函数得到的是全闭区间

function getRandom(N, M) {

return Math.floor(Math.random() * (M - N + 1)) + N

}

console.log(getRandom(4, 8))

2.10.7 基本数据类型和引用数据类型

简单数据类型是直接把值放在了栈中,复杂数据类型是将值的地址放在栈中,值放在堆中,通过地址得到存放的内容

所有复杂数据类型都存放在堆中,将它内容的地址存放在栈中

简单数据类型是深拷贝,复杂数据类型是浅拷贝

js实际是没有堆栈的,这里是为了方便理解,在ts中有堆栈,ts与js百分之80是相同的