Day1—初识JS

JavaScript基础

JavaScript是一门编程语言,但和Java没有任何关系,他和C语言的关系更亲密

JS组成

  • ECMAScript 基础语法
  • DOM 标签
  • BOM 浏览器

JS有三种引入方式,和CSS一样,分行内、内联、外联,和CSS不同的是一般JS是写在主体body里的而不是头部head里,内联使用script标签包裹,外联使用script标签的scr属性引入外部JS文件

JS的注释有两种,单行注释//和多行注释/* */

注意,在超链接a标签中href属性值在不需要使用时最好写JavaScript:;,因为空链接会刷新页面,而这样不会刷新页面

弹窗和点击事件

window.alert('hello')可以在浏览器中调用弹窗显示内容,JS中窗口类可以省略前面的window前缀,直接写成alert('hello')

JS是通过HTML中标签的id来和标签进行互动的

id名.onclick = function(){}代表了点击事件

  show.onclick = function (){
     alert('hello world')
  }

上例是一个点击事件,他绑定了一个id为show的HTML标签,在我们点击这个标签之后,浏览器会弹框显示hello world

除了点击,JS还可以通过标签id读取到标签的内容,比如通过使用id名.value来获取到标签中的value值,需要注意的是value读取到的数据均为字符串类型,在进行运算前需要注意这一点

变量和常量

JavaScript也有变量概念,需要使用关键字var或者let(推荐)来定义,关于两者的区别将会在后面讲解,总之let优于var,我们可以使用变量来存取获取到的各种数据,比如HTML标签的value值,比如文本框中输入的数字等

变量在初始化的时候可以直接赋值,也可以不赋值,未赋值的变量会显示undefined

变量可以通过使用赋值运算符=来给变量赋值不同的内容,变量可以重复赋值,后值会覆盖前值

变量适用于不确定值,比如后端数据库传入的数据、用户输入的数据等

变量的命名规则

  • 不能数字开头
  • 可以使用特殊符号 _ $
  • 可以使用中文(不建议)
  • 不能使用关键字

常量与变量不同,他在初始化的时候必须赋值,一旦赋值无法进行地址更改,如果给一个常量进行二次赋值会报错

但如果是改变属性则可以实现,比如数组中的一个数,比如对象中的一个属性

const arr = []
arr.push(3)
console.log(arr) // arr[3]

const obj = {name:'jack', age:18,}
obj.age = 20
console.log(obj) // {name:'jack', age:20,}

const arr2 = [1,2,4]
arr2 = []  //报错

上例中对于数组和对象内的属性更改可以实现,但如果是直接复制则会报错,因此归根结底,常量存储的是数据的地址,因此只要不改变存储地址其余操作并不影响

常量适用于存储程序内不会进行二次更改的数据

数据类型和强制类型转换

JS中基本数据类型有

  • number 数字类型

    • NaN(Not a Number)也是数字类型,NaN和任意数据运算都是NaN,且NaN不等于NaN
  • string 字符串类型

    • 可以使用单引号’’双引号””反引号``包裹,不同字符串或者字符串和变量可以使用+号来拼接在一起
    • 模版字符串:可以直接在字符串中嵌入变量,需要使用反引号``来包裹字符串,变量用${变量名}嵌入字符串内
  • boolean 布尔类型
    • 只有两个,true和false
  • null 空

    • 可以和数字进行运算,null+1 = 1
    • 在一个变量确定是存放对象Object但还没准备好的情况下可以赋值null,此时变量就转换为Object数据类型
  • undefined 未定义

    • 和null有区别,null可以和数字运算,但undefined不可以会返回NaN
    • 变量未赋值就是undefined

数据类型检测使用typeof 数据,也可以使用typeof(数据),在JS中我们需要根据不同的数据类型进行不同的操作,而往往很多读取操作已经默认数据类型可能与我们想要的数据类型不符,因此我们需要分清不同的数据类型,比如prompt读取到的数据默认字符串型,如果我们需要读取到的数字来进行运算就要先进行类型转换

