JavaScript基础

 

JavaScript基础

1- 初识JavaScript

1.1 JavaScript 是什么

  • JavaScript是一种运行在客户端的脚本语言,现基于Node.js技术进行服务端编程;

    所谓脚本(Script)语言:是运行时不需要编译,运行过程中由 js 解释器( js 引擎)逐行来进行解释并执行。读到一行,执行一行;

  • 目的是实现逻辑业务与页面控制,相当于动作;

    所谓逻辑性:就是 实现这个要求的思路 先怎么做后怎么做;

1.2 JavaScript的作用

  • 表单动态校验(密码强度检测) ( JS 产生最初的目的 )

  • 网页特效

  • 服务端开发(Node.js)

  • 桌面程序(Electron)

  • App(Cordova)

  • 控制硬件-物联网(Ruff)

  • 游戏开发(cocos2d-js)

1.3 HTML/CSS/JS 的关系

HTML 和 CSS 属于描述类语言;JS 属于 编程类语言;

1.4 浏览器执行 JS 简介

浏览器分成两部分:渲染引擎和 JS 引擎

  • 渲染引擎:用来解析HTML和CSS,俗称内核,比如 chrome浏览器的 blink,老版webkit等;

  • JS 引擎:也称 JS 解释器。用来读取网页中的 JavaScript代码,处理后运行,如chrome的V8;

    浏览器本身并不会执行JS代码,而是通过内置 JavaScript 引擎(解释器) 来执行 JS 代码 。JS 引擎执行代码时逐行解释每一句源码(转换为机器语言),然后由计算机去执行,所以 JavaScript 语言归为脚本语言,会逐行解释执行。

1.5 JS 的组成

  1. ECMAScript

    ECMAScript:规定了JS的编程语法和基础核心知识,是所有浏览器厂商共同遵守的一套JS语法工业标准。

    更多参看MDN: MDN手册

  2. DOM——文档对象模型

    文档对象模型(DocumentObject Model,简称DOM),是W3C组织推荐的处理可扩展标记语言的标准编程接口。通过 DOM 提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)——元素对象;

  3. BOM——浏览器对象模型

    浏览器对象模型(Browser Object Model,简称BOM) 是指浏览器对象模型,它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等——浏览器窗口;

 

1.6 JS 书写位置

JS 有3种书写位置,分别为行内、内嵌和外部。

1.行内式

<input type="button" value="点我" onclick="alert('Hello World')" />

 

  • 可以将单行或少量 JS 代码写在HTML标签的事件属性中(以 on 开头的属性),如:onclick

  • 注意单双引号的使用:在HTML中我们推荐使用双引号, JS 中我们推荐使用单引号

  • 可读性差, 在html中编写JS大量代码时,不方便阅读;

2.内嵌式

<script>
    alert('Hello  World~!');
</script>

 

  • 可以将多行JS代码写到 script 标签中

  • 内嵌 JS 是学习时常用的方式

3.外部JS文件

<script src="my.js"></script>

 

  • 利于HTML页面代码结构化,把大段 JS代码独立到 HTML 页面之外,既美观,也方便文件级别的复用

  • 引用外部 JS文件的 script 标签中间不可以写代码

  • 适合于JS 代码量比较大的情况

    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <!-- 2.内嵌式的js -->
        <script>
            alert('这是我的第一个js');
        </script>
// 3.外部js的写法,开始和结束标签间不能写字
        <script src="script.js"> </script>
    </head>
<body>
        <!-- 1.行内式的js 直接写到元素内部,以on开头的属性 外双内单引号 -->
        <input type="button" value="提交" onclick="alert('提交成功')">
    </body>

 

 

2 - JavaScript注释

JS中的注释主要有两种,分别是单行注释和多行注释。

1. 单行注释
// 用来注释单行文字(  快捷键   ctrl  +  /   )
2. 多行注释
/* */  用来注释多行文字( 默认快捷键  alt +  shift  + a )

 


更改快捷键:vscode → 首选项按钮 → 键盘快捷方式 → 查找 原来的快捷键 → 修改为新的快捷键 → 回车确认

3 - JavaScript输入输出语句

为了方便信息的输入输出,JS中提供了一些输入输出语句,其常用的语句如下:

方法说明面向对象
alert(msg) 浏览器弹出警示框 用户
console.log(msg) 浏览器控制台打印输出信息 程序员
prompt(info) 浏览器弹出输入框,用户可以输入 用户
  <script>
       // 1.弹出输入框 输入内容后默认弹出输入的内容
        prompt('请输入你的年龄');
       // 2.alert 弹出警示框 输出的 展示给用户的
        alert('这是我的第一个js');
      // 3.console 控制台输出打印信息 给程序员测试用的 浏览器f12控制台左手第二个
        console.log('这是程序员能看到的');
  </script>

 

 

程序设计基础

1 - 变量概述

1.1 什么是变量

  • 为什么需要变量?有些数据需要保存,所以需要变量;

  • 变量是什么?变量相当一个容器,用来存储数据;

  • 本质?变量的本质是程序在内存中的一块存储空间;

  • 通过变量名找到变量,访问内存;

  • 变量的命名规范:见名知意-驼峰命名法;

1.2 - 变量的使用

  • 变量的声明

  • 变量的赋值

  • 变量的初始化

    1.声明变量

var age; // 声明一个名称为 age 的变量;本质是 在内存中申请一块存储空间

 

  • var 是一个 JS关键字,用来声明变量( variable 变量的意思 )。使用该关键字声明变量后,计算机会自动为变量分配内存空间,不需要程序员管;

  • age 是程序员定义的变量名,我们要通过 变量名来访问内存中分配的空间;

    2.赋值

age = 10; // 给 age 这个变量赋值为 10    

 

      
  • = 表示赋值,用来把右边的值赋给左边的变量空间

  • 变量值是程序员保存到变量空间里的值

    3.变量的初始化

声明一个变量的同时并赋值, 我们称之为变量的初始化。

var age  = 18;  // 声明变量同时赋值为 18

 

案例:

  • 弹出一个输入框,提示用户输入姓名;

  • 弹出一个对话框,输入 用户刚才输入的姓名;

    <script>
        // 1.用户输入姓名 存储到一个myname的变量里 变量是存储容器
        var myname = prompt('请输入姓名');
        // 2.输出这个用户名
        alert(myname);
        // alert('myname');加了单引号就显示不出变量名了
    </script>

 

 

1.3 变量语法扩展

1.更新变量

变量被重新复赋值后,它原有的值就会被覆盖,变量值将以最后一次赋的值为准。

var age = 18;
age = 81;   // 最后的结果就是81 因为18 被覆盖掉了 

 

         

2.同时声明多个变量

同时声明多个变量时,只需要写一个 var, 多个变量名之间使用英文逗号隔开。

var age = 10,  name = 'zs', sex = 2;     

 

3.声明变量特殊情况

情况说明结果
var age ; console.log (age); 只声明 不赋值 undefined
console.log(age) 不声明 不赋值 直接使用 报错
age = 10; console.log (age); 不声明 只赋值 10 可运行

案例:变量的语法扩展

    <script>
        // 1.更新变量 变量被重新赋值后,以最新一次为准
        var myname = '卡卡西';
        console.log(myname);
        myname = '火影';
        console.log(myname);//最新一次显示 火影 但之前的因为也输出了,也会有历史显示

        // 2.声明多个变量,可简写 只需写一个var,变量名间逗号隔开,分号表结束
        // var age = 18;
        // var address = '通辽';
        // var sex = 'nv';
        var age = 18,
            address = '通辽',
                sex = 'nv';

        // 3. 声明变量的特殊情况
        // 3.1 只声明 不赋值 结果是?undefined
        var sex;
        console.log(sex); // undefined
        // 3.2 不声明 不赋值 直接使用某个变量会报错
        console.log('tel');
        // 3.3 不声明直接赋值 js 可以使用
        qq = 110;
        console.log(qq); // 110
    </script>

 

案例:交换两个变量的值

js 是编程语言有很强的逻辑性在里面: 实现这个要求的思路 先怎么做后怎么做

// 思路:引入一个临时变量temp
    <script>
        var temp;
        var apple1 = '青苹果';
        var apple2 = '红苹果';
        temp = apple1;
        apple1 = apple2;
        apple2 = temp;
        console.log(apple1);
        console.log(apple2);
    </script>

 

1.4 变量命名规范

  • 由字母(A-Za-z)、数字(0-9)、下划线(_)、美元符号( $ )组成,如:usrAge, num01, _name

  • 严格区分大小写。var app; 和 var App; 是两个变量

  • 不能 以数字开头。 18age 是错误的

  • 不能 是关键字、保留字。例如:var、for、while

  • 变量名必须有意义。 MMD BBD nl → age

  • 遵守驼峰命名法。首字母小写,后面单词的首字母需要大写。

 

2 - 数据类型

2.1 数据类型简介

1.为什么需要数据类型?

在计算机中,不同的数据所需占用的存储空间是不同的,为了便于把数据分成内存所需的大小,充分利用存储空间,于是定义了不同的数据类型。

2.变量的数据类型?

变量的数据类型决定了以什么样的类型存储到计算机的内存中。JavaScript 是一种弱类型或者说动态语言。这意味着不用提前声明变量的类型;在程序运行过程中,变量的数据类型是由 JS引擎根据 = 右边变量值的数据类型来判断的。

var age = 10;// 这是一个数字型
var areYouOk = '是的';// 这是一个字符串     

 

JavaScript 拥有动态类型,同时也意味着相同的变量可用作不同的类型:

var x = 6;// x 为数字
var x = "Bill";// x 为字符串   

 

3.数据类型的分类

  • 简单数据类型 (Number,String,Boolean,Undefined,Null)

  • 复杂数据类型 (object)

2.2 简单数据类型

简单数据类型(基本数据类型)

简单数据类型说明默认值
Number 数字型,包含整形和浮点型,如21和0.21 0
String 字符串型,加了引号的都是字符串 “ ”、‘ ’
Boolean 布尔值型,返回值true、false,等价于1和0 false
Undefined var a;声明变量确没给值,此时a = undefined undefined
Null var a = null;声明了变量a为空值 null

1、数字型 Number

  <script>
   
        // 1.存储整形和浮点型
        var age = 21; // 整数
        var Age = 21.3747; // 小数

          // 2.存储各进制数值
        var num1 = 010; // 八进制
        var num2 = 0xff; // 十六进制

        // 3.数字型范围 三个特殊值
        alert(Number.MAX_VALUE); // 最大值
        alert(Number.MIN_VALUE); // 最小值
        alert(Infinity); // 无穷大
        alert(-Infinity); // 无穷小
        alert(NaN); // not a number,代表一个非数值

        console.log('Number.MAX_VALUE * 2'); // Infinity 无穷大
        console.log('-Number.MAX_VALUE * 2'); // -Infinity 无穷小

        console.log('pink老师' - 100);// NaN 非数值

        // 4.isNaN() 判断 非数字类型 并且返回一个值 
        // 是数字返回 false 不是返回true
        console.log(isNaN(12)); // false
        console.log(isNaN(userName)); // true 
 </script>

 

2、字符串型 String

(1)字符串型是引号内的任意文本,内部换行需要用转义字符 如 \ n

    <script>
        // 嵌套原则:外双内单 或 外单内双;
        var str = '我是一个"高富帅"的程序员';
        console.log(str);

        // 字符串转义字符  都是用 \ 开头 但是这些转义字符写到引号里面
        var str1 = "我是一个'高富帅'的\n程序员";
        console.log(str1);
    </script>

 

(2)字符串转义符

转义符解释说明
\n 换行符,n 是 newline 的意思
\ \ 斜杠 \
' ' 单引号
" ”双引号
\t tab 缩进
\b 空格 ,b 是 blank 的意思

(3)字符串拼接:

  • 多个字符串之间可以使用 + 进行拼接, 字符串 + 任何类型 = 新字符串类型

  • + 号总结口诀:数值相加 ,字符相连

    <script>
        // 1. 检测获取字符串的长度 length 
        var str = 'my name is andy';
        console.log(str.length); // 15

        // 2. 字符串的拼接 + 不同类型也可拼接 但最后是字符串型 
        // 数字型是结果 即:数值相加、字符相连
        console.log('沙漠' + '骆驼'); // 字符串的 沙漠骆驼
        console.log('pink老师' + 18); // 'pink老师18'
        console.log('pink' + true); // pinktrue
        console.log(12 + 12); // 24
        console.log('12' + 12); // '1212'
    </script>

 

