js – day01

js的组成

我们可以使用js来完成如下的相关功能

  1. 人机交互
  2. 后端
  3. 页面特效和动画
  4. 数据处理和数据交互

js就是一门语言

这门语言可以使我们方便的取去操作页面和浏览器中的元素

所以js由以下三个部分组成

  1. ECMAScript
    • JS的核心语法,也就是这个语言是怎么写的
  2. DOM => document object model
    • 文档对象模型
    • 使用js提供的API(一些属性和方法)来操作页面的相关元素
  3. BOM => browser object model
    • 浏览器对象模型
    • 使用js提供的API 来操作浏览器中的相关要素

变量

变量是一个容器,这个容易中可以存储对应的值

所谓的变量,也就是值会变化的量

也即是说我们这个容器中存储的内容是可以随时发生改变的

6种定义变量的方式

// ES5定义变量的方式
var num = 14
console.log(num) // => 14

// 变量的值是可以被修改的
num = 22
console.log(num) // => 22

// ES6 中定义变量的方式
let num = 23

// const定义的量为常量
// 也就是说常量所对应的值是固定不变的,是无法修改的
// 我们可以认为 常量是一种特殊的变量

// num => 常量   22 => 字面量
const num = 22

// 其它的一些js行为也可以被视为变量的创建
// 1. 定义函数
// 定义了变量 fun 来存储我所对应的函数代码块
const fun = function() { ... }

// 2. 定义类
// 定义变量Person 来存储我整个类的代码
class Person { ... }

// 3. 模块导入
// 定义一个path变量来接收模块导出的内容
import path from './path.js'
                        
// 4. 定义唯一值 (独一无二的值)
let symbol1 = new Symbol(100)
let symbol2 = new Symbol(100)
symbol1 === symbol2 // => false
复制代码

变量的命名规范

  • 严格区分大小写
let num = 200
console.log(NUM) // => error
复制代码
  • 使用数字,字母,下划线和$ 组成 其中不能以数字开头
let $box; // => $开头的变量一般是存储 使用JQuery获取的元素
let _box; // => 以下划线开头的一般代表全局变量或者公共变量 (这种写法主要是约定俗称的规范)
let 2box; // => error
let box1; // => 合法的变量
let 变量; // => 合法的变量 极度不推荐
复制代码
  • 命名应该见名知意(语义化)
let a = 222 // => bad
let num = 222 // => good
复制代码
  • 命令的方式有 驼峰命令法(CamelCase) 和 帕斯卡命名法(PascalCase)
// 小驼峰 => 第一个单词的首字母小写,其余每一个有意义的单词或简写的首字母都要大写
let userInfo

// 大驼峰(帕斯卡命名法) => 所有的有意义的单词或简写的首字母都大写 一般用于定义类或者构造函数(约定俗成)
let UserInfo 

// 下划线命令法
let user_info
复制代码
  • 不能使用关键字和保留字
    • 关键字 -> 当下有特殊含义的叫做关键字
    • 保留字 -> 未来可能存为关键字的叫做保留字
let break = 222 // => error
复制代码