在JS中存在隐式数据类型转换,比如- 、*、/、%、++、--、==,在进行上列运算的时候可以不进行统一数据类型,会自动将字符串转换为数字,而+因为有加法运算和字符串拼接两种使用方法,因此在运算的时候会默认以字符串拼接来进行操作,但有个小技巧,当+号作为正号解析可以把字符串转换为数字类型

JavaScript中除了隐式转换也有显式类型转换,有如下几种

  • 转数字,转换失败会显示NaN(Not a Number)
    • Number() 严格数字
    • parseInt() 整数
    • parseFloat() 浮点数
  • 转字符串

    • toString() JS提供的固定函数,toString()方法适用于数值、布尔值、对象和字符串

      默认情况下toString()不接受参数,但当数值类型操作时可以传入参数来选择相应进制的字符串

    • a + '' 利用JS特性,加上空字符串会自动拼接转换为字符串类型

  • 转布尔值
    • Boolean()
      • 真:true 非0数字 非空字符串
      • 假:false 0 ‘’ null undefined NaN

我们使用经典案例时间转换来练习类型转换

        btn.onclick = function(){
            let n = Number(s1.value)
            if(n){
                var day = parseInt(n / 86400)
                var hours = parseInt(n % 86400 / 3600)
                var sec = parseInt(n % 3600 / 60)
                alert(day + '天' + hours + '小时' + sec + '分钟' + n % 60 + '秒')
            }else{
                alert('请输入数字')
            }
        }

可以看到JavaScript和C语言的书写相似,因此学习的重点就是如何做到变量之间的拼接,但需要注意的是,JS的运算不会自动向下取整,因此想要整数一定要使用parseInt()类型转换

输入框prompt和控制台输出

        let n = prompt('请输入数字')
        if(n%2){
            alert('奇数')
        }else{
            alert('偶数')
        }

这里prompt()是让浏览器弹出一个输入框,括号内可以书写弹出输入框时显示的提示文字,比如上例就会在弹出输入框时显示“请输入数字”,需要注意的是prompt读取到的数据均为字符串类型

我们在调试程序时除了使用alter(),也可以使用console.log()来进行调试,调试的结果会显示在浏览器的控制台中,打开控制台的方法是在页面按下“F12”

练习

  1. 输入秒数换算为天时分秒

        <input type="text" id="time">
        <button id="btn">计算</button>
    
            btn.onclick = function(){
                var day =  parseInt(time.value / 86400) 
                var hours = parseInt(time.value % 86400 / 3600) 
                var min = parseInt(time.value % 3600 / 60) 
                var seconds = parseInt(time.value % 60) 
                if(Number(time.value)){
                    alert(day + '天' + hours + '小时' + min + '分钟' + seconds + '秒')
                }else{
                    alert('请输入有效数字')
                }
            }
    

  2. 摄氏度转华氏度

        <input type="text" id="F">
        <button id="btn">提交</button>
    
            btn.onclick = function(){
                var temp = (F.value - 32) * 5 / 9 
                if(Number(F.value)){
                    alert(parseInt(temp * 1000) / 1000 + '℃')
                }else{
                    alert('请输入有效数字')
                }
            }
    

  3. 数值交换

        <input type="text" id="a">⇄<input type="text" id="b">
        <button id="btn">提交</button>
    
            btn.onclick = function(){
                if(Number(a.value) && Number(b.value))
                var temp = a.value
                a.value = b.value
                b.value = temp
            }
    

  4. 数字拆解

            var num = prompt('请输入四位数')
            if(!parseInt(num/10000)){
                var a = num / 1000
                var b = num % 1000 / 100
                var c = num % 100 / 10
                var d = num % 10
                console.log(parseInt(a),parseInt(b),parseInt(c),parseInt(d))
                // console.log(num / 10000)
            }else{
                alert('请输入正确的四位数')
            }
    