(4)字符串拼接加强

  • 经常会将字符串和 变量 来拼接,变量可以很方便地修改里面的值

  • 变量是不能添加引号的,因为加引号的变量会变成字符串

  • 如果变量两侧都有字符串拼接,口诀“引引加加 ”,删掉数字,变量写加中间

    <script>
        console.log('pink老师 18 岁');
        //先写此句,然后删除18 引引加加 中间加变量
        
        var age = 18;
        console.log('pink老师' + age + '岁');// 引引加加
    </script>

 

案例:交互编程的三个基本要素

  • 用户输入:弹出一个输入框prompt,让用户输入年龄;

  • 程序内部处理:把用户输入的值作为变量保存起来,把刚才输入的年龄与所要输出的字符串拼接;

  • 输出结果:使用alert语句弹出警示框;

案例:显示年龄案例

    <script>
        var age = prompt('请输入你的年龄');
        var str = '你今年已经' + age + '岁了';
        alert(str);
    </script>

 

 

3、布尔型Boolean

  • 布尔类型有两个值:true 和 false ,其中 true 表示真,而 false 表示假;

  • 布尔型和数字型相加的时候, true 的值为 1 ,false 的值为 0;

console.log(true + 1);  // 2
console.log(false + 1); // 1

 

4、Undefined 和 Null

  • 一个声明后没有被赋值的变量会有一个默认值undefined ( 如果进行相连或者相加时,注意结果)

var variable;
console.log(variable);           // 只声明未赋值 输出 undefined
console.log('你好' + variable);  // 你好undefined
console.log(11 + variable);    // undefined 和数字相加 输出 NaN 
console.log(true + variable); //  NaN

 

  • 一个声明变量给 null 值,里面存的值为空(学习对象时,我们继续研究null)

var vari = null;
console.log('你好' + vari);  // 你好null
console.log(11 + vari);     // 11
console.log(true + vari);   //  1

 

2.3 获取变量数据类型

1.typeof 获取检测变量的数据类型

    <script>
        var num = 18;
        console.log(typeof num); // number
        var str = 'pink';
        console.log(typeof str); // string
        var flag = true;
        console.log(typeof flag); // boolean
        var vari = undefined;
        console.log(typeof vari); // undefined
        var timer = null;
        console.log(typeof timer); // object

        // prompt 取过来的值是 字符型的
        var age = prompt('请输入您的年龄');
        console.log(age);
        console.log(typeof age); // string
    </script> 

 

也可以通过控制台的颜色判断数据类型;黑色是字符串;

2.字面量

字面量表示如何表达这个值,一眼看上去知道这个属于什么类型的值。

    <script>
        console.log(18);// 数字字面量
        console.log('18');// 字符串字面量
        console.log(true);// 布尔字面量
        console.log(undefined);
        console.log(null);
    </script>

 

 

2.4 数据类型转换

什么是数据类型转换?就是把一种数据类型的变量转换成另一种数据类型,通常会实现3种方式的转换:

  • 转换为字符串类型

  • 转换为数字型

  • 转换为布尔型

1.转换为字符串

方式说明案例
加号拼接字符串 和字符串拼接的结果都是字符串 var num = 1;alert(num + '我是字符串');也称隐式转换
toString( ) 转成字符串 var num = 1;alert(num.toString( ));
String( )强制转换 转成字符串 var num = 1;alert(String(num));
    <script>
        // 1. 把数字型转换为字符串型变量 .toString()
        var num = 10;
        var str = num.toString();
        console.log(str);
        console.log(typeof str);
        // 2. 我们利用 String(变量)   
        console.log(String(num));
        // 3. 利用 + 拼接字符串的方法实现转换效果 隐式转换
        console.log(num + '');
    </script>

 

2.转换为数字型(重点)

方式说明案例
parseInt(string)函数 将string类型转换成整数数值型 parseInt('78')
parseFloat(string)函数 将string类型转换成浮点数值型 parseFloat('78.21')
Number()强制转换函数 将string类型转换成数值型 Number('12')
js隐式转换(- * /) 利用算数运算隐式转换为数值型 '12' - 0
    <script>
        var age = prompt('请输入你的年龄');
        // 1. parseInt(变量) 可以把字符型的转换成数字型 得到的是整数
        console.log(parseInt(age));
        console.log(parseInt('3.14')); // 整数 3
        console.log(parseInt('120px')); // 整数 120 单位px被去掉
        console.log(parseInt('rem120px')); // NaN 首字母检测不是数字

        // 1. parseFloat(变量) 可以把字符型的转换成浮点型 得到的是浮点数
        console.log(parseFloat('3.14')); // 3.14
        console.log(parseFloat('120px')); // 单位也会去掉

        // 3. Number(变量)
        var str = '123';
        console.log(Number(str));
        console.log(Number('12'));

        // 4. 利用了算术运算 - * / 隐式转换(不能 +)
        console.log('12' - 0); // 数字型 12,先把数字转为数字型在-
        console.log('123' - '120'); // 3

        console.log('123' + '120'); // 123120 + 是字符串拼接,
    </script>

 

 

案例:输出年龄

思路:

  • 弹出一个输入框(prompt),让用户输入出生年份(用户输入)

  • 把用户输入的值用变量保存起来,用今年年份减去变量值,就是现在的年龄(程序内部处理)

  • 弹出警示框(alert),把计算的结果输出(输出结果)

    <script>
        var year = prompt('请输入你的出生年份');
        var age = 2020 - year;// year是字符串 减法隐式转换 成数字型
        alert('你今年已经 ' + age + ' 岁了');
    </script>

 

案例:简单加法器

要求:计算两个数的值,用户输入第一个值后,继续弹出第二个输入框并输入第二个值,最后弹出窗口显示两次输入值相加的结果。

    <script>  
        var num1 = prompt('请输入第一个值:');
        var num2 = prompt('请输入第二个值:');
        var result = parseFloat(num1) + parseFloat(num2);
        alert('结果是:' + result);
    </script>

 

3.转换为布尔型

  • 代表空、否定的值会被转换为 false ,如 ''、0、NaN、null、undefined ;

  • 其余值都会被转换为 true;

console.log(Boolean('')); // false
console.log(Boolean(0)); // false
console.log(Boolean(NaN)); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false

console.log(Boolean('小白')); // true
console.log(Boolean(12)); // true

 

 

3 - 标识符、关键字、保留字

3.1 标识符

标识(zhi)符:就是指开发人员 为变量、属性、函数、参数取的名字。
标识符不能是关键字或保留字。

3.2 关键字

关键字:是指 JS本身已经使用了的字,不能再用它们充当变量名、方法名。

包括:break、case、catch、continue、default、delete、do、else、finally、for、function、if、in、instanceof、new、return、switch、this、throw、try、typeof、var、void、while、with 等。

3.3 保留字

保留字:实际上就是预留的“关键字”,意思是现在虽然还不是关键字,但是未来可能会成为关键字,同样不能使用它们当变量名或方法名。

包括:boolean、byte、char、class、const、debugger、double、enum、export、extends、fimal、float、goto、implements、import、int、interface、long、mative、package、private、protected、public、short、static、super、synchronized、throws、transient、volatile 等。

注意:如果将保留字用作变量名或函数名,那么除非将来的浏览器实现了该保留字,否则很可能收不到任何错误消息。当浏览器将其实现后,该单词将被看做关键字,如此将出现关键字错误。

3.4 标识符命名规范

  • 变量、函数的命名必须要有意义

  • 变量的名称一般用名词

  • 函数的名称一般用动词

  • 操作符(=)、括号、左右各留一个空格;

    注释后面打一个空格;

     

4 - 运算符(操作符)

4.1 运算符的分类

运算符(operator)也被称为操作符,是用于实现赋值、比较和执行算数运算等功能的符号。

JavaScript中常用的运算符有:
    - 算数运算符  + - * / %
    - 递增和递减运算符  ++ --
    - 比较运算符  > < >= <= != ==
    - 逻辑运算符  && || !
    - 赋值运算符  =

4.2 算数运算符

1.算术运算符概述

概念:算术运算使用的符号,用于执行两个变量或值的算术运算。

运算符描述实例
+ 10+20=30
- 10-20=-10
* 10*20=200
/ 10/20=0.5
% 取余数(取模) 返回除法的余数 9%2=1

2.浮点数的精度问题

浮点数值的最高精度是 17 位小数,但在进行算术计算时其精确度远远不如整数。

    var result = 0.1 + 0.2; // 结果是:0.30000000000000004
    console.log(0.07 * 100); // 结果是:7.000000000000001
    // 所以:不要直接判断两个浮点数是否相等 !

 

3.表达式和返回值

表达式:是由数字、运算符、变量等组成的式子

表达式最终都会有一个结果,返回给开发者,称为返回值

 

4.3 递增和递减运算符

如果需要反复给数字变量+1或-1可以使用递增(++)和递减(--)运算符来完成。
在 JavaScript 中,递增(++)和递减(--)既可放在变量前,也可以放变量后面 前置递增和后置递增。
注意:前置递增和后置递增在单独使用时,效果是一样的;在表达式里,有所不同;

递增运算符

  • 前置递增运算符 “++变量”:

    使用口诀:先自加,后返回值 ++num——num = num + 1;

    var  num = 10;
    alert(++num + 10);   // num = 11  11+10=21

 

  • 后置递增运算符 “变量++”:

    使用口诀:先原值运算,后自加 num++ —— num = num + 1 ;

    var  num = 10;
    alert(10 + num++);  // num = 11 10+10=20

 

案例:递增运算符:

    <script>
        var a = 10;
        ++a; // ++a  11    a = 11
        var b = ++a + 2; // a = 12
        console.log(b); // 14

        var c = 10;
        c++; // c++ 11 
        var d = c++ + 2; //  c++  = 11+2     c = 12
        console.log(d); // 13

        var e = 10;
        var f = e++ + ++e; // 1. e++ =  10  e = 11  2. e = 12  ++e = 12
        console.log(f); // 10 + 12 = 22
        // 后置自增  先表达式返回原值 后面变量再自加1
    </script>

 

 

4.4 比较运算符

  • 比较运算符概述

    概念:比较运算符(关系运算符)是两个数据进行比较时所使用的运算符,比较运算后,会返回一个布尔值(true / false)作为比较运算的结果。

    运算符名称说明案例结果
    < 小于号 1<2 true
    > 大于号 1>2 false
    >= 大于等于号 2>=2 true
    <= 小于等于号 2<=3 false
    == 判断号(会转型) 37==37 true
    != 不等号 37!=37 false
    === !== 全等 要求值和数据类型都一致 37==='37' false

     

  • 等号比较

    符号作用用法
    = 赋值 等号右侧的值赋给左侧
    == 判断 判断两边的值是否相等(注意隐式转换)
    === 全等 判断两边的值和数据类型是否完全相同

    实例:比较运算符

            //1. 我们程序里面的 == 是判断两边值是否相等
            console.log(3 == 5); // false
            console.log('pink老师' == '刘德华'); // flase
            console.log(18 == 18); // true
            console.log(18 == '18'); // true
            console.log(18 != 18); // false
            // 2. 我们程序里面有全等 一模一样  要求 两侧的值 还有 数据类型完全一致才可以 true
            console.log(18 === 18);
            console.log(18 === '18'); // false

     

4.5 逻辑运算符

  • 逻辑运算符概述

    逻辑运算符是用来进行布尔值运算的运算符,其返回值也是布尔值。

    逻辑运算符说明案例
    && "逻辑与" ’与‘ and true && false
    || "逻辑或" ’或‘ or true || false
    "逻辑非" ’非‘ not ! true

    案例:逻辑运算符

            <script>
            // 1. 逻辑与 &&  and 两侧都为true  结果才是 true  只要有一侧为false  结果就为false 
            console.log(3 > 5 && 3 > 2); // false
            console.log(3 < 5 && 3 > 2); // true
            // 2. 逻辑或 || or  两侧都为false  结果才是假 false  只要有一侧为true  结果就是true
            console.log(3 > 5 || 3 > 2); // true 
            console.log(3 > 5 || 3 < 2); // false
            // 3. 逻辑非  not  ! 
            console.log(!true); // false
        </script>

     

     

  • 短路运算(逻辑中断)

    逻辑运算符左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值;

    // 1.逻辑与 短路运算
    //如果第一个表达式为真,则返回表达式2;如果第一个为假,则返回表达式1;
    console.log(123 && 456);//456
    console.log(0 && 456 + 1 && 2);// 0
    console.log('' && 1 + 2 && 456 * 56789); // ''
    // 空或者否定的为假 其余是真  0 ‘’ null undefined NaN 为假;

    // 2.逻辑或 短路运算
    //如果表达式1 结果为真 则返回表达式1 如果结果为假,则返回表达式2
    console.log(123 || 456);//123
    console.log(0 && 456 + 1 && 2);//456 继续向后运行

 

4.6 赋值运算符