数据类型

  1. 基本数据类型
    • Number 数值 =>常规数值 + NaN(代表对应的值不是一个数值类型,但是NaN本身属于数值类型)
    • String 字符串 => 所有使用单引号或双引号或反引号包裹起来的内容都是字符串
    • Boolean 布尔值 => true | false
    • Undefined 未定义
    • Null 空对象指针
    • Symbol 唯一值
  2. 引用数据类型
    • 对象数据类型 Object
      • 普通对象 { … }
      • 数组对象 [ … ]
      • 正则对象 / ^ 基本数据类型

        Number

        1. 常规数字 = 正数 + 负数 + 小数 + 整数 + 零 ….
        2. NaN => not a number 表示当前变量不是一个数值,但是NaN本身是一个数值类型的值
        // NaN 和任何值都是不相等的,包括它自己本身
        console.log(NaN === NaN) // => false
        
        // 判断一个值是不是有效数字, 使用方法 isNaN()
        // isNaN([val]) => 检测一个值是不是有效数字,如果是有效数字返回false,不是有效数字,返回true1
        console.log(isNaN(2)) // => false
        console.log(isNaN(NaN)) // => true
        
        // 在使用isNaN进行检测的时候,会先判断参数是不是number类型,如果不是会先尝试使用Number()方法,将参数转换为number类型后再进行判断,如果值以及是数值类型,那么就直接进行判断
        console.log(isNaN('10')) // => false
        // 所以凡是可以使用isNaN进行转换后,变成有效数值的,那么这个值就是有效数值,调用isNaN方法的时候,将会返回false
        复制代码
        // 其它类型值转换为数值类型
        
        // 1. Number(val) => 如果参考可以转换为数字,那么就转换为数字,如果不能转换为数字,那么就返回NaN
        
        // 字符串->数字 必须保证当前字符串的值不能包含任何一个非有效的数值字符(第一个点除外)
        console.log(Number('12.3')) // => 12.5
        console.log((Number('12.5px'))) // => NaN
        console.log(Number('12.5.6')) // => NaN
        console.log(Number('')) // => 0 空字符串会被转换为数值零
        
        // 布尔->数字
        console.log(Number(true))  // => 1
        console.log(Number(false)) // => 0
        console.log(isNaN(true)) // => false
        
        // null|undefined->数字
        console.log(Number(null)) // => 0
        console.log(Number(undefined)) // => NaN
        
        // 引用数据类型->数字
        // 先将引用数据类型调用toString方法转换为字符串,后在按照字符串的规则进行转换
        // 大部分对象调用toString方法后结果为[object Object]
        console.log(Number({name: '10'})) // => NaN
        console.log(Number({})) // => NaN
        
        console.log([]) // => 0      [].toStirng() -> ''
        console.log([12]) // => 12   [12].toString() -> '12'
        console.log([12, 13]) // => NaN  [12,13].toString() -> '12,13'
        复制代码
        // 字符串转数值的其它方法
        let str = '12.5px'
        console.log(Number(str)) // => NaN
        console.log(parseInt(str)) // => 12
        console.log(parseFloat(str)) // => 12.5
        
        // parseInt|parseFloat(字符串类型的值, 进制)
        // 对于字符串来说,这两个方法是从左往右依次查找有效数字字符,一直到非有效的数字字符为止(不管后边是否还有数字,都不在找了),将找到的转变为数字返回
        // 所谓的有效字符 指点的是数字 和 第一个点
        
        // 在进行相等(==)判断的时候,也可能出现其它类型的值转换为数值
        console.log('10' == 10) // => true 字符串转换为数值后在进行比较
        复制代码
        // Number方法和parseInt|parseFloat方法的区别
        // Number方法是v8引擎提供的方法,是走v8判断机制 -> 浏览器默认转换的时候会调用的方法
        // parseInt|parseFloat 是浏览器自己封装的方法 -> 只有自己手动调用的时候,才会执行的方法
        console.log(number(true)) // => true -> 1 -> 1
        console.log(parseInt(true)) // => 因为parseInt|parseFloa只能解析字符串类型的值,所以会将参数转换为字符串后再进行判断
        // true -> 'true' -> NaN
        复制代码

        String

        所有使用单引号双引号反引号包起来的都是字符串

        // 其它类型值转换为字符串
        
        // toString方法
        let v = 12
        console.log(v.toString()) // => '12'
        console.log(12.toString()) // => error
        // (NaN)  ---> 括号表达式
        // 基本类型值在调用toString方法的时候,需要外层包裹一层括号表达式
        // 引用类型的值可以直接调用toString方法
        console.log((NaN).toString()) // => 'NaN'
        
        // 绝大多数数据调用toString方法的结果就是在值的外边加上引号
        // 比较特别的是null和undefined是没有办法调用toString方法
        // null和undefined是有toString方法的,就是无法直接调用
        // 这是因为null和undefined表示空或者是未定义,此时浏览器解析时候是无法调用方法的
        console.log((null).toString()) // => error
        console.log((undefined).toString()) // => error
        
        console.log({}.toString()) // => '[object Object]'
        console.log(/^$/.toString()) // => '/^$/'
        
        console.log([].toString) // => ''
        console.log([12].toString) // => '12'
        console.log([12, 23].toString) // => '1223'
        
        // 字符串拼接
        // 四则运算法则中,除加法之外,其余都是数学运算,但是+可能表示加法,也可能表示字符串拼接
        console.log('10' + 10) // => 1010 只要+两边有一个为字符串,那么+表达的作用就是字符串拼接
        console.log('10' - 10) // => 0 '10'使用浏览器内置的Number方法转换为数字10 所以结果为0
        console.log('10px' - 10) // => NaN
        console.log(10 + null + true + [] + undefined) // => 10 + 0 + 1 + '' + undefined([]在转换的过程中会先转换为空字符串,所以直接变成字符串拼接) => 结果为 11undefined
        复制代码

        Boolean

        只有2个值 true(真) / false(假)

        // 把其它类型的值转boolean的时候
        // 0, NaN, '', undefined, null -> false
        // 其余 -> true
        // 中间没有任何的中间过程
        
        // Boolean函数
        console.log(Boolean(0)) // => false
        console.log(Boolean('')) // => false
        console.log(Boolean(' ')) // => true
        console.log(Boolean(null)) // => false
        console.log(Boolean(undefined)) // => false
        console.log(Boolean([])) // => true 中间没有任何的中间过程,所以直接是true
        console.log(Boolean([12])) // => true 
        
        // !/!! -> 取反/取反再取反 (先转换为boolean值,再取反)
        console.log(!1) // => false
        console.log(!!1) // => true   !! <=> Boolean函数
        
        // 逻辑判断
        if(1) { ... } // => 逻辑执行
        if('3px' - 3) { ... } // => '3px' - 3 --> Number('3px') -3 --> NaN --3 -> NaN
        复制代码

        null 和 undefined

        null -> 空对象指针, undefined -> 未定义

        // null 和 undefined 都是没有
        // null -> 空指针,
        // undefined -> 定义未赋值
        
        // null -> 一开始不知道值的时候,设置的默认值,后期再进行赋值操作
        let num = null
        let num = 0
        // 上述两个方法都可以设置num的初始值,区别在于 设置为0的时候,是只要一个确切的值的,是有值的,会在内存中有存储空间
        // null是空值,在内存中是不占存储空间的,但是所有的变量全部初始值为null,不利于语义化,但是使用null性能会好上一点点
        
        // undefined -> 我没有给初始值,V8给变量的初始值
        // 所以在变量定义了,未赋值的条件下, 这个变量的默认值就是undefined
        let u // => undefined
        复制代码

        引用数据类型

        普通对象

        任何一个对象,都是由零到多组键值对(属性名-属性值)组成的

        属性名不能重复,后一个属性名会覆盖前一个同名属性

        const Person =  {
          name: 'Klaus', // => 多个键值对之间使用逗号隔开
          age: 18 // 所有的属性名都是字符串或数值, 如果是字符串类型,引号可以省略, age: 18 <=> 'age': 18
        }
        
        // 获取属性名对应属性值
        console.log(person.name) // => 对象.属性名
        console.log(person['age']) // => 对象[属性名] 此时的属性名可以为变量,但是如果是一个具体的值的时候,需要使用字符串
        
        console.log(person.size) // => undefined 如果当前属性名不存在,默认的属性值是undefined
        复制代码
        // 原则上,属性名可以是数字(不推荐),此时只可以使用中括号语法来获取属性名对应的属性值
        const obj = {
          1: 100
        }
        
        console.log(obj[1]) // => 100
        console.log(obj.1) // error
        复制代码
        const obj = {
          name: 'Klaus'
        }
        
        // 设置属性名
        obj.age = 18
        obj['gender'] = 'male'
        
        // 如果属性名对应的属性值已经存在,就不是添加属性名,而是修改属性名对应的属性值
        obj.name = 'Alice'
        console.log(obj.name) // => Klaus
        复制代码
        const obj = {
          name: 'Klaus',
          age: 18
        }
        
        // 删除属性名
        // 1. 真删除:彻底删除
        delete obj.age
        
        // 2. 假删除: 属性还在,值为空
        person.name = null // 或 person.name = undefined
        复制代码

        数组对象

        // 数组是一种特殊的对象数据类型
        // 1. 数组的属性名是从0递增的索引值 (索引=> 从0开始连续递增,代表每一项位置的属性名)
        // 2. 数组的属性名是数值类型,所以我们只能通过中括号语法来通过属性名获取到对应的属性值
        // 3. 数组有一个默认属性,length代表着数组的长度 (不需要设置,会自动修改和更新)
        let arr = ['Klaus', 18, true]
        /*
        	arr => {
        		0: 'Klaus',
        		1: 18,
        		2: true,
        		length: 3
        	}
        */
        
        console.log(arr.length)
        console.log(arr[0])
        
        // 向数组末尾添加内容
        arr[arr.length] = 'demo'
        复制代码

        堆栈内存

        • 浏览器想要执行JS代码,
          • 从电脑内存中分配出一块内存,以执行js代码(提供js执行所需要的运行环境), 这部分内存被称之为栈内存(Stack)-> ‘饭店’
          • 浏览器分配一个主线程用于自上而下执行JS代码 -> ‘服务员’

        IqdJzy.png

        JS中内存的划分

        1. 栈 -> 执行代码 + 存储变量和基本数据类型值以及引用类型值的引用地址
        2. 堆 -> 用来存储引用数据类型对应的值

        变量的存储过程

        JS中数据分为2种

        1. 基本数据类型 -> 按值操作(直接操作的是数据值)-> 也被叫做值类型

          -> 值一般存储在栈(Stack)中

        2. 复杂数据类型 -> 操作的是对应的堆内存中的值在内存中的引用地址 -> 也被叫做引用类型

          -> 值一般存储在堆(Heap)中,使用其存储在栈中的地址进行关联

        // 基本数据类型在内存中的存储过程
        let a = 12
        // 1. 创建变量a, 放置到栈内存的变量存储区域
        // 2. 创建一个值12,放置到当前栈内存的值存储区域 -> 只有简单的值可以这么存储
        // 3. = 代表这赋值,在内存中是让变量和值相互关联的过程
        复制代码
        // 引用数据类型在内存中的存储过程
        let per = {
          name: 'Klaus'
        }
        // 1. 在内存中分配出一块新的内存,专门用于存储引用类型值,这种内存被称之为堆内存(Heap)
        //    => 所有的内存都有一个十六进制的值来表示某一块内存的地址
        // 2. 把对象中的键值对依次存储到堆内存中,并将这个堆内存的地址存储到栈内存的值存储空间中
        // 3. 将堆内存地址和变量进行关联
        复制代码

        修改变量的值

        基本数据类型

        let a = 12
        let b = a
        a = 13
        console.log(a) // => 12
        复制代码

        Iqdp5G.png

        let o1 = {
          name: 'Klaus'
        }
        
        let o2 = o1
        o2.name = 'Alice'
        console.log(o1.name) // => 'Alice'
        复制代码

        Iqdfo6.png

        阶段练习

        let n = [10, 20]
        let m = n
        let x = m
        m[0] = 100
        x = [30, 40]
        x[0] = 200
        m = x
        m[1] = 300
        n[2] = 400
        console.log(m) // => [200, 300]
        console.log(n) // => [100, 20, 400]
        console.log(x) // => [200, 300]
        复制代码
        let a = {
          n: 1
        }
        
        let b = a
        
        a.x = a = {
          n: 2
        }
        // 连续赋值等价于从往右依次赋值
        /*
        	a.x = a = {n: 2}
        	<=> 可以从左往右划分为两行代码(有先后执行顺序)
        	a.x = { n:2 }
        	a = { n:2 }
        */
        
        console.log(a.x) // => undefined
        console.log(b) // => { n: 1, x: { n: 2 } }
        复制代码

        数据类型检测

        JS中检测数据类型的方法有且只有4种:

        1. typeof [val] : 用来检测数据类型的运算符,不是函数,调用不需要加小括号
        2. instanceof: 也是一个运算符,用于检测当前实例是否属于某个类的实例 (基于类)
        3. constructor: 使用构造函数的方式去检测数据类型 (基于类)
        4. Object.prototype.toString.call(): 检测数据类型最好的办法
        console.log(typeof 1) // => 'number' -> 返回的就是1的数据类型, 返回的number本身是一个字符串类型的值,全部都是小写的
        console.log(typeof typeof 1) // => 'string'
        
        let a = NaN
        console.log(typeof a) // => 'number'
        
        console.log(typeof null) // => 'object' -> typeof运算符认为null是空对象指针,所以认为null的数据类型是object, 这是typeof运算符的局限性,但是本质上null是空对象指针,是基本数据类型,不是引用数据类型
        
        console.log(typeof undefined) // => 'undefined'
        
        // typeof 无法区分普通对象类型和特殊对象类型,统一返回的都是object
        console.log(typeof {}) // => 'object'
        console.log(typeof /^$/) // => 'object'
        console.log(typeof []) // => 'object'
        
        // 但是特别的是 typeof 可以区分出函数类型
        console.log(typeof function(){}) // => 'function'
        复制代码

        JS中的操作语句

        判断

        条件成立做什么,条件不成立做什么

        JS中的条件判断有3种

        • if/ else if/ else
        • 三元运算符
        • switch … case …

        if/else if/else

        /*
        	if(条件成立) {
        		条件1成立需要执行的代码
        	} else if(条件2成立) {
        		条件2成立需要执行的代码
        	} ...
        	else {
        		以上条件都不成立的时候需要执行的代码
        	}
        	
        	// => 只要有一个条件成立就执行其中的代码块,后边的代码块就一律不会执行
        */
        
        // A && B => A和B同时成立,表达式才成立
        // A || B => A和B只要有一个成立,表达式就直接成立
        
        let a = 10
        if(a) { // a在条件判断框中,会先转换为boolean值,在进行判断
          .... // 所以这里的代码块会被执行
        }
        
        if(a=2) { // 如果条件块中的代码是语句的时候,只要语句合法,那么条件就认定为true
          .... // 所以这里的代码块会被执行
        }
        复制代码

        三元运算符 --- 简单if-else的简写方式

        // 条件 ? 条件成立执行语句 :条件不成立执行语句
        // 如果if-else比较简单的话,可以使用三元运算符代替
        let a = a > 1010 : 5
        
        // 1. 如果需要处理的事情比较多,可以使用括号包起来,每一件事情使用逗号进行分割
        // 2. 如果不需要处理事情,可以使用null或undefined来进行占位
        a > 10 && a < 20 ? ( a++, console.log(a) ) : null
        复制代码

        switch ... case ...

        一个变量在不同值情况下,需要有不同的操作

        switch(a) {
          case 1: // 在switch...case...中每一个case的比较使用的都是全等(绝对相等)
            console.log(1)
            break // 每一个case的最后都最好需要加上break,
            // 如果不加break,就表示当前代码块和后面的代码块都需要执行,直到遇到break为止或者全部执行完毕
        
            case 2:
            console.log(2)
            break
        
          case 3:
            console.log(3)
            break
        
          case 4:
            console.log(4)
            break
        
          case 5:
            console.log(5)
            break
        
          default:
            console.log('end') // 因为是默认条件,也就是最后一个条件,所以这里不需要加break,加了也没有意义
        }
        
        
        switch(a) {
          // 不加break可以实现变量在某些值的时候,执行相同的功能,此处就相当于 a === 1 || a === 5  (注意: 是全等)
          case 1:
          case 5:
            a += 2
            
          default:
            a -= 2
        }
        复制代码
        // == 和 === 的区别
        // == -> 相等 --- 如果左右两边数据类型不同,默认先转化为相同类型(优先转换为数值类型),然后在进行比较
        // === -> 全等 --- 只有类型和值都相同的情况下,才会相等 --- 推荐使用
        5 == ’5// => true
        复制代码

        案例

        <!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>基于CSS实现鼠标滑过显示下拉列表内容</title>
          <style>
            .box {
              /*
                默认值是content-box: 也就是设置的内容本质是内容区的宽度和高度,设置padding或margin会改变盒子的大小
                border-box: 设置的宽高就是盒子的宽高,设置padding或margin不会改变盒子的大小
              */
              box-sizing: border-box;
              text-align: center;
              margin: 20px auto;
              width: 200px;
              height: 40px;
              line-height: 40px;
              border: 1px solid lightblue;
              position: relative;
            }
        
            .box .detail {
              position: absolute;
              /* detail是box的子元素,所以默认边框会左移1px */
              left: -1px;
              /* 定位后,上移,detail的上边框和box的下边框重叠 */
              top: 38px;
              box-sizing: border-box;
              width: 500px;
              height: 100px;
              text-align: center;
              line-height: 100px;
              border: 1px solid lightblue;
              display: none; /* 默认不显示 */
            }
        
            .box:hover {
              /* box的下边框和背景色一致,来覆盖detail和box重叠的边框色 */
              border-bottom-color: #fff;
            }
        
            .box:hover .detail {
              display: block;
              /* 因为box和detail同时定位,所以降低detail的层级,以便于box的下边框可以覆盖detail的上边框 */
              /* 因为detail是box的子元素,如果设置在box上,那么box和其子元素detail一起都会发生改变,所以这里只能设置在子元素detail上 */
              z-index: -1; /* z-index的默认值是0 */
            }
          </style>
        </head>
        <body>
          <!-- 基于CSS实现鼠标滑过显示下拉列表内容 -->
          <div class="box">
            购物车
            <div class="detail">购物车中的相关信息</div>
          </div>
        </body>
        </html>
        复制代码
        <!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>基于js点击显示下拉列表内容</title>
            <style>
              .box {
                box-sizing: border-box;
                text-align: center;
                margin: 20px auto;
                width: 200px;
                height: 40px;
                line-height: 40px;
                border: 1px solid lightblue;
                position: relative;
                cursor: pointer; /* 鼠标移动上去的时候,显示一个小手 */
              }
        
              .box .detail {
                position: absolute;
                left: -1px;
                top: 38px;
                box-sizing: border-box;
                width: 500px;
                height: 100px;
                text-align: center;
                line-height: 100px;
                border: 1px solid lightblue;
                display: none;
                z-index: -1;
              }
            </style>
          </head>
          <body>
            <!-- 基于js点击显示下拉列表内容 -->
            <div class="box">
              购物车
              <div class="detail">购物车中的相关信息</div>
            </div>
        
            <script>
              // 想操作谁就先获取谁 --- 获取元素
              const box = document.querySelector('.box')
              const detail = document.querySelector('.detail')
        
              // 在对应的时候做对应的事情 --- 绑定事件
              // onxxx - 当xxx的时候执行绑定的函数 (xxx就是函数名)
              // onxxx --- 都是小写的,没有大写字母
              box.onclick = () => {
                // 元素.style.xxxx 获取元素在行内设置的样式值,如果有就返回设置的值,如果没有就返回空字符串
        
                // 所以原则上需要在行内设置display样式后,才可以获取到这个样式的值,
                // 但是一开始默认就是隐藏的(false),点击以后会自动设置上对于的行内样式,所以这里此步可以省略
                let isShow = detail.style.display === 'block'
        
                // 元素.style.xxx == yyy -> 以设置行内样式的方式设置元素的名为xxx的样式属性,值为yyy
                detail.style.display = isShow ? 'none' : 'block'
                // js中操作的样式名采用的是小驼峰命名法
                box.style.borderBottomColor = isShow ? 'lightblue' : '#fff'
              }
            </script>
          </body>
        </html>
        复制代码

        传统DOM编程(命令式编程)的逻辑思路

        • 想操作谁就先获取谁 — 获取元素

        • 在对应的时候做对应的事情 — 绑定事件

        • 需要做什么 —- 编写事件处理函数

        现代框架(响应式编程)的逻辑思路

        • 界面长什么样 —- 定义视图

        • 有哪些数据和方法 —- 声明相关数据和方法

        • 数据和视图进行绑定

          —- 使用框架提供的特有语法(vue的模板语法,react的jsx语法等)将对应的数据插入视图中,将对应的方法在视图中进行绑定

          —- 具体如何绑定和渲染主要由框架来进行处理,我们只要关心界面的处理逻辑即可,当数据发送改变的时候通知框架,对应的数据改变了,框架就会自动去更新我们的界面视图

          —- 也就是数据驱动界面显示,所以这里的数据又被称之为状态

        循环

        重复做一些事

        • for循环
        • for … in …
        • for …. of … (ES6新增)
        • while
        • do … while …

        for循环

        1. 创建循环初始值
        2. 设置(验证)循环执行条件
        3. 条件成立, 执行循环体中内容
        4. 当前循环结束,步长累加操作
        // ()中放置条件
        // (设置初始值,循环执行条件,步长)
        for (var i = 0; i < 5; i++) {
          //  大括号中写的代码块 叫做 循环体
          console.log(i)
          /*
                =>
                  0,
                  1,
                  2,
                  3,
                  4
        
                  总共循环了5次
              */
        }
        
        // var这里设置的变量是全局变量
        console.log(i) // => 5
        复制代码
        for (var i = 10; i > 4; i-=2) {
          i = i < 7 ? i++ : i --
        }
        
        console.log(i) // => 4
        复制代码
        // 循环体中有2个关键词 break和continue
        // continue --- 结束当前循环,进入下一次循环
        // break --- 结束所有轮次的循环,循环结束
        复制代码

        阶段案例

        有一个输入框,判断输入的内容是正数,负数还是零

        const inputEl = document.getElementById('input')
        
        inputEl.addEventListener('blur', e => {
          // 文本框输入的内容可以通过value属性来获取或者可以事件对象的target属性的value值来进行获取
          // 表单元素输入的内容的默认类型都是字符串
          // const val = Number(inputEl.value)
          const val = Number(e.target.value)
        
          // Number将字符串转换为数值类型的时候,是可以正常转换负数的 Number('-12') -> -12
          isNaN(val) ? console.error('not a number') :  console.log( val > 0 ? '正数' : val === 0 ? '零' : '负数')
        })
        复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享