Day2—判断和循环

JS的判断和C语言逻辑一样,因此这里不进行赘述

运算符

算术运算符

+、-、*、/、%,其中%表示模运算,也就是求余数

除了+号其余运算符都存在隐式类型转换

在运算失败时会显示NaN

赋值运算符

变量进行赋值的运算符,有=,是将右侧数值赋值给左侧变量

除此之外还有+=、-=、*=、/=、%=,以+=为例,定义一个这样的式子变量 += 右侧数值,他代表的是左侧变量存储的值加上右侧数值后再次赋值给自己,等价于变量 = 变量存储的值 + 右侧数值

自增/自减运算符

++自增、--自减,属于一元运算符,可以前置可以后置,前置后置在单独使用时没有区别

前置++变量,表示变量值先自增,然后用自增后的结果参与运算

后置变量++,表示变量值先使用原值参与运算,然后变量值自增

比较运算符

<、>、<=、>=、==、===、!=、!==,比较运算符有隐式类型转换,其中=====的区别是,前者会进行隐式类型转换,数据类型不同可以相等,后者为严格等于,数据类型不同则不同,!=!==同理

因此我们更推荐使用严格等于和严格不等,因为这样可以排除隐式类型转换的干扰

返回值是布尔值,满足条件则为true,不满足则为false

尽量不要比较小数,会有精度问题

涉及NaN问题全是false

逻辑运算符

&&与、||或、!非,逻辑运算符是比较布尔值并返回布尔值

&&:两者都为真才返回真,否则为假

||:两者只要有一个为真就结果返回真

!:取反,!真就是假,!假就是真

运算符优先级

小括号的优先度是最高的

然后是一元运算符,附带一个!逻辑非

再是算术运算符,其中乘除模优先级高于加减

再是关系运算符

再是相等运算符

再是逻辑运算符,不带非!,与的优先级高于或

再是赋值运算符

再是逗号运算符

判断分支if-else

适用于范围判断

// 条件成立执行语句1,不成立执行语句2
if (条件) {
  语句1
} else {
  语句2
}

// 条件成立执行对应的语句,没有成立的条件不执行语句
if (条件) {
  语句1
} else if(条件2) {
  语句2
} else if(条件3) {
  语句3
}

//  条件成立执行对应的语句, 没有成立的条件执行else
if (条件) {
  语句1
} else if(条件2) {
  语句2
} else if(条件3) {
  语句3
} else {
  语句4
}


// 简易判断,如果就已经话可以不写大括号 {}
if (条件) 语句1
else 语句2

三目运算符

格式为条件 ? 语句1 : 语句2,在条件为真时执行语句1,条件为假时执行语句2

三目运算符适用于简单的判断分支语句,书写起来更方便,但复杂判断仍需要if-else

条件分支switch

switch是让括号内的数据和下列的各个值从上到下开始严格比较,即===运算,相同的就会执行相应的语句,break的作用是在运行完语句之后直接结束分支不会再继续比较后面的值,如果不写break会导致程序穿透,也就是后面的语句也会跟着执行

适用于有一个确定值来比较

// 数据和值 是全等比较            也就是=== 严格比较
// break不写会有穿透效果
// default默认语句可以不写
switch(数据) {
    case 值1:
        语句1;
        break;
    case 值2:
        语句3;
        break;
    case 值3:
        语句;
        break3;
    default:
        默认语句
        break;
}

循环

  • 循环顺序:初始化、条件、语句、自增
    • 优化循环:使用break来终断for 、while 、for in,这样可以省去无用循环
    • 循环嵌套一定要注意变量名重复问题
    • 多层循环计算方法 length * length, 多层循环一定要注意优化(减少循环次数)
// for 
// - 固定次数 
// - 数组 字符串
for (let i = 0; i < length; i++) {}

// while
// - 没有固定次数使用
let i = 0
let len = 5
while(i < len) {
  console.log(i)        // 0 1 2 3 4 
  i++
}