概念:用来把数据赋值给变量的运算符。

赋值运算符说明案例
= 直接赋值 var name = '值';
+=、-= 加、减一个数后在赋值 var age = 10; age+=5; // 15
*=、/=、%= 乘、除、取模后再赋值 var age = 2; age*=5; // 10

案例:赋值运算符

    var age = 10;
    age += 5;  // 相当于 age = age + 5;
    age -= 5;  // 相当于 age = age - 5;
    age *= 10; // 相当于 age = age * 10;

 

 

4.7 运算符优先级

优先级运算符顺序
1 小括号 ( )
2 一元运算符 ++ -- !
3 算术运算符 先 * / % 后 + -
4 关系运算符 > >= < <=
5 相等运算符 == != === !==
6 逻辑运算符 先 && 后 ||
7 赋值运算符 =
8 逗号运算符 ,
  • 一元运算符里面的逻辑非优先级很高

  • 逻辑与比逻辑或优先级高

 

5 - 流程控制

5.1 流程控制概念

流程控制就是来控制代码按照一定结构顺序来执行
流程控制主要有三种结构:顺序结构、分支结构、循环结构

5.2 顺序流程控制

特点:从上到下,依次执行

5.3 分支流程控制

特点:根据不同的条件,执行不同的路径代码(多选一的过程)得到不同的结果;

JS 语言提供了两种分支结构语句:if 语句、switch 语句

5.4 if 语句

       // 1. if语句 
        // 条件表达式成立 则执行代码,否则什么也不做
        if (条件表达式) {
            // 条件成立执行的代码语句
        }
        // 2. if else 双分支语句
        // 分支语句 2选1过程 最终只有一条语句执行
        if (条件表达式) {
            语句1;//如果条件成立则执行语句1
            }
        else { 语句2 };//条件不成立执行语句2

         // 3. 多分支语句 
        // 最后也是只有一个语句执行 else if任意多,都不成立执行 else
        if (条件表达式1) {
            语句1;
        } else if (条件表达式2) {
             语句2;      
        } else {
            最后的语句;
        }

        // 4. 三元表达式 条件表达式 ?表达式1 :表达式2
       // 如果条件表达式为真,则返回表达式1,否则返回表达式2,表达式有返回值
        var num = 10;
        var result = num > 5 ? '是的' : '不是的'; // 我们知道表达式是有返回值的
        console.log(result);

        // if (num > 5) {
        //     result = '是的';
        // } else {
        //     result = '不是的';
        // }

 

案例:判断是否闰年 (if ...else...)

// 算法:能被4整除且不能整除100的为闰年,或者能够被400整除的就是闰年
    <script>
        var year = prompt('请您输入年份:');
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
            alert('您输入的年份是闰年');
        } else {
            alert('您输入的年份是平年');
        }
    </script>

 

案例:判断成绩级别 (if ...else if ...else...)

// 思路:从大到小的顺序,否则 就都输出了
    <script>
        var score = prompt('请您输入分数:');
        if (score >= 90) {
        alert('宝贝,你是我的骄傲');
        } else if (score >= 80) {
        alert('宝贝,你已经很出色了');
        } else if (score >= 70) {
        alert('你要继续加油喽');
        } else if (score >= 60) {
        alert('孩子,你很危险');
        } else {
        alert('熊孩子,我不想和你说话,我只想用鞭子和你说话');
    </script>

 

案例:数字补0案例 (条件表达式 ? 表达式1 : 表达式2)

// 思路:用户输入一个0-59之间的数字,如果小于10,在这个数字前面补0(加0 拼接) 
    <script>
        var time = prompt('请您输入一个 0 ~ 59 之间的一个数字');
        // 三元表达式 表达式 ? 表达式1 :表达式2 
        var result = time < 10 ? '0' + time : time; 
        alert(result);
    </script>

 

 

5.5 switch分支流程控制

  • switch :开关 转换 , case :小例子 选项

  • 关键字 switch 后面括号内可以是表达式或值, 通常是一个变量,不用数值;

  • 如果表达式与case后面得值 存在匹配全等(===) ,则与该 case 关联的代码块会被执行,并在遇到 break 时停止,整个 switch 语句代码执行结束

  • 如果所有的 case 的值都和表达式的值不匹配,则执行 default 里的代码

  • 注意: 执行case 里面的语句时,如果没有break,则继续执行下一个case,不会退出switch

特点:switch后面的表达式是 固定值,通常是变量,优点是可以直接跳转到特定的case语句;

// 思路:利用我们的表达式的值 和 case 后面的选项值相匹配 如果匹配上,就执行该case 里面的语句  如果都没有匹配上,那么执行 default里面的语句
    switch(表达式) {
        case value1: 执行语句1; break;
        case value2: 执行语句2; break;
        default: 最后的语句;
    }

 

案例:查询水果价格 switch()

        // 弹出 prompt 输入框,让用户输入水果名称,把这个值取过来保存到变量中。
        // 将这个变量作为 switch 括号里面的表达式。
        // case 后面的值写几个不同的水果名称,注意一定要加引号 ,因为必须是全等匹配。
        // 弹出不同价格即可。

        var fruit = prompt('请您输入查询的水果:');
        switch (fruit) {
        case '苹果':
        alert('苹果的价格是 3.5/斤');
        break;
        case '榴莲':
        alert('榴莲的价格是 35/斤');
        break;
        default:
        alert('没有此水果');
    }    

 

5.5 switch 语句和 if else if 语句的区别

  • 一般情况下,它们两个语句可以相互替换

  • switch用于处理case比较确定的情况,如固定值的;进行条件判断后直接执行到程序的条件语句,效率更高;

  • if else更加灵活,常用于范围判断(大于 小于);但if else有几种条件就判断多少次;分支较少时效率较高;

 

6 - 循环

循环的目的:可以重复执行某些代码

JS三种循环结构:

  • for循环:常用于 计数

  • while循环:复杂一点的条件判断,比for灵活

  • do...while循环:比while严谨

三个循环很多情况可以相互转换;

6.1 for循环

重复执行某些代码,通常和计数有关系

    // 1. 语法结构
    for (初始化变量; 条件表达式; 操作表达式) {
        //循环体
    }

    //1.初始化变量 就是用 var声明一个普通变量,常用于作为计数器
    //2.条件表达式 用来决定每一次循环是否继续执行 终止的条件
    //3.操作表达式 每次循环最后执行的代码 常用于计数器变量递增减

    for (var i = 1; i <= 100; i++) {
        console.log('你好吗');
    }
    //1.先赋初值 var i = 1 整个循环只执行一次
    //2.在执行 i <= 100 条件成立执行循环语句 不成立跳出循环
    //3.条件成立的话 接下来执行console.log('')
    //4.最后执行i++ i++是单独写的代码 递增  第一轮结束
    //5.接着执行 i <= 100 如果满足条件 就去执行循环体 不满足条件退出循环 第二轮

 

for循环执行方式

    <script>
        // 1.for循环 重复执行相同代码
        // 让用户 控制 输入的次数
        var num = prompt('请输入次数');
        for (var i = 1; i <= num; i++) {
            alert('hello world');
            // console.log('hello world');
        }

        // 2.for循环 重复执行不同的代码 因为我们有计数器变量 i 的存在 i每次循环值都会变化
        // 计数器 输出一个人 1~100岁
        for (var i = 1; i <= 100; i++) {
            console.log('这个人今年' + i + '岁了');
        }
    </script>

 

案例:有关for循环的算法

    <script>
    // 1. 求 1~100 之间的整数累加和 算法:sum = sum + i  5050;   
        var sum = 0;// 求和变量 初始值为0
        for (var i = 1; i <= 100; i++) {
            // sum = sum + i;
            sum += i;
        }
        console.log(sum);

    // 2. 求1~100间的所有数的平均值 需要一个 sum 和的变量 还需要一个平均值 average 的变量  50.5
        var sum = 0;
        var average = 0;
        for (var i = 1; i <= 100; i++) {
            sum = sum + i;
            // sum += i;
        }
        average = sum / 100;
        console.log(average);

   // 3. 求1~100间所有偶数和奇数的和 需要一个偶数和even 和一个奇数和odd
        var even = 0;
        var odd = 0;
        for (var i = 1; i <= 100; i++) {
            if (i % 2 == 0) {
                even = even + i;
            } else {
                odd = odd + i;
            }
        }
        console.log('1~100之间的所有偶数和是' + even);
        console.log('1~100之间的所有奇数和是' + odd);
    </script>

 

案例:求学生成绩案例

    <script>
        // 思路:
        // 1. 弹出输入框输入总得班级人数(num)
        // 2. 依次输入学生成绩并保存(score)
        // 3. for循环 弹出的次数与班级总人数之间的关系 i <= num
        // 4. 先求总成绩 sum ,之后求平均成绩 average 弹出结果
        var num = prompt('请输入班级的总人数');// num 总的班级人数
        var sum = 0;
        var average = 0;
        for (var i = 1; i <= num; i++) {
            var score = prompt('请输入第' + i + '个学生成绩');
            sum = sum + parseFloat(score);
        }
        average = sum / num;
        alert('班级总成绩是' + sum);
        alert('班级的平均分是' + average);
    </script>

 

案例:打印五角星

  <script>
        //     一行打印五个星星 
        // console.log('★★★★★');
        //     循环打印5次
        // for (var i = 1; i <= 5; i++) {
        //     console.log('★');
        // }
    
    // 1.一行打印五颗星星 追加字符串的方法-是一行打印多少个,不是循环多少次一行一个
        // var str = '';
         // for (i = 1; i <= 5; i++) {
        //     str = str + '★';
        // }
    
    // 2.取决于用户输入
        var num = prompt('请输入星星的个数');
        var str = '';
        for (i = 1; i <= num; i++) {
            str = str + '★';
        }
        console.log(str);
    </script>

 

 

双重for循环

双重for循环:

    <script>
        // 1.语法结构 
        for (外层的初始化变量; 外层的条件表达式; 外层的操作表达式) {
            for (里层的初始化变量; 里层的条件表达式; 里层的操作表达式) {
                执行语句;
            }
        }
        //  内层循环可以看做外层循环的循环体语句
        //  外层循环执行一次,内层循环 执行全部
        //  总共执行了 i*j 次

        for (var i = 1; i <= 3; i++) {
            console.log('这是外层循环第' + i + '次');
            for (var j = 1; j <= 3; j++) {
                console.log('这是内层循环第' + j + '次');
            }
        }
    </script>

 

案例:打印n行n列五角星

    <script>
        var rows = prompt('请你输入行数:');
        var cols = prompt('请你输入列数:');
        var str = '';
        for (var i = 1; i <= rows; i++) { // 外层循环负责 打印i行

            for (var j = 1; j <= cols; j++) { // 内层循环负责 一行打印j个
                str = str + '★';
            }
            // 如果一行打印完毕j个星星就要另起一行 加 \n
            str = str + '\n'; // 字符串拼接 追加字符串
        }
        console.log(str);
    </script>

 

案例:打印 倒三角

    <script>
        var str = '';
        for (var i = 1; i <= 10; i++) { //外层循环控制行数
            for (var j = i; j <= 10; j++) { 
                //内层循环打印个数不一样 j=i=1,从1~10打印10个
                str = str + '★';
            }
            // 如果一行打印完毕j个星星就要另起一行 加 \n
            str = str + '\n';
        }
        console.log(str);
    </script>

 

案例:打印九九乘法表(正三角)

       // 一共有9行,但是每行的个数不一样,因此需要用到双重 for 循环
       // 外层的 for 循环控制行数 i ,循环9次 ,可以打印 9 行  
       // 内层的 for 循环控制每行公式  j 
 	  // 核心算法:每一行 公式的个数正好和行数一致, j <= i;
      // 每行打印完毕,都需要重新换一行
    <script>
        str = '';
        for (i = 1; i <= 9; i++) {
            for (j = 1; j <= i; j++) {
                // str = str + '★';
                // str += i + 'x' + j + '=' + i * j;
                str += j + 'x' + i + '=' + i * j + '\t';
                //为了符合列匹配关系
            }
            str = str + '\n';
        }
        console.log(str);
   </script>

 

for 循环小结

  • for 循环可以重复执行某些相同代码

  • for 循环可以重复执行些许不同的代码,因为我们有计数器

  • for 循环可以重复执行某些操作,比如算术运算符加法操作

  • 双重 for 循环,外层循环一次,内层 for 循环全部执行

  • for 循环是循环条件和数字直接相关的循环

断点调试:

  • 浏览器中f12打开调试器窗口

  • 单击某条语句设置断点,并刷新浏览器

  • 右上角 步进 进行一步步调试,看程序怎样运行的

 

6.2 while循环

while语句的语法结构如下:

使用 while 循环时一定要注意,它必须要有退出条件,否则会成为死循环

    <script>
        // 1. while 循环语法结构 while 当...的时候
        // 2.执行思路 当条件表达式为true时 执行循环体 否则 退出循环
         while (条件表达式) {
             循环体
         }
       
        // 3.代码验证
        var num = 1;// 初始化变量 计数器
        while (num <= 100) {
            console.log('hello');
            num++; // 操作表达式 完成计数器的更新 防止死循环 不加限制会变成死循环 一定要有退出条件
        }

        // 转换写法
        for (num = 1; num <= 100; num++) {
            console.log('hello');
        }
    </script>

 

案例:while循环 输出人的年龄

    <script>
        // while循环案例
        // 1.打印人的一生,从1岁到100岁
        var i = 1;
        while (i <= 100) {
            console.log('这个人今年' + i + '岁了');
            i++;
        }

        // 2.计算1~100之间所有的整数和
        var sum = 0;
        var j = 1;
        while (j <= 100) {
            sum = sum + j;
            j++;
        }
        console.log(sum);

        // 3.弹出一个提示框,你喜欢我么? 如果输入喜欢,就提示结束,否则 一直询问
        var message = prompt('你喜欢我么?');
        while (message !== '喜欢') {
            message = prompt('你喜欢我么');
        }
        alert('我也喜欢你啊');
    </script>

 

 

6.3 do-while循环

比while更简单一些;

while是先判断后循环;do...while是先执行,后判断,至少执行一次;

    <script>
        // 1.语法结构  先循环,在判断,至少执行一次
        do {
            //循环体
        } while (条件判断);

        // 2.代码
        var i = 1;
        do {
            console.log('how are you');
            i++;
        } while (i <= 100)
            
        do {
            var message = prompt('你喜欢我么?');
        } while (message !== '喜欢')
         alert('我也喜欢你啊');
    </script>

 

 

6.4 continue、break

1.continue 关键字用于立即跳出本次循环

继续下一次循环(本次循环体中 continue 之后代码会少执行一次)

案例:吃5个包子,第3个有虫子,就扔掉第3个,继续吃第4个第5个包子,代码实现如下

     for (var i = 1; i <= 5; i++) {
         if (i == 3) {
             console.log('这个包子有虫子,扔掉');
             continue; // 跳出本次循环,跳出的是第3次循环 
          }
          console.log('我正在吃第' + i + '个包子呢');
     }

    //1. 求 1~100 之间,除了能被7整除之外的 整数和
        var sum = 0;
        for (var i = 1; i <= 100; i++) {
            if (i % 7 == 0) {
                continue;// 退出本次循环 直接跳到 i++
            }
            sum += i;
            console.log(sum);
        }
    </script>

 

2.break 关键字用于立即跳出整个循环(循环结束)

案例:吃5个包子,吃到第3个发现里面有半个虫子,其余的不吃了,其代码实现如下

  for (var i = 1; i <= 5; i++) {
     if (i == 3) {
         break; // 直接退出整个for 循环,跳到整个for下面的语句
     }
     console.log('我正在吃第' + i + '个包子呢');
   }

 

 

7 - 数组

为什么需要数组?

普通变量一次只能存一个值;数组(Array)是一组数据的集合,一次可以存多个值;

7.1 数组的概念

数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。

7.2 创建数组

JS 中创建数组有两种方式:

  • 利用new 关键字 创建数组(对象)

var 数组名 = new Array() ;
var arr = new Array();   // 创建一个新的空数组

 

  • 利用数组字面量创建数组

var  数组名 = [];
// 使用数组字面量方式创建带初始值的数组 数组类型不限
var  数组名 = [1,'pink',true];// 数组的初始化

 

7.3 获取数组中的元素

索引 (下标) :用来访问数组元素的序号(数组下标从 0 开始)。

数组可以通过索引来访问、设置、修改对应的数组元素,可以通过“数组名[索引]”的形式来获取数组中的元素。

        // 4. 我们数组里面的数据一定用逗号分隔
        // 5. 数组里面的数据 比如1,2, 我们称为数组元素
        // 6. 获取数组元素  格式 数组名[索引号]  索引号从 0开始 
        console.log(arr1);
        console.log(arr1[1]); // pink老师
        console.log(arr1[2]); // true   

 

注意:如果访问时数组没有和索引值对应的元素,则得到的值是undefined

7.4 遍历数组

把数组中的每个元素 从头到尾 都访问一次(类似学生的点名)称为遍历数组;

for循环中的 i 是计数器,当索引号使用,arr[i] 是数组元素 第i个数组元素,索引号从0开始

    <script>
        // 1.数组索引 访问数组中某个元素
        var arr = ['red', 'green', 'blue'];
        console.log(arr[0]);// red

        // 2.遍历数组 通过for循环访问数组所有元素
        //   因为数组索引号从0开始,所以i必须从0开始 i < 3
        //   输出的时候 arr[i] i 计数器 当索引号来用
        var arr = ['red', 'green', 'blue'];
        for (var i = 0; i < arr.length; i++) {
            console.log(arr[i]);
        }
        // 数组名.length 可以直接获取数组长度 动态监测数组元素的个数
        console.log(arr.length);// 此处数组的长度是数组元素的个数,并非索引
    </script>

 

案例:求数组里面所有元素的和及平均值

    <script>
        // 1.声明一个求和变量 sum
        // 2.遍历这个数组,把里面每个数组元素 加到sum 里
        // 3.用求和变量 sum 除以数组的长度得到数组的平均值
        var arr = [2, 4, 1, 7, 4];
        var sum = 0;
        var average = 0;
        for (i = 0; i < arr.length; i++) {
            // sum+=i;// 加的不是计数器,是数组里的元素
            sum += arr[i];
        }
        average = sum / arr.length;
        console.log('这组数的和是:' + sum);
        console.log('这组数的平均值是:' + average);
        console.log(sum, average); // 想要输出多个变量,用逗号分隔即可
    </script>

 

案例:求数组 [2,6,1,77,52,25,7] 中的最大值

    <script>
        // 1.声明一个求和变量 max 默认最大值可以取数组中的第一个元素
        // 2.遍历这个数组,把里面每个数组元素和 max 相比较
        // 3.如果这个数组元素大于max 就把这个数组元素存到 max 里面,否则继续下一轮比较。
        var arr = [2, 6, 1, 77, 52, 25, 7];
        var max = arr[0];// 将数组第一个值赋值给max
        for (i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        console.log('该数组里最大的是:' + max);
    </script>

 

案例:将数组元素转换为字符串,中间用任意字符相连

        // 将数组 ['red', 'green', 'blue', 'pink'] 转换为字符串,并且用 | 或其他符号分割
        // 1.需要一个新变量用于存放转换完的字符串 str。
        // 2.遍历原来的数组,分别把里面数据取出来,加到字符串里面。
        // 3.同时在后面多加一个分隔符    
    <script> 
        var arr = ['red', 'green', 'blue', 'pink'];
        var str = '';
        var sep = '|';
        for (i = 1; i < arr.length; i++) {
            str += arr[i] + sep;
        }
        console.log(str);
    </script>

 

注意

  • 此处数组的长度是数组元素的个数 ,不是数组的索引号(下标号)。

  • 当我们数组里面的元素个数发生了变化,这个 length 属性跟着一起变化;数组的length属性可以被修改:

  • 如果设置的length属性值大于数组的元素个数,则会在数组末尾出现空白元素;

  • 如果设置的length属性值小于数组的元素个数,则会把超过该值的数组元素删除

7.5 数组中新增元素

1、通过修改length长度新增数组元素,通过length长度实现数组的扩容

2、通过修改数组索引新增数组元素,追加数组元素

    <script>
        // 1.新增数组元素 修改length长度
        var arr = ['red', 'green', 'blue'];
        console.log(arr.length);
        arr.length = 5;// 数组长度修改为5 里面应该有5个元素
        console.log(arr);// 后面两个是空的 undefined

        // 2.新增数组元素 修改索引号 追加数组元素
        var arr1 = ['red', 'green', 'blue'];
        arr1[3] = 'pink';
        console.log(arr1);
        arr1[4] = 'hotpink';
        console.log(arr1);
        arr1[0] = 'yellow';// 替换原来的数组元素
        console.log(arr1);

        arr1 = '有点意思';// 不要直接给 数组名赋值 否则里面的数组元素都没有了
        console.log(arr1);
    </script>

 

 

案例:数组存放0~10个值,循环追加的方式输出

    <script>
        var arr = [];// 定义一个空数组
        for (var i = 0; i < 10; i++) {// 遍历数组
            // arr=i;// 不要直接给数组名赋值 否则以前的元素都没了
            arr[i] = i + 1;// i是数组下标 下标为0的数组对应着 第一个数组元素
        }
        console.log(arr);
    </script>

 

案例:筛选数组 筛选数组中大于10的数存入新数组

    <script>
        // 方法一
        var arr = [1, 2, 3, 4, 5, 6, 7, 8, 19, 10];
        var newArr = [];// 声明一个新的数组存放新数据
        var j = 0;// 方法1 声明一个新变量
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] >= 10) {
                // 新数组索引号应该从0开始 依次递增
                newArr[j] = arr[i];
                // 在旧数组里找出大于等于10的元素 依次追加给新数组
                j++;
            }
        }
        console.log(newArr);

        // 方法二
        var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        var newArr = [];// 声明一个新的数组存放新数据
        // 刚开始 newArr.length 就是0
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] >= 10) {
                // 新数组索引号应该从0开始 依次递增
                newArr[newArr.length] = arr[i];
            }
        }
        console.log(newArr);
    </script>

 

案例:删除数组指定元素,数组去重 删除数组中的0

    // 1、需要一个新数组用于存放筛选之后的数据。
    // 2、遍历原来的数组, 把不是 0 的数据添加到新数组里面(此时要注意采用数组名 + 索引的格式接收数据)。
    // 3、新数组里面的个数, 用 length 不断累加。
    <script>
        var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        var newArray = [];
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] != 0) {
                newArray[newArray.length] = arr[i];
            }
        }
        console.log(newArray);
    </script>

 

案例:翻转数组 将数组中的内容反过来存放

    // 1、声明一个新数组 newArr
    // 2、把旧数组索引号第4个取过来(arr.length - 1),给新数组索引号第0个元素 (newArr.length)
    // 3、我们采取 递减的方式  i--
  // 思路:把 旧数组 的 最后一个元素 取出来给 新数组 作为第一个  (递减)  
    <script>
        var arr = ['red', 'green', 'blue', 'pink', 'purple'];
        var newArr = [];
        for (var i = arr.length - 1; i >= 0; i--) {
            newArr[newArr.length] = arr[i];
        }
        console.log(newArr);
    </script>

 

案例:数组排序 交换相邻两个变量(冒泡排序)

冒泡排序:一种算法,把一系列数据按照一定的顺序排列,依次比较相邻两个元素;

    <script>
        var arr = [5, 4, 3, 2, 1];
        for (var i = 0; i <= arr.length - 1; i++) { // 外层交换趟数 5个元素交换4趟
            for (var j = 0; j <= arr.length - i - 1; j++) 
                //里层循环 负责每一趟的交换次数
            {
                // 内部交换2个变量的值 前一个和后面一个数组元素相比较
                if (arr[j] > arr[j + 1]) {
                    var temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        console.log(arr);
    </script>

 

 

8 - 函数

8.1 函数的概念

函数:就是封装了一段可被重复调用执行的代码块

通过此代码块可以实现大量代码的重复使用

8.2 函数的使用

函数使用分为两步: 声明函数 和 调用函数;

     // 1.声明函数  函数名 命名为动词
    // (1) function 声明函数的关键字 全部小写
     // (2) 函数是做某件事情,函数名一般是动词 sayHi 
     // (3) 函数不调用自己不执行
    function 函数名() {
        //函数体代码
    }
// 2.调用函数 函数名(); // 通过调用函数名来执行函数体代码 函数不调用 自己不执行 function sayHi() { console.log('hi~~'); } sayHi();

 

注意:声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码。

案例:利用函数封装计算1-100累加和

        // 1.声明函数
        function getSum(num1,num2) {
            var sum = 0;// 准备一个变量,保存数字和
            for (var i = num1; i <= num2; i++) {
                sum += i;// 把每个数值 都累加 到变量中
            }
            alert(sum);
        }
        // 2.调用函数
        getSum(1,100);

 

8.3 函数的参数

  • 形参:形式上的参数 声明函数时定义 可看做不用声明的变量

  • 实参:实际上的参数 函数调用时传递的 最终实参传递给形参

函数参数的运用:

        // 1.函数声明 声明形参
        function 函数名(形参1, 形参2, 形参3...) {
            // 函数体
        }
        // 2.函数调用 调用实参
        函数名(实参1, 实参2, 实参3...); 

        // 声明函数
        function getSum(num1, num2) {
            console.log(num1 + num2);
        }
        // 调用函数
        getSum(1, 3); // 4 先将实参传递给形参 在执行函数体
        getSum(6, 5); // 11

 

函数形参和实参数量不匹配时

参数个数说明
实参个数等于形参个数 输出正确结果
实参个数多于形参个数 值取到形参个数
实参个数小于形参个数 多的形参定义为undefined,结果NaN
注意:在JavaScript中,形参的默认值是undefined。

案例:函数的执行

// 1.函数可以重复相同的代码
    function cook() {
        console.log('hello');
    }
    cook();

// 2.也可以利用函数的参数 实现函数重复不同的代码
    function 函数名(形参1,形参2...) { // 声明的小括号里是形参 形式上的
        
    }
    函数名(实参1,实参2...);// 函数调用的小括号里是实参 实际的

    function cook(aru) { // 形参是接收实参的 aru='hello' 相当于一个不用声明的变量
        console.log(aru);
    }
    cook('hello');// 形参和实参个数尽量相匹配
// 1.利用函数求任意两个数之间的和
    function getSum(num1,num2) {
        console.log(num1 + num2);
    }
    getSum(1, 3);
    getSum(2, 6);
// 2.利用函数求任意两个数之间的累加和 function getSum(start, end) { var sum = 0; for (var i = start; i <= end; i++) { sum += i; } console.log(sum); } getSum(1, 100);

 

8.4 函数的返回值return

return 语句

函数只是用来做某件事或实现某种功能,最终的结果需要返回给函数的调用者;
只要函数遇到return 就把后面的结果 返回给函数的调用者  函数名()= return + 后面
   // 声明函数
    function 函数名(){
        ...
        return  需要返回的值;
    }
    // 调用函数
    函数名();// 此时调用函数就可以得到函数体内return 后面的值

    // 声明函数
    function sum(){
     ...
     return 666;
    }
    // 调用函数
    sum(); // 此时sum = 666,return 语句会把自身后面的值返回给调用者

 

  • 在使用 return 语句时,函数会停止执行,并返回指定的值

  • 如果函数没有 return ,返回的值是 undefined

    // 1.利用函数求任意两个数之和
        function getResult(num1,num2) {
            return num1 + num2;
        }
        //getResult();// getResult = num1+num2
        console.log(getResult(1,2));

    // 2.利用函数求两个数中最大值
        function getMax(num1,num2) {
            // if (num1 > num2) {
            //     return num1;
            // } else {
            //     return num2;
            return num1 > num2 ? num1 : num2;
        }
        console.log(getMax(1, 3));

    // 3.利用函数求数组中的最大值
        function getArrMax(arr) { // arr接收一个数组
            var max = arr[0];
            for (var i = 1; i<=arr.length; i++) {
                if (arr[i] > max) {
                    max = arr[i];
                }
            }
            return max;
        }
        // getArrMax([1,2,3,4,5]);// 实参是一个数组
        // 实际开发中,常用一个变量 来接收 函数的返回结果
        var re = getArrMax([1,2,3,4,5]);
        console.log(re);

 

return函数注意事项:

// 1.return 终止函数
        function getSum(num1, num2) {
            return num1 + num2;
            alert('这条语句不被执行');//return结束,后面的代码不被执行
        }

        // 2.return 只能返回一个值
        function fn(num1, num2) {
            return num1, num2;// return返回的结果是最后一个值 num2
        }
        console.log(fn(1, 2));

        // 3.求任意两个数的 加减乘除结果
        function getResult(num1, num2) { // 想要输出多个值return 可以返回数组
            return [num1 + num2, num1 - num2, num1 * num2, num1 / num2];
        }
        var re = getResult(1, 2);
        console.log(re);

        // 4. 我们的函数如果有return 则返回的是 return 后面的值,如果函数么有 return 则返回 undefined
           console.log(fun1()); // 返回 666
        function fun2() {

        }
        console.log(fun2()); // 函数返回的结果是 undefined

 

退出循环

break ,continue ,return 的区别

  • break :结束当前的循环体(如 for、while)

  • continue :跳出本次循环,继续执行下次循环(如 for、while)

  • return :不仅可以退出循环,还能够返回 return 语句中的值,同时还可以结束当前的函数体内的代码

 

8.5 arguments的使用

当不确定有多少个参数传递的时候,可以用 arguments 来获取。

arguments对象中存储了传递的所有实参,是当前函数的一个内置对象,函数独有的;

  <script>
        // arguments 的使用  只有函数才有 arguments对象  而且是每个函数都内置好了这个arguments
        function fn() {
            // console.log(arguments); // 里面存储了所有传递过来的实参  arguments = [1,2,3]
            // console.log(arguments.length);
            // console.log(arguments[2]);
            // 我们可以按照数组的方式遍历arguments
            for (var i = 0; i < arguments.length; i++) {
                console.log(arguments[i]);
            }
        }
        fn(1, 2, 3);
        fn(1, 2, 3, 4, 5);
        // 伪数组 并不是真正意义上的数组
        // 1. 具有数组的 length 属性
        // 2. 按照索引的方式进行存储的
        // 3. 它没有真正数组的一些方法 pop()  push() 等等
    </script>

 

注意:在函数内部使用该对象,用此对象获取函数调用时传的实参。

案例:利用函数求任意个数的最大值

 <script>
        // 利用函数求任意个数的最大值
        function getMax() { // arguments = [1,2,3]
            var max = arguments[0];
            for (var i = 1; i < arguments.length; i++) {
                if (arguments[i] > max) {
                    max = arguments[i];
                }
            }
            return max;
        }
        console.log(getMax(1, 2, 3));
        console.log(getMax(1, 2, 3, 4, 5));
        console.log(getMax(11, 2, 34, 444, 5, 100));
    </script>

 

案例:

<script>
        // 1.利用函数封装方法 翻转任意数组 reverse 翻转
        function reverse(arr) {
            var newArr = [];
            for (var i = arr.length - 1; i >= 0; i--) {
                newArr[newArr.length] = arr[i];
            }
            return newArr;
        }
        var arr1 = reverse([1, 2, 3, 4, 5]);
        console.log(arr1);

        // 2.利用函数封装的方法,对数组排序--冒泡排序
        function sort(arr) {
            for (var i = 0; i < arr.length - 1; i++) {
                for (var j = 0; j < arr.length - i - j; j++) {
                    if (arr[j] > arr[j + 1]) {
                        var temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
            return arr;
        }
        var arr2 = sort([1, 2, 3, 4, 5]);
        console.log(arr2);

        // 3.判断闰年
        function isRunYear(year) {
            // 如果是闰年返回 true 否则返回false
            var flag = flase;
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                flag = true;
            }
            return flag;
        }
        console.log(isRunYear(2000));
        console.log(isRunYear(1999));
    </script>

 

函数之间可以相互调用:

函数内部可以调用另一个函数;

    <script>
        // 函数是可以相互调用的
        // function fn1() {
        //     console.log(11);
        //     fn2(); // 在fn1 函数里面调用了 fn2 函数
        // }
        // fn1();

        // function fn2() {
        //     console.log(22);

        // }
        </script>

 

在同一作用域代码中,函数名即代表封装的操作,使用函数名加括号即可以将封装的操作执行。

案例:输出当年年的2月份天数

<script>
        // 用户输入年份,输出当年年的2月份天数
        function backDay() {
            var year = prompt('请您输入年份');
            if (isRunYear(year)) {
                alert('当前年份是闰年 2月份有29天');
            } else {
                alert('当前年份是平年 2月份有28天');
            }
        }
        backDay();
        // 判断是否为闰年的函数
        function isRunYear(year) {
            var flag = false;
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                flag = true;
            }
            return flag;
        }
    </script>

 

 

8.6 函数的两种声明方式

1、自定义函数方式(命名函数)

利用函数关键字 function 自定义函数方式

    // 声明定义方式
    function fn() {...}
    // 调用 调用函数的代码既可以放到声明函数的前面,也可以放在声明函数的后面
    fn();

 

2、函数表达式方式(匿名函数)

        // var 变量名 = function () { }
        var fun = function () {
            console.log('我是函数表达式');
        }
        fun();

 

  • fun是变量名 不是函数名

  • 函数表达式 声明方式和 声明变量差不多,只不过变量里存的是值 而 函数表达式里存的是函数

  • 函数调用的代码必须写到函数体后面

  • 函数表达式也可以进行传递参数

 

9 - 作用域

9.1 作用域概述

作用域:变量能够起作用和效果的 某个范围
目的:为了提高程序的可靠性 更重要的作用是减少命名冲突
全局作用域和局部作用域命名不冲突

9.2 作用域的分类

JavaScript(es6前)中的作用域有两种:

  • 全局作用域

  • 局部作用域(函数作用域)

1.全局作用域

	作用于所有代码执行的环境(整个script标签内部)或独立的js文件,或者var声明的。
	如果在函数内部没有声明,直接赋值的变量也属于全局变量,一般不用console.log();
	全局变量只有浏览器关闭时才会结束,占资源;

2.局部作用域

	作用于函数内的代码环境,就是局部作用域(函数作用域) 
	在函数内部的作用域,这个代码名字只在函数内部起作用 
	function fn { 局部作用域 };
	函数的形参也可以看做局部变量;局部变量在代码执行完毕后就结束;

3.es6新增块级作用域

js在es6中新增块级作用域,块作用域由 { } 包括 如if{} for{}等
在其他编程语言中(如 java、c#等),在 if 语句、循环语句中创建的变量,仅仅只能在当前 if 语句、当前循环语句中使用
  • java有块级作用域:

if(true){
  int num = 123;
  system.out.print(num);  // 123
}
system.out.print(num);    // 报错

 

以上java代码会报错,是因为代码中 { } 即一块作用域,其中声明的变量 num,在 “{ }” 之外不能使用;

而与之类似的JavaScript代码,则不会报错。

  • js中没有块级作用域(在ES6之前)

if(true){
  var num = 123;
  console.log(123); //123
}
console.log(123);   //123

 

 

9.3 - 变量的作用域

在JavaScript中,根据作用域的不同,变量可以分为两种:

  • 全局变量

  • 局部变量

1.全局变量

在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。
注意 如果在函数内部 没有声明直接赋值的变量也属于全局变量
  • 全局变量在代码的任何位置都可以使用

  • 在全局作用域下 var 声明的变量 是全局变量

  • 特殊情况下,在函数内不使用 var 声明的变量也是全局变量(不建议使用)

2.局部变量

在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)
注意: 函数的形参也可以看做是局部变量
  • 局部变量只能在该函数内部使用

  • 在函数内部 var 声明的变量是局部变量

  • 函数的形参实际上就是局部变量

3.全局变量和局部变量的区别

  • 全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存;

  • 局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间;

 

9.4 - 作用域链

根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链。

案例分析1:
function f1() { // 外部函数
    var num = 123;
    function f2() {
        console.log( num );// 站在目标出发,一层一层的往外查找
    }
    f2(); // 内部函数
}
var num = 456;
f1();

 

案例:

作用域链:采取就近原则的方式来查找变量最终的值
var a = 1;
function fn1() {
    var a = 2;
    var b = '22';
    fn2();
    function fn2() {
        var a = 3;
        fn3();
        function fn3() {
            var a = 4;
            console.log(a); //a的值 ?
            console.log(b); //b的值 ?
        }
    }
}
fn1();
 

        // 作用域链
        var num = 10;
        function fn() {
            var num = 20;// 根据作用域链机制 先调用上一级的
            function fun() {
                console.log(num);// 内部函数可以调用外部函数 属于子集
            }
        }

        function f1() {
            var num = 123;
            function f2() {
                console.log(num);// 站在目标出发一层层往外查找 num=123 近
            }
            f2();
        }
        var num = 456;
        f1();

 

 

预解析

1.1 预解析的相关概念

JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。

JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析和代码执行。

预解析:  js引擎会把js里所有的 var 还有 function 提升到当前作用域的最前面,预解析也叫做变量、函数提升。
代码执行: 按照代码抒写的顺序从上到下执行

注意:预解析会把变量和函数的声明在代码执行之前执行完成。

 

1.2 预解析分类

预解析分为变量预解析(变量提升) 和 函数预解析(函数提升)

变量提升:变量的声明会被提升到当前作用域的最上面,变量的 赋值 不会提升。
函数提升:函数的声明会被提升到当前作用域的最上面,但是不会调用函数。

预解析分为变量预解析(变量提升) 和 函数预解析(函数提升)

 // 1.未声明 直接调用  报错
        console.log(num);

        // 2.先调用 后声明  undefined 坑1
        // 变量预解析(变量提升)声明提升,赋值不提
        console.log(num);
        var num = 10;
        // 预解析后相当于:
        var num; // 只声明 未赋值 undefine
        console.log(num);
        num = 10;

        // 3.利用关键字定义函数 函数先调用后声明 或 先声明后调用 无影响
        // 函数预解析(函数提升)
        fn();
        function fn() {
            console.log(11);
        }
        // 预解析后相当于:把函数提升到最前面

        // 4.利用函数表达式定义函数 只能先声明后调用 否则会报错
        // 解决函数表达式声明调用问题
        var fun = function () {
            console.log(22);
        }
        // 预解析后相当于:
        var fun;
        fun();
        fun = function() {
            console.log(22);
        } 

 

案例:

// 1.
        var num = 10;
        fun();
        function fun() {
            console.log(num);
            var num = 20;
        }
    // 函数提升后 相当于以下代码   输出undefined
        var num;
        function fun() {
            var num; // 只声明 未赋值 undefined
            console.log(num);
            num = 20;
        }
        num = 10;
        fun();

    // 4.
        f1();
        console.log(c);
        console.log(b);
        console.log(a);
        function f1() {
            var a = b = c = 9;
            console.log(a);
            console.log(b);
            console.log(c);
        }
    // 相当于以下代码
        function f1() {
            //var a = b = c = 9;
            // 相当于 var a = 9;b = 9;c = 9;//b c 直接赋值 没有var声明 相当于全局变量
            // 集体声明应该是 var a  =9,b = 9,c = 9;
            var a;
            a = b = c = 9;
            console.log(c);// 9
            console.log(b);// 9
            console.log(a);// 报错 a当局部变量看 只声明
        }

 

 

对象

1.1 对象的相关概念

1、什么是对象?

对象是指具体的事物,如字符串、数值、数组函数等;万物皆对象;

对象是由属性和方法组成的:

  • 属性:事物的特征,在对象中用属性来表示(常用名词)

  • 方法:事物的行为,在对象中用方法来表示(常用动词)

2、为什么需要对象?

保存一个值用变量;保存多个值,可以使用数组;保存一个人的完整信息可以用对象(相当于C语言结构体);

  • 对象可以让代码结构更清晰

  • 对象属于复杂数据类型object。

  • 本质:对象就是一组无序的相关属性和方法的集合。

  • 构造函数泛指某一大类,比如苹果,不管是红色苹果还是绿色苹果,都统称为苹果。

  • 对象实例特指一个事物,比如这个苹果、正在给你们讲课的pink老师等。

  • for...in 语句用于对对象的属性进行循环操作。

 

变量、属性、函数、方法的区别

相同点 他们都是用来存储数据的;

  • 变量:单独声明赋值,使用的时候直接写变量名 单独存在

  • 属性:对象里面的变量称为属性,不需要声明,用来描述对象特征 对象.属性;

    属性是对象的一部分,而变量不是对象的一部分,变量是单独存储数据的容器

  • 函数:单独存在的,通过“函数名()”的方式就可以调用

  • 方法:对象里面的函数称为方法,方法不需要声明,使用“对象.方法名()”的方式就可以调用;

    方法是对象的一部分,函数是单独封装操作的容器

    函数和方法的相同点 都是实现某种功能 做某件事

// 变量和属性的相同点 都是用来存储数据的
        // 1.变量 单独声明并赋值 使用的时候直接写变量名 单独存在
        var name = 10;
        // 2.属性 在对象里不需要声明 调用的时候必须是 对象.属性
        var obj = {
            age: 18
        }
        console.log(obj.age);

        // 函数和方法的相同点 都是实现某种功能 做某件事
        // 3.函数是单独声明 并且调用的 函数名() 单独存在的
        function fn() {

        }
        // 4.方法 在对象里面 调用的时候 对象.方法()
        var obj = {
            age: 18
            fn: function () {

            }
        }

 

小括号()优先级;中括号[ ]数组;花括号{ }对象

1.2 创建对象的三种方式

  • 利用字面量创建对象;

  • 利用new object创建对象;

  • 利用构造函数创建对象;

1、利用字面量创建对象

    <script>
        // 1.利用 字面量 创建对象 利用键值对形式 属性名 :属性值 ,中间 逗号 隔开
            
        var obj = {};
        var obj = {
            uname: '张三疯', // 里面的属性或方法采取键值对的形式 键 属性名 :值 属性值
            age: '18',       // 多个属性或者方法中间用逗号隔开
            sex: '男',
            sayHi: function () {    // 方法冒号后面跟的是一个匿名函数 function
                console.log('hi~');
            }
        }

        // 2.调用对象
        
        console.log(obj.name); // 调用对象的属性 采用 对象名.属性名 理解为 的
        console.log(obj['age']); // 调用属性还有一种方法 对象名['属性名']    
        obj.sayHi(); // 调用对象的方法 sayHi  对象名.方法名()
    </script>

 

2、利用 new Object 创建对象

        // 利用 new Object 创建对象 利用 等号 = 赋值的方法 添加对象的属性和方法
        var obj = new Object();// 创建一个空的对象
        obj.uname = '张三疯'; // 利用 等号 = 赋值的方法 添加对象的属性和方法
        obj.age = 18;        // 每个属性和方法之间用分号结束
        obj.sayHi = function () {
            console.log('hi~');
        }
        console.log(obj.uname);
        console.log(obj['sex']);
        obj.sayHi();   

 

3、利用构造函数创建对象

因为前面两种方式一次只能创建一个对象;

  • 构造函数就是把 我们对象里一些相同的属性和方法抽象出来封装到函数中;

  • 构造函数用于创建某一类函数,首字母要大写;与关键字 new 一起使用;

  • 利用构造函数创建对象的过程称为对象的实例化

    <script>
        // 利用构造函数创建对象
        // 需要创建四大天王的对象 相同的属性: 名字 年龄 性别 相同的方法:唱歌
        function 构造函数名() {
            this.属性 = 值;
            this.方法 = function () { }
        }
        new 构造函数名();
// 1.构造函数 泛指一大类
        function Star(uname, age, sex) { // 构造函数首字母大写
            this.name = uname;
            this.age = age;
            this.sex = sex;
            this.sing = function (sang) {
                console.log(sang);
            }
        }
// 2.对象 特指某一个 对象的实例化
        var ldh = new Star('刘德华', 18, '男');
        // 多了个 this 和new 不需要 return 就可以返回结果
        // console.log(typeof ldf); // object
        console.log(ldh.name);
        console.log(ldh['sex']);
        ldh.sing('冰雨');
    </script>
        // 1. 构造函数名字首字母要大写
        // 2. 我们构造函数不需要return 就可以返回结果
        // 3. 我们调用构造函数 必须使用 new
        // 4. 我们只要new Star() 调用函数就创建一个对象 ldh  {}
        // 5. 我们的属性和方法前面必须添加 this

 

 

构造函数和对象的区别:

  • 构造函数 如明星 泛指一大类 类似于java语言中的类

  • 对象 特指 是一个具体的事物

我们利用构造函数创建对象的过程我们也称为对象的实例化

 

new关键字:

  • new 构造函数可以 在内存中创建了一个空的新对象;

  • 让this就会指向刚才的空对象

  • 执行构造函数里面的代码 给这个空对象添加属性和方法

  • 返回这个新对象(所以不需return)

var ldh = new Star('刘德华', 18, '男');

 

1.3 遍历对象

for...in 语句用于对数组或者对象的属性进行循环操作。

for (变量 in 对象名字) {
    // 在此执行代码
}

 

变量通常用 k 或者 key

         // for (变量 in 对象) { }
        for (var k in obj) {
            console.log(k);// k变量输出 得到的是 属性名
            console.log( obj[k] );// 得到的是 属性值
        }

 

 

1.4 内置对象

1.41内置对象的概念

  • JavaScript 中的对象分为3种:自定义对象 、内置对象、 浏览器对象

  • 前面两种对象是JS 基础 内容,属于 ECMAScript; 第三个浏览器对象属于我们 JS 独有的, 我们JS API 讲解

  • 内置对象就是指 JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)

  • 内置对象最大的优点就是帮助我们快速开发

  • JavaScript 提供了多个内置对象:Math、 Date 、Array、String等

 

1.42 MDN文档查阅!

查找文档:学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过查文档学习,可以通过MDN/W3C来查询。 Mozilla 开发者网络(MDN)提供了有关开放网络技术(Open Web)的信息,包括 HTML、CSS 和万维网及 HTML5 应用的 API。 MDN:https://developer.mozilla.org/zh-CN/

 

Math对象

1.Math 概述

Math 对象不是构造函数,所以我们不需要new 来调用 而是直接使用里面的属性和方法即可,它具有数学常数和函数的属性和方法。跟数学相关的运算(求绝对值,取整、最大值等)可以使用 Math 中的成员。

属性、方法名功能
Math.PI 圆周率
Math.floor() 向下取整
Math.ceil() 向上取整
Math.round() 四舍五入版 就近取整 注意 -3.5 结果是 -3
Math.abs() 绝对值
Math.max()/Math.min() 求最大和最小值
Math.random() 获取范围在[0,1)内的随机值

注意:上面的方法使用时必须带括号

        // Math 三个取整的方式
        // (1) Math.floor() 地板 向下取整 往小了取值
        console.log(Math.floor(1.9));// 1
        // (2) Math.ceil()  天花板 向上取整 往大了取值
        console.log(Math.ceil(1.1));// 2
        // (3) Math.round() 四舍五入 其他数字都是四舍五入 5往大了取
        console.log(Math.round(1.1));// 1
        console.log(Math.round(1.5));// 2
        console.log(Math.round(-1.1));// -1
        console.log(Math.round(-1.5));// -1

        
         // Math 数学对象 不是一个构造函数,不需要 new 调用 直接使用里面的属性和方法
        console.log(Math.PI);// 一个属性 圆周率
        console.log(Math.abs(-1));// 1 绝对值
        console.log(Math.max(1, 33, 99));// 99
        console.log(Math.max('pink'));// NaN
        console.log(Math.max());//

        // 利用对象封装自己的数学对象 里面有PI最大值和最小值
        var myMath = {
            PI: 3.1415926,
            max: function () {
                var max = arguments[0]; // 不确定传递过来多少实参
                for (var i = 1; i < arguments.length; i++) {
                    if (arguments[i] > max) {
                        max = arguments[i];
                    }
                }
                return max;
            },
            min: function () {
                var min = arguments[0]; 
                for (var i = 1; i < arguments.length; i++) {
                    if (arguments[i] < min) {
                        min = arguments[i];
                    }
                }
                return min;
            }
        }
        console.log(myMath.PI);
        console.log(myMath.max(1, 5, 9));
        console.log(myMath.min(1, 5, 9));

 

2. 随机数方法 random()

random() 方法可以随机返回一个小数,其取值范围是 [0,1),左闭右开 0 <= x < 1 ;

得到一个两数之间的随机整数,包括两个数在内。

获取指定范围内的随机整数算法

function getRandom(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min; 
}

 

案例:Math对象随机数方法

        // 想要得到两个数之间的随机整数 并且包括这2个数
        // Math.floor(Math.random() * (max - min +1)) + min
        function getRandom(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }
        console.log(getRandom(1, 10));
        // 随机点名
        var arr = ['张三', '张三疯', '张三疯子', '李四', '李思思'];
        // console.log(arr[0]);
        console.log(arr[getRandom(0, arr.length - 1)]);

 

案例:猜数字游戏

程序随机生成一个 1~ 10 之间的数字,并让用户输入一个数字,

案例分析

① 随机生成一个1~10 的整数 我们需要用到 Math.random() 方法。

② 需要一直猜到正确为止,所以一直循环。

③ 用while 循环合适更简单。

④ 核心算法:使用 if else if 多分支语句来判断大于、小于、等于。

    <script>
        function getRandom(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }

        var random = getRandom(1, 10);
        while (true) { // 死循环
            var num = prompt('你来猜?输入1~10之间的一个数字');
            if (num > random) {
                alert('你猜大了');
            } else if (num < random) {
                alert('你猜小了');
            } else {
                alert('你猜对了');
                break;// 退出整个循环 一定要写结束循环条件
            }
        }
    </script>

 

如果限定猜的次数,可以在条件判断改为for

日期对象

Date 对象和 Math 对象不一样,

Date是一个构造函数,使用时需要实例化后(new)才能使用其中具体方法和属性 Date 实例用来处理日期和时间

1.使用Date实例化日期对象

  • 获取当前时间必须实例化:

var now = new Date();
console.log(now);

 

  • 获取指定时间的日期对象

var future = new Date('2019/5/1');
如果Date()不写参数,就返回当前时间
如果Date()里面写参数,就返回括号里面输入的时间

注意:如果创建实例时并未传入参数,则得到的日期对象是当前时间对应的日期对象

        // Date() 日期对象 是一个构造函数 必须使用new 来调用创建日期对象
        var arr = new Array();// 创建了一个数组对象
        var obj = new Object();//创建了一个新的对象实例

        // 1.使用Date 如果没有参数 返回当前系统的当前时间
        var date = new Date();
        console.log(date);
        // 2.参数常用写法 数字型 2019,10,01 或者 字符串型 '2019-10-1 8:8:8'
        var date1 = new Date(2019, 10, 1);
        console.log(date1);// 返回的是 11月 不是 10月
        var date1 = new Date('2019-10-1 8:8:8');
        console.log(date2);

 

2.使用Date实例的方法和属性 日期格式化

方法名说明代码
getFullYear() 获取当年 getFullYear()
getMonth() 获取当月(0-11) getMonth()
getDate() 获取当前日期 getDate()
getDay() 获取星期几(周日为0) getDay()
getHours() 获取当前小时 getHours()
getMinutes() 获取当前分钟 getMinutes()
getSeconds() 获取当前秒钟 getSeconds()

 

案例: 输出当前日期

请写出这个格式的日期:2019年5月1日 星期三

    <script>
        // 格式化日期 年月日 手动更改显示
        var date = new Date();
        console.log(date.getFullYear());// 返回当前日期的年 2019
        console.log(date.getMonth() + 1); // 月份 返回的月份小1个月 月份写时加1
        console.log(date.getDate()); // 返回的是 几号
        console.log(date.getDay()); // 3 周日返回的是0
        // 写一个 2019年 5月 1日 星期三
        var year = date.getFullYear();
        var month = date.getMonth();
        var dates = date.getDate();
        var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
        var day = date.getDay();
        console.log('今天是:' + year + '年' + month + '月' + dates + '日' + arr[day]);
    </script>

 

案例: 输出当前时间

写一个函数,格式化日期对象,成为 HH:mm:ss 的形式 比如 00:10:45

    <script>
        // 格式化日期 时分秒
        var date = new Date();
        console.log(date.getHours());//
        console.log(date.getMinutes()); //
        console.log(date.getSeconds()); //
        // 要求封装一个函数返回当前的时分秒 格式 08:08:08
        function getTime() {
            var time = new Date();
            var h = time.getHours();
            h = h < 10 ? '0' + h : h;
            var m = time.getMinutes();
            m = m < 10 ? '0' + m : m;
            var s = time.getSeconds();
            s = s < 10 ? '0' + s : s;
            return h + ':' + m + ':' + s;
        }
        console.log(getTime());
    </script>

 

 

3.通过Date实例获取总毫米数

总毫秒数的含义:基于1970年1月1日(世界标准时间)起的毫秒数

毫秒数也叫时间戳,永远不会重复;

案例:获取总毫秒数

    <script>
        // 获得 Date总的毫秒数 不是当前时间的毫秒数 而是距离1970年1月1日
      
        var date = new Date();// 实例化Date对象
        // 1. 通过 valueOf()  getTime() 用于获取对象的原始值
        console.log(date.valueOf());// 距离 1970 过了多少毫秒
        console.log(date.getTime());

        // 2. 简单的写法(常用)
        var date1 = +new Date();// +new Date() 返回的是总毫秒数
        console.log(date1);

        // 3. HTML5新增的的方法,有兼容性问题
        console.log(Date.now());
    </script>

 

案例:倒计时效果

案例分析

① 核心算法:输入的时间减去现在的时间就是剩余的时间,即倒计时 ,但是不能拿着时分秒相减,比如 05 分减去25分,结果会是负数的。

② 用时间戳(毫秒)来做。用户输入时间总的毫秒数减去现在时间的总的毫秒数,得到的就是剩余时间的毫秒数。

③ 把剩余时间总的毫秒数转换为天、时、分、秒 (时间戳转换为时分秒)

转换公式如下:

 d = parseInt(总秒数/ 60/60 /24); // 计算天数

 h = parseInt(总秒数/ 60/60 %24) // 计算小时

 m = parseInt(总秒数 /60 %60 ); // 计算分数

 s = parseInt(总秒数%60); // 计算当前秒数

    <script>
        function countDown(time) {
            var nowTime = +new Date();// 返回的是当前时间的总毫秒数
            var inputTime = +new Date(time);// 返回的是用户输入事件的总毫秒数
            var times = (inputTime - nowTime) / 1000; // times是剩余时间总的秒数 1s=1000ms
            var d = parseInt(times / 60 / 60 / 24);//
            d = d < 10 ? '0' + d : d;
            var h = parseInt(times / 60 / 60 % 24);//
            h = h < 10 ? '0' + h : h;
            var m = parseInt(times / 60 % 60);//
            m = m < 10 ? '0' + m : m;
            var s = parseInt(times % 60);//
            s = s < 10 ? '0' + s : s;
            return d + '天' + h + '时' + m + '分' + s + '秒';
        }
        console.log(countDown('2019-5-1 18:00:00'));
        var date = new Date();
        console.log(date);
    </script>

 

 

数组对象

1.创建数组的两种方式

  • 字面量方式

       var arr = [1, 2, 3];
            console.log(arr[0]);

     

  • new Array() 构造函数

        // var arr1 = new Array();  // 创建了一个空的数组
            // var arr1 = new Array(2);  // 这个2 表示 数组的长度为 2  里面有2个空的数组元素 
            var arr1 = new Array(2, 3); // 等价于 [2,3]  这样写表示 里面有2个数组元素 是 2和3
          console.log(arr1);

     

    注意:上面代码中arr创建出的是一个空数组,如果需要使用构造函数Array创建非空数组,可以在创建数组时传入参数

    参数传递规则如下:

    • 如果只传入一个参数,则参数规定了数组的长度

    • 如果传入了多个参数,则参数称为数组的元素

2.检测是否为数组

  • instanceof 运算符

    instanceof 可以判断一个对象是否是某个构造函数的实例

    var arr = [1, 23];
    var obj = {};
    console.log(arr instanceof Array); // true arr是数组
    console.log(obj instanceof Array); // false obj是对象

     

  • Array.isArray()

    Array.isArray()用于判断一个对象是否为数组,isArray() 是 HTML5 中新增的方法 ie9以上不支持

    var arr = [1, 23];
    var obj = {};
    console.log(Array.isArray(arr));   // true
    console.log(Array.isArray(obj));   // false

     

翻转数组:

  // 翻转数组
        function reverse(arr) {
            // if (arr instanceof Array) {
            if (Array.isArray(arr)) {
                var newArr = [];
                for (var i = arr.length - 1; i >= 0; i--) {
                    newArr[newArr.length] = arr[i];

                }
                return newArr;
            } else {
                return 'error 这个参数要求必须是数组格式 [1,2,3]'
            }
        }
        console.log(reverse([1, 2, 3]));
        console.log(reverse(1, 2, 3));

 

3.添加删除数组元素的方法

数组中有进行增加、删除元素的方法,部分方法如下表

方法名说明返回值
push(参数1...) 末尾添加一个或多个元素,注意修改原数组 并返回新的长度
pop() 删除数组最后一个元素,把数组长度减1 无参数、修改原数组 返回他删除的元素的值
unshift(参数1...) 向数组的开头添加一个或多个元素,注意修改原数组 并返回新的长度
shift() 删除数组的第一个元素,数组长度减1无参数,修改原数组 并返回第一个元素得值

注意:push、unshift为增加元素方法;pop、shift为删除元素的方法

案例:添加删除数组元素

   <script>
        // 添加删除数组元素方法
        // 1. push() 在我们数组的末尾 添加一个或者多个数组元素   push  推
        var arr = [1, 2, 3];
        // arr.push(4, 'pink');
        console.log(arr.push(4, 'pink'));

        console.log(arr);
        // (1) push 是可以给数组追加新的元素
        // (2) push() 参数直接写 数组元素就可以了
        // (3) push完毕之后,返回的结果是 新数组的长度 
        // (4) 原数组也会发生变化
        // 2. unshift 在我们数组的开头 添加一个或者多个数组元素
        console.log(arr.unshift('red', 'purple'));

        console.log(arr);
        // (1) unshift是可以给数组前面追加新的元素
        // (2) unshift() 参数直接写 数组元素就可以了
        // (3) unshift完毕之后,返回的结果是 新数组的长度 
        // (4) 原数组也会发生变化

        // 3. pop() 它可以删除数组的最后一个元素  
        console.log(arr.pop());
        console.log(arr);
        // (1) pop是可以删除数组的最后一个元素 记住一次只能删除一个元素
        // (2) pop() 没有参数
        // (3) pop完毕之后,返回的结果是 删除的那个元素 
        // (4) 原数组也会发生变化
        // 4. shift() 它可以删除数组的第一个元素  
        console.log(arr.shift());
        console.log(arr);
        // (1) shift是可以删除数组的第一个元素 记住一次只能删除一个元素
        // (2) shift() 没有参数
        // (3) shift完毕之后,返回的结果是 删除的那个元素 
        // (4) 原数组也会发生变化
    </script>
</head>

 

案例: 筛选数组

有一个包含工资的数组[1500, 1200, 2000, 2100, 1800],要求把数组中工资超过2000的删除,剩余的放到新数组里面

    var arr = [1500, 1200, 2000, 2100, 1800];
    var newArr = [];
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] < 2000) {
        // newArr[newArr.length] = arr[i];
         newArr.push(arr[i]);
         } 
    }
    console.log(newArr);

 

 