// do while
// - 没有固定次数
// - 无论条件如何都至少执行一次
do{
  语句1
}while(条件)

使用逻辑运算符时,会有所谓短路的现象

比如 条件1 || 条件2 ,当条件1为真时,程序不会继续比较条件2,而是直接输出结果true

案例 九九乘法表

CSS样式

    span {
      text-align: center;
      height: 20px;
      width: 60px;
      padding: 5px;
      display: inline-block;
      line-height: 20px;
      border: 1px solid #000;
      border-radius: 3px;
      margin: 2px;
      background: rgba(255, 192, 203, .2);
      box-shadow: 2px 2px 2px rgba(255, 192, 203, .7);
    }

JavaScript

    for (let i = 1; i <= 9; i++) {
      for (let j = 1; j <= i; j++) {
        box.innerHTML += `<span>${j}x${i}=${j * i}</span>`
      }
      box.innerHTML += '</br>'
    }

样式

71162720318

网页输出打印

之前学习了console.log,还有一种输出为document.write(),这会将内容直接输出到网页上,也可以用来输出标签document.write('<br/>')

练习

  1. 输入日期计算一年中的第几天

            var year = 2024
            var month = 2
            var day = 29
            var a = [31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 ,31]
            var sum = 0
    
            for(var i = 0 ; i < month - 1 ; i++)
            {
                sum += a[i]
            }
            sum += day
            if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
                sum++
                console.log(sum)
            }else{
                console.log(sum)
            }
    
  2. 输出1000到2000之间的闰年

            for(var i = 1000 , n = 1; i<= 2000 ; i += 4){
                if(i % 4 == 0 && i % 100 != 0 || i % 400 == 0){
                    document.write(i + ' ')
                    if(n % 4 == 0){
                        document.write('<br/>')
                    }
                    n++
                }
            }
    
  3. 判断是不是水仙花数

            var num = prompt('请输入一个三位数')
            if(num > 999 || num < 100){
                alert('请输入正确的三位数')
            }else{
                var a = parseInt(num / 100) 
                var b = parseInt(num / 10 % 10 ) 
                var c = num % 10
                if(a*a*a + b*b*b + c*c*c == num){
                    alert('是水仙数')
                }else{
                    alert('不是水仙数')
                }
            }
    


Day3—循环优化和函数

循环优化break和continue

break是结束循环,遇到break,会直接跳出循环继续运行循环下面的语句

continue是跳过循环,遇到continue,循环会跳过当前循环开始新的循环

循环可以多层嵌套,但要注意时间复杂度,以及变量冲突可能会造成陷入死循环

标签

break可以配合标签使用,可以直接跳出多层循环

top:
  for (var i = 0; i < 3; i++){
    for (var j = 0; j < 3; j++){
      if (i === 1 && j === 1) continue top;  //满足条件会直接跳出双层循环
      console.log('i=' + i + ', j=' + j);
    }
  }

函数

函数的格式为function 函数名(形参,形参...){},函数可以直观地减少代码的耦合度

函数function是一种复杂数据类型,在内存中占据一片空间

函数分命名函数和匿名函数两种

function 函数名() {}命名函数—声名式函数,函数调用可以出现在函数定义前

let 函数名 = function() {}匿名函数—赋值式函数,函数调用必须出现在函数定义后

函数形参是函数声明时的书写的参数,他只存在于函数中,命名和变量名一样

函数实参是调用函数时传入的参数,必须是一种数据类型

当传入函数的参数数量不定时,使用arguments参数集来存储参数,他和数组的操作很像,使用arguments[下标]来读取存储的数据,arguments.length来确定数组的长度,但他不是数组而是对象,数组循环map方法他就用不了,需要注意的是,参数集只在函数内起作用

立即调用的函数表达式

圆括号跟在函数名后表示调用这个函数,因此如果在书写完函数立即加上圆括号就表示立即调用这个函数