4.数组排序

数组中有对数组本身排序的方法,部分方法如下表

方法名说明是否修改原数组
reverse() 颠倒数组中元素的熟悉怒,无参数 改变原来数组 返回新数组
sort() 对数组的元素进行排序 改变原数组 返回新数组

 

注意:sort方法需要传入参数来设置升序、降序排序

  • 如果传入“function(a,b){ return a-b;}”,则为升序

  • 如果传入“function(a,b){ return b-a;}”,则为降序

        // 数组排序
        // 1. 翻转数组
        var arr = ['pink', 'red', 'blue'];
        arr.reverse();
        console.log(arr);

        // 2. 数组排序(冒泡排序)
        var arr1 = [17, 4, 71, 6, 9];
        // arr1.sort();// 只能对单位数字排序
        arr1.sort(function (a, b) {
            return a - b;// 按照升序排列
            return b - a;// 按照降序排序
        });
        console.log(arr1);

 

 

5.数组索引方法

数组中有获取数组指定元素索引值的方法,部分方法如下表

方法名说明返回值
indexOf() 数组中查找给定元素的第一个索引 存在返回索引,不存在,返回-1
lastIndexOf() 在数组中的最后一个索引 存在返回索引,不存在,返回-1

获取数组指定元素索引值

    <script>
        // 返回数组元素索引号方法  indexOf(数组元素)  作用就是返回该数组元素的索引号 从前面开始查找
        // 它只返回第一个满足条件的索引号 
        // 它如果在该数组里面找不到元素,则返回的是 -1  
        // var arr = ['red', 'green', 'blue', 'pink', 'blue'];
        var arr = ['red', 'green', 'pink'];
        console.log(arr.indexOf('blue'));
        // 返回数组元素索引号方法  lastIndexOf(数组元素)  作用就是返回该数组元素的索引号 从后面开始查找
        var arr = ['red', 'green', 'blue', 'pink', 'blue'];

        console.log(arr.lastIndexOf('blue')); // 4
    </script>

 

案例: 数组去重(重点案例)

有一个数组[‘c’, ‘a’, ‘z’, ‘a’, ‘x’, ‘a’, ‘x’, ‘c’, ‘b’],要求去除数组中重复的元素

案例分析

① 目标:把旧数组里面不重复的元素选取出来放到新数组中,重复的元素只保留一个,放到新数组中去重。

② 核心算法:我们遍历旧数组,然后拿着旧数组元素去查询新数组,如果该元素在新数组里面没有出现过,我们就添加,否则不添加。

③ 我们怎么知道该元素没有存在? 利用 新数组.indexOf(数组元素) 如果返回时 -1 就说明 新数组里面没有该元素

旧数组['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b']

新数组 [ ]

    <script>
        // 数组去重 ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'] 要求去除数组中重复的元素。
        // 1.目标: 把旧数组里面不重复的元素选取出来放到新数组中, 重复的元素只保留一个, 放到新数组中去重。
        // 2.核心算法: 我们遍历旧数组, 然后拿着旧数组元素去查询新数组, 如果该元素在新数组里面没有出现过, 我们就添加, 否则不添加。
        // 3.我们怎么知道该元素没有存在? 利用 新数组.indexOf(数组元素) 如果返回时 - 1 就说明 新数组里面没有改元素
        // 封装一个 去重的函数 unique 独一无二的
        function unique(arr) {
            var newArr = [];
            for (var i = 0; i < arr.length; i++) {
                if (newArr.indexOf(arr[i]) === -1) {
                    newArr.push(arr[i]);
                }
            }
            return newArr;
        }
        // var demo = unique(['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'])
        var demo = unique(['blue', 'green', 'blue'])
        console.log(demo);
    </script>

 

 