但是实际上使用后会发现报错,是因为JavaScript解释器将function之后解释为函数定义,认为不应该圆括号结尾,因此会报错,解决方案就是让解释器认为这是表达式,可以给整个语句加上括号

同时需要注意,多个立即调用函数必须加分号,因为解释器会将两个函数合在一起解释导致报错

(function(){ /* code */ }());  //这里必须加分号,否则解释器会将两行合并
// 或者
(function(){ /* code */ })();

除此之外任何让解释器认为是表达式的方法都是可以的

var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();
!function () { /* code */ }();
~function () { /* code */ }();
-function () { /* code */ }();
+function () { /* code */ }();

这种立即调用的函数表达式常使用于匿名函数,这样不用为匿名函数起名字,且不会污染全局变量

练习

  1. 打印等腰三角形

            function fn(n) {
                for (var i = 0; i < n; i++) {
                    for (var j = n - i - 1; j > 0; j--) {
                        document.write('&nbsp')
                    }
                    for (var j = i * 2 + 1; j > 0; j--) {
                        document.write('*')
                    }
                    document.write('<br/>')
                }
            }
    
            fn(prompt('请输入三角形高度'))
    

  2. 寻找两个数之间的质数

             //判断一个数是否是质数
            function isPrimes(i) {
                if (i <= 1) return false
                for (var j = 2; j <= Math.sqrt(i); j++) {
                    if (i % j == 0) {
                        return false
                    }
                }
                return true
            }
    
            function findPrimes(n, m) {
                if (n > m) {
                    var temp = n
                    n = m
                    m = temp
                }
                for (var i = n; i <= m; i++) {
                    if (isPrimes(i)) {
                        document.write(i + '<br/>')
                    }
                }
            }
    
            findPrimes(prompt('请输入第一个数字') ,prompt('请输入第二个数字'))
    

  3. 求最大最小值

            function Max() {
                let max = arguments[0]
                for (let i = 1; i < arguments.length; i++) {
                    if (max < arguments[i]) {
                        max = arguments[i]
                    }
                }
                document.write('最大值为:' + max)
            }
    
             Max(12,34,2,54,1236,23,5,6)
    
            function Min() {
                let min = arguments[0]
                for (let i = 1; i < arguments.length; i++) {
                    if (min > arguments[i]) {
                        min = arguments[i]
                    }
                }
                document.write('最小值为:' + min)
            }
    
             Min(23,435,6,565,45,12,45,123)
    


Day4—函数和递归

函数返回值

和C语言类似,返回值使用return来返回函数的结果,他会阻止函数的运行,但不会阻止函数的预解析,return一次只能返回一个结果,如果需要返回多个数据可以使用数组形式返回数据

function fn() {
    console.log(a)      // undefined
    return
    var a = 100
}

上例中输出结果为undefined,这意味着函数虽然没有执行a = 100的语句,但是对a的定义已经完成了,这被称为预解析,可见return不会阻止预解析

预解析

为了防止程序报错,JS解析器具有预解析(变量提升/函数提升)这一功能,但会容易造成逻辑混乱和使用不合理的现象

能实现预解析的有变量和函数,在JS文件运行的时候实际上是分为两步,预解析和执行

变量的预解析是将变量的声明提到作用域顶部,但是不提升赋值操作

函数的预解析只对声名式函数有效,它是将函数的声明提到作用域最顶端,但函数内的语句不会解析或执行