6.数组转换为字符串

数组中有把数组转化为字符串的方法,部分方法如下表

方法名说明返回值
toString() 把数组转换成字符串 逗号分割每一项 返回一个字符串
join('分隔符') 方法用于把数组中的所有元素转换为一个字符串 返回一个字符串

注意:join方法如果不传入参数,则按照 “ , ”拼接元素

        // 数组转换成字符串
        // 1. toString() 
        var arr = [1, 2, 3];
        console.log(arr.toString());// 1,2,3
        // 2. join(分隔符)
        var arrr1 = ['green', 'blue', 'pink'];
        console.log(arr1.join());// green,blue,pink
        console.log(arr1.join('-'));// green-blue-pink
        console.log(arr1.join('&'));// green&blue&pink

 

 

其他方法

  • 数组中还有其他操作方法,同学们可以在课下自行查阅学习

  • slice() 和 splice() 目的基本相同,建议同学们重点看下 splice()

方法名说明返回值
concat() 连接两个或多个数组 不影响原数组 返回一个新的数组
slice() 数组截取 slice(begin,end) 返回被截取项目的新数组
splice() 数组删除splice(第几个开始,要删除个数) 返回被删除项目的新数组 影响原数组

 

字符串对象

1.基本包装类型

为了方便操作基本数据类型,JavaScript 还提供了三个特殊的引用类型:String、Number和 Boolean。