预解析是先解析变量后解析函数,预解析有范围,分别是函数内和一个script标签内,因此实际上一个函数内部也会存在预解析现象

  1. 案例一,变量提升

    console.log(age)  //此程序结果为undefined
    var age = 10
    console.log(age)  //此程序结果为10
    //实际上上例的解析顺序为
    var age  //变量提升--只提升声明,不提升赋值
    console.log(age)
    age = 10
    console.log(age)
    
  2. 案例二,不使用var定义

    console.log(age)  //报错
    function fn() {
        age = 10
        console.log(age)  //10
    
        job = 100
        console.log(job)  //100
        var job = 200
        console.log(job)  //200
    }
    fn()
    console.log(age)  //10
    console.log(job)  //报错
    //实际上例的解析顺序为
    function fn() {}  //1.函数提升--只提升声明,不解析内部
    console.log(age)  //2.因为变量未声明,报错
    fn(){  //3.函数执行
        var age  //3.1自动声明变量,此变量为全局
        var job  //3.2自动声明变量,此变量为全局
        var job  //3.3变量提升,此时变量被声明成局部变量
        age = 10
        console.log(age)  //10
        job = 100
        console.log(job)  //100
        job = 200
        console.log(job)  //200
    }
    console.log(age)  //因为没用var声明,因此默认声明成全局变量  10
    console.log(job)  //因为函数内重定义了一遍,因此变成局部变量,外部无法调用,报错
    
  3. 案例三

        var a = 100
        function fn() {
          console.log(a)
          var a = 200
          console.log(a)
        }
        console.log(a)
        fn()
        // 结果  100 undefined 200
    
        //执行顺序为
        // 预解析
        //       var a
        //       function fn(){}
        // 执行
        //    a=100
        //    console.log(a)  //100
        //    fn(){
        //      预解析
        //          var a
        //      执行
        //          console.log(a)  //undefined
        //          a=200
        //          console.log(a)  //200 
        //      }
    

不过在ES6之后预解析实际上已经不重要了,因为有let这个新变量声明了,let的使用严格要求了变量的声明必须在使用之前,否则会直接报错,而且let不允许重复定义变量,因此书写代码时使用let更规范

作用域

变量的作用域是变量的有效范围,分为全局作用域和局部作用域还有块级作用域

全局作用域就是所有函数外部的变量,所有的内部函数都可以使用它,谁都可以更改,容易命名冲突,只要程序在执行变量就一直存在消耗性能

局部作用域就是函数内的变量,只有函数内部可以更改,函数外部无法使用也无法获取到值,在函数结束之后变量就会被回收

块级作用域,凡是代码块就会产生作用域,这被称为块级作用域,比如for(let i = 0 ; i < n ; i++)for循环内的i只有for循环内能使用,除了循环就会被回收,又比如我们使用两个花括号将两个语句分别括起来{let sum = 0}{let sum = 1},此时这两个代码块就具有局部作用域,两者之间的sum不会冲突,可以重复定义

作用域链,在多层函数嵌套中,如果最里面的函数使用了一个变量,他会从内开始往外搜索最近的变量声明,如果一直到全局都没有找到,就会报错

递归

和C语言相同,递归就是函数自己调用自己,这种方式往往会消耗性能,因此并不长使用,多数使用循环代替

书写递归时最重要的就是结束条件,没有结束条件会导致无限递归

练习

  1. 两个数之间的数互相组合排列呈正方形矩阵

        function twoSum(n, m) {
          for (let i = n; i <= m; i++) {
            for (let j = n; j <= m; j++) {
              document.write(i, j)
              document.write(' ')
            }
            document.write('<br/>')
          }
    
        }
    
        twoSum(0,3)
    

  2. 数字加密+5%10,且逆序输出

        function password(n) {
          let j = 1
          for (let i = 0; i < 4; i++) {
            let m = parseInt(n / j) % 10
            m = (m + 5) % 10
            document.write(m)
            j *= 10
          }
        }
    
        password(4567)
    

  3. 计算BMI是否标准

        function BMI(height, weight) {
          let bmi = (height - 108) * 2
          let res = bmi - weight
          if (res >= -10 && res <= 10) {
            document.write('标准')
          } else {
            document.write('不标准')
          }
        }
    
        BMI(184, 150)
    


Day5—对象和数组

对象

对象Object

  • 复杂数据类型
  • 无序数据列表
  • 用来存储一组相关联的数据
let obj = {
    name : 'jack',
    age : 18,
    job : '前端工程师'
    ...
}

对象的内容是以键值对的形式存储的,键值之间使用冒号分割,多对之间用逗号隔开

对象的创建

对象有两种创建方式

  • 字面量—-{}
    • 可以直接在里面书写内容
    • 数据以键值对形式出现
    • 键key默认是字符串形式
    • 值可以是任意数据类型
  • 构造函数—-new Object()
    • 没有默认内容,不能直接书写,必须使用赋值语句
    • 值可以是任意数据类型
        var obj = {
            'name': 'Jack',
            'age': 18,
            'flag': true,
            'fn': function () { },  //值可以是函数
            'nu': null,
            'un': undefined,
            'obj': {}  //值可以是数组
        }

        var obj = new Object()
        obj.name = 'Jack'  //使用赋值语句
        obj.age = 18
        console.log(obj)

对象的操作

  1. 书写

    键key有三种写法

    • key: , 常用写法可以不使用引号,因为键key默认就是字符串类型
    • 'key': , 规范写法,带引号表示字符串格式,key里如果有特殊符号比如A-1: ,则必须带引号,如果不带引号会被判定为运算操作
    • [变量名]: , 特殊写法,因为key是变量因此使用中括号包起来,本质上编译器会自动将变量名识别为他所代表的变量值字符串,也就是会识别为['变量值']: ,
  2. 读取

    有三种读取的书写方式

    • obj.key key为字符串格式,可以使用.且不加引号
    • obj['age'] key为字符串格式,可以使用中括号且加引号,如果有特殊字符则必须使用中括号加引号
    • obj[变量名] key为变量,此时不需要写引号,且必须使用中括号不能使用.
  3. 删除

    删除delete obj.key使用delete关键字,书写格式和读取一样有三种

  4. 更改

    直接赋值obj['key'] = 20书写方式和读取一样有三种方式

循环对象

for in专门用来循环对象的

        var obj = {
            name: 'Jack',
            age: 18,
            job: '前端'
        }

        for (var key in obj) {
            console.log(key)        // 输出属性名
            console.log(obj[key])      // 输出属性值,只有一种写法
        }

数组

有序数据列表

一种复杂数据类型

数组使用下标:下标从0开始计算

数组是有长度的:.length

数组的创建

数组也有两种创建方式

  • 字面量[]
    • 在中括号内可以输入多个数据,使用逗号隔开
    • 默认没有长度限制
    • 数据可以是不同的数据类型
  • 构造函数new Array()
    • 在括号内可以输入多个数据,使用逗号隔开
    • 当括号内只有一个数据且是数字,代表数组的长度

数组操作

.push() 在数组后面添加

.unshift() 在数组前面添加

.pop() 在数组后面删除

.shift() 在数组前面删除

练习

  1. 查找数组

        let Arr1 = [12, 99, 5, 7, 9, 34, 78, 32]
        function findArr(arr, n) {
          for (let i = 0; i < arr.length; i++) {
            if (arr[i] == n) {
              return true
            }
          }
          return false
        }
    
        console.log(findArr(Arr1, prompt('请输入要查找的数字')))
    

  2. 数组去重

        let Arr2 = ['d', 'a', 'c', 'a', 'd', 'b', 'a', 'b']
        function no_repeat(arr) {
          let res = [arr[0]]
          for(let i = 1 ; i < arr.length ; i++){
            let flag = true
            for(let j = 0 ; j < res.length ; j++){
              if(res[j] == arr[i]) {
                flag = false
                break
              }
            }
            if(flag){
              res.push(arr[i])
            }
          }
          return res
        }
    
        console.log(no_repeat(Arr2))
    

  3. 数组每个数增长倍数

        let Arr3 = [10, 100, 1000, 10000]
        function multiple(arr , n){
          let res = []
          for(let i = 0 ; i < arr.length;i++){
            res.push(arr[i] * n)
          }
          return res
        }
    
        console.log(multiple(Arr3 , 5))