基本包装类型就是把 简单数据类型 包装成为 复杂数据类型,这样基本数据类型就有了属性和方法。

// 下面代码有什么问题?
var str = 'andy';
console.log(str.length);

 

按道理简单数据类型是没有属性和方法的,而对象才有属性和方法,但上面代码却可以执行,这是因为js 会把基本数据类型包装为复杂数据类型,其执行过程如下 :

    // 对象 才有 属性和方法   复杂数据类型才有 属性和方法 
    // 简单数据类型为什么会有length 属性呢? 
    // 基本包装类型:  就是把简单数据类型 包装成为了 复杂数据类型 
// 1. 生成临时变量,把简单类型包装为复杂数据类型
var temp = new String('andy');
// 2. 赋值给我们声明的字符变量
str = temp;
// 3. 销毁临时变量
temp = null;

 

2.字符串的不可变

	指的是里面的值不可变,虽然看上去可以改变内容,但只是地址变了,在内存中新开辟了一个内存空间。 原来的值还是有的;
	当重新给字符串变量赋值的时候,变量之前保存的字符串不会被修改,依然在内存中重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变。
	

由于字符串的不可变,在大量拼接字符串的时候会有效率问题

var str = 'abc';
str = 'hello';
// 当重新给 str 赋值的时候,常量'abc'不会被修改,依然在内存中
// 重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变
// 由于字符串的不可变,在大量拼接字符串的时候会有效率问题
var str = '';
for (var i = 0; i < 100000; i++) {
 str += i;
}
console.log(str); // 这个结果需要花费大量时间来显示,因为需要不断的开辟新的空间

3.根据字符返回位置

字符串的所有方法,都不会修改字符本身(字符串是可变的),操作完成后会发挥成以个新的字符串;

字符串通过基本包装类型可以调用部分方法来操作字符串,以下是返回指定字符的位置的方法:

方法名说明
indexOf('要查找的字符',开始的位置) 返回指定内容在元字符串中的位置,如果找不到返回-1,开始的位置是index索引号
lastIndexOf() 从后往前找,值找第一个匹配的

 

 // 字符串对象 根据字符返回位置 str.indexOf('要查找的字符',[起始位置])
        var str = '改革春风吹满地,春天来了';
        console.log(str.indexOf('春'));// 2
        console.log(str.indexOf('春', 3));// 从索引号是 3的位置开始往后查找 8

 

案例:返回字符位置

查找字符串"abcoefoxyozzopp"中所有o出现的位置以及次数

① 核心算法:先查找第一个o出现的位置

② 然后 只要indexOf 返回的结果不是 -1 就继续往后查找

③ 因为indexOf 只能查找到第一个,所以后面的查找,利用第二个参数,当前索引加1,从而继续查找

    <script>
        var str = "abcoefoxyozzopp";
        var index = str.indexOf('o'); // 从第一个o开始查找,返回 索引号 3
        var num = 0;
        // console.log(idnex);
        while (index !== -1) {
            console.log(index);
            num++; // 开始寻找第二个 o
            index = str.indexOf('o', index + 1);
        }
        console.log('o出现的次数是:' + num);
    </script>

 

 

4.根据位置返回字符

字符串通过基本包装类型可以调用部分方法来操作字符串,以下是根据位置返回指定位置上的字符:

方法名说明使用
charAt(index) 返回指定位置的字符(index字符串的索引号) str.charAt(0)
charCodeAt(index) 获取指定位置处字符的ASII码(index索引号) str.charCodeAt(0)
str[index] 获取指定位置处字符 html/ie8+支持

 

在上述方法中,charCodeAt方法返回的是指定位置上字符对应的ASCII码,ASCII码对照表如下:

        // 根据位置返回字符
        // 1. charAt(index) 根据位置返回字符
        var str = 'andy';
        console.log(str.charAt(3));// y
        // 遍历所有字符
        for (var i = 0; i < str.length; i++) {
            console.log(str.charAt(i));
        }
        // 2. charCodeAt(index) 反应相应索引号的字符ASII值 目的:判断用户按下了哪个键
        console.log(str.charCodeAt(0));//97
        // 2. str[index] H5 新增的
        console.log(str[0]); // a

 

案例:返回字符位

统计出现最多的字符和次数

判断一个字符串 'abcoefoxyozzopp' 中出现次数最多的字符,并统计其次数

1.核心算法:利用 charAt() 遍历这个字符串

2.把每个字符都存储给对象, 如果对象没有该属性,就为1,如果存在了就 +1

3.遍历对象,得到最大值和该字符

注意:在遍历的过程中,把字符串中的每个字符作为对象的属性存储在对象总,对应的属性值是该字符出现的次数

    <script>
        var str = 'abcoefoxyozzopp';
        var o = {};
        for (var i = 0; i < str.length; i++) {
            var chars = str.charAt(i);// chars是字符串中的每一个字符
            if (o[chars]) { // o[chars]得到的是属性值
                o[chars]++;
            } else {
                o[chars] = 1;
            }
        }
        console.log(o);
        // 2.遍历对象
        var max = 0;
        var ch = '';
        for (var k in o) {
            // k得到的是 属性名
            // o[k]得到的是属性值
            if (o[k] > max) {
                max = o[k];
                ch = k;
            }
        }
        console.log(max);
        console.log('最多的字符是' + ch);
    </script>
    <script>
        // 有一个对象 来判断是否有该属性 对象['属性名']
        var o = {
            age: 18
        }
        if (o['sex']) {
            console.log('里面有该属性');

        } else {
            console.log('没有该属性');

        }

        //  判断一个字符串 'abcoefoxyozzopp' 中出现次数最多的字符,并统计其次数。
        // o.a = 1
        // o.b = 1
        // o.c = 1
        // o.o = 4
        // 核心算法:利用 charAt() 遍历这个字符串
        // 把每个字符都存储给对象, 如果对象没有该属性,就为1,如果存在了就 +1
        // 遍历对象,得到最大值和该字符
        var str = 'abcoefoxyozzopp';
        var o = {};
        for (var i = 0; i < str.length; i++) {
            var chars = str.charAt(i); // chars 是 字符串的每一个字符
            if (o[chars]) { // o[chars] 得到的是属性值
                o[chars]++;
            } else {
                o[chars] = 1;
            }
        }
        console.log(o);
        // 2. 遍历对象
        var max = 0;
        var ch = '';
        for (var k in o) {
            // k 得到是 属性名
            // o[k] 得到的是属性值
            if (o[k] > max) {
                max = o[k];
                ch = k;
            }
        }
        console.log(max);
        console.log('最多的字符是' + ch);
    </script>

 

5.字符串操作方法

字符串通过基本包装类型可以调用部分方法来操作字符串,以下是部分操作方法:

方法名说明
concat(str1,str2,str3...) 用于连接两个或多个字符串,拼接字符串,等效于+(+常用)
substr(start,length) 从start位置开始(索引号),length取个数
slice(start,end) 从start位置开始,截取到end位置,end取不到(都是索引号)
substring(start,end) 从start位置开始,截取到end,end取不到,基本和slice相同,但不接收负值

 

        // 字符串操作方法
        // 1.concat('字符串1','字符串2'...)
        var str  ='andy';
        console.log(str.concat('red'));// andyred

        // 2. substr('截取的起始位置','截取几个字符');
        var str1 = '改革春风吹满地';
        console.log(str1.substr(2,2));// 春风
// 第一个2 是索引号的2 从第几个开始  第二个2 是取几个字符

 

 

replace()方法

replace() 方法用于在字符串中用一些字符替换另一些字符,其使用格式如下:

字符串.replace(被替换的字符串, 要替换为的字符串);
var str = 'andyandy';
console.log(str.replace('a')); //只替换第一个a

 

split()方法

split()方法用于切分字符串,它可以将字符串切分为数组。在切分完毕之后,返回的是一个新数组。

字符串.split("分割字符")
var str = 'a,b,c,d';
console.log(str.split(',')); // 返回的是一个数组 [a, b, c, d]
    <script>
        // 1. 替换字符 replace('被替换的字符','替换为的字符') 只替换第一个
        var str = 'andyandy';
        console.log(str.replace('a', 'b'));// bndyandy
        // 替换里面所有选中的字符串
        var str1 = 'andyandy';
        while (str1.indexOf('a') !== -1) {
            str1 = str1.replace('a', '*');
        }
        console.log(str1);
        // 2. 字符串转换为数组 split('分隔符') join 把数组转为字符串
        var str2 = 'red,pink,blue';
        console.log(str2, split(','));// ['red','pink','blue']
        console.log(str2, split('&'));// ['red'&'pink'&'blue']
    </script>

 

课下查阅

 toUpperCase() //转换大写

 toLowerCase() //转换小写

 

数据类型

1.1 简单数据类型

简单类型基本数据类型值类型):

在存储时变量中存储的是值本身,包括string ,number,boolean,undefined,null

null返回的是object,如果有个变量,以后打算存储为对象,可以用;

  <script>
        // 简单数据类型 null  返回的是一个空的对象  object 
        var timer = null;
        console.log(typeof timer);
        // 如果有个变量我们以后打算存储为对象,暂时没想好放啥, 这个时候就给 null 
        // 1. 简单数据类型 是存放在栈里面 里面直接开辟一个空间存放的是值
        // 2. 复杂数据类型 首先在栈里面存放地址 十六进制表示  然后这个地址指向堆里面的数据
    </script>

 

 

1.2 复杂数据类型

复杂数据类型(引用类型):在存储时变量中存储的仅仅是地址(引用),通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等;

1.3 堆栈

  • 堆栈空间分配区别:

  1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放到栈里面;

  2、堆(操作系统):存储 复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收

 

js中没有堆栈概念

  • 简单数据类型的存储方式

    值类型变量的数据直接存放在变量(栈空间)中,存储的是值

  • 复杂数据类型的存储方式

    引用类型变量(栈空间)里存放的是地址,地址指向堆里面的数据,真正的对象实例存放在堆空间中

1.4 简单类型传参

函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。

    function fn(a) {
        a++;
        console.log(a); 
    }
    var x = 10;
    fn(x);
    console.log(x);

 

运行结果如下:

 

1.5 复杂数据类型传参

函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。

function Person(name) {
    this.name = name;
}
function f1(x) { // x = p
    console.log(x.name); // 2. 这个输出什么 ?    刘德华
    x.name = "张学友";
    console.log(x.name); // 3. 这个输出什么 ?    张学友
}
var p = new Person("刘德华");
console.log(p.name);    // 1. 这个输出什么 ?   刘德华
f1(p);
console.log(p.name);    // 4. 这个输出什么 ?  张学友

 

 

 

 

 

 

 

 

 

posted @ 2021-02-22 16:31  新新子  阅读(448)  评论(0编辑  收藏  举报