黑马程序员 JavaScript基础

目标:

能够说出什么是编程语言
能够区分编程语言和标记语言的不同
能够说出常见的数据存储单位及其换算关系
能够说出内存的主要作用以及特点

目录:

编程语言
计算机基础

编程语言

一、编程

编程:就是让计算机 为解决某个问题 而使用某种程序设计语言编写程序代码,并最终得到结果的过程。

计算机程序:就是 计算机执行的一系列指令集合,而程序全部都是用我们所掌握的语言来编写的,所以人们要控制计算机一定要通过计算机语言向计算机发出命令。

注意:上面所定义的计算机指的是任何能够执行代码的设备,可能是智能手机、ATM机、黑莓PI、服务器等等。


二、计算机语言

计算机语言指 用于人与计算机之间通讯的语言,它是人与计算机之间传递信息的媒介

计算机语言的种类 非常多,总的来说可以分成 机器语言汇编语言高级语言三大类。

实际上计算机最终所执行的都是机器语言,它是由"0"和"1组成的二进制数,二进制是计算机语言的基础。


三、编程语言

可以通过类似于人类语言的"语言来控制计算机,让计算机为我们做事情,这样的语言就叫做 编程语言 (Programming Language)。

编程语言 用来控制计算机的一系列指令,它有固定的格式词汇 (不同编程语言的格式和词汇不一样),必须遵守。

如今通用的编程语言有两种形式:汇编语言和高级语言。

  • 汇编语言和机器语言实质是相同的,都是直接对硬件操作,只不过指令采用了英文缩写的标识符,容易识别和记忆。

  • 高级语言主要是相对于低级语言而言,它并不是特指某一种具体的语言,而是包括了很多编程语言,常用的有C语言、C++、Java、C#、Python、PHP、JavaScript、Go语言、Objective-C、Swift等。

C语言:puts("你好");
PHP:echo"你好";
Java:System.out.println("你好);
JavaScript:alert("你好")

四、翻译器

高级语言所编写的程序不能直接被计算机识别,必须经过转换才能被执行,为此,我们需要一个翻译器。翻译器可以将我们所编写的源代码转换为机器语言,这也称为二进制,记住1和0.


五、编程语言和标记语言的区别

  • 编程语言有很强的逻辑和行为能力。在编程语言里,你会看到很多 If else、for、while等具有逻辑性和行为能力的指令,这是主动的。

  • 标记语言不用于向计算机发出指令,常用于格式化和链接。标记语言的存在是用来被读取的,它是被动的。


计算机基础

一、计算机组成


二、数据存储

  • 计算机内部使用二进制 0 和 1 来表示数据。

  • 所有数据,包括文件、图片等最终都是以二进制数据 ( 0 和1 ) 的形式存放在硬盘中的

  • 所有程序,包括操作系统,本质都是各种数据,也以二进制的形式存放在硬盘中。平时我们所说的安装软件,其实就是把程序文件复制到硬盘中。

  • 硬盘、内存都是保存的二进制数据。


三、数据存储单位

bit <byte < kb < GB < TB < ......

  • 位 (bit):1bit 可以保存一个 0 或者 1 (最小的存储单位)

  • 字节 (Byte):1B = 8b

  • 千字节 (KB):1KB = 1024B

  • ......


四、程序运行

  1. 打开某个程序时,先从硬盘中把程序的代码加载到内存中

  2. CPU 执行内存中的代码

注意:之所以要内存的一个重要原因,是因为cpu运行太快了,如果只从硬盘中读数据,会浪费cpu性能,所以,才使用存取速度更快的内存来保存运行时的数据。(内存是电,硬盘是机械)


目标:

能够说出 JavaScript 是什么?
能够知道 JavaScript 的发展史
能够说出浏览器执行 JavaScript 的原理
能够说出 JavaScript由哪三部分组成
能够写出 JavaScript三个输入输出语句

目录:

初始 JavaScript
JavaScript 注释
JavaScript输入输出语句

初识JavaScript

一、JavaScript历史


二、JavaScript是什么

  • JavaScript是世界上最流行的语言之一,是一种运行在客户端的脚本语言 (Script是脚本的意思)

  • 脚本语言不需要编译,运行过程中由 Js解释器 (JS引擎) 逐行来进行解释并执行。

  • 现在也可以基于Node.js技术进行服务器端编程


三、JavaScript的作用

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

  • 网页特效

  • 服务器端开发 (Node.js)

  • 桌面程序 (Electrom)

  • APP (Cordova)

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

  • 游戏开发(cocos2d-js)


四、HTML/CSS/JS的关系


五、浏览器执行 JS 简介

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

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

  • JS引擎:也成为 JS解释器。用来读取网页中的 JavaScript代码,对其处理后运行,比如chrom浏览器的V8

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


六、JS的组成

JavaScript分为:ECMAScript (JavaScrpt语法)Dom(页面文档对象模型)BOM(浏览器对象模型)


1. ECMAScript

ECMAScript是由ECMA国际(原欧洲计算机制造商协会)进行标准化的一门编程语言,这种语言在万维网上应用广泛,它往往被称为 JavaScript或JScript,但实际上后两者是ECMAScript语言的实现和扩展。


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


2. DOM—文档对象模型

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


3. BOM—浏览器对象模型

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


七、JS引入方式

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

行内式JS

<input type="button" value="唐伯虎" Onclick="alert('弹出警示框')">
  • 可以将单行或少量 JS 代码写在HTML标签的事件属性中(以 on 开头的属性),如:onclick

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

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

  • 引号易错,引号多层嵌套匹配时,非常容易弄混;

  • 特殊情况下使用


内嵌式JS

<script>
    alert('沙漠骆驼');    // 沙漠骆驼(提示框)
<script>
  • 可以将多行JS代码写到< script >标签中

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


外部JS

新建一个js文件,编写JS代码。

alert(’外部JS‘)

引入新建的js文件

<script src="路径位置"></script>
  • 利用HTML页面代码结构化,把大段JS代码独立到HTML页面之外,既美观,也方便文件级别的复用

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

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


JavaScript注释

// 单行注释	ctrl+/

/* */多行注释  shift+alt+a 目前在VSCode修改成ctrl+shift+/

JavaScript输入输出语句

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

方法说明归属
alert(msg)浏览器弹出警示框浏览器
console.log(msg)浏览器控制台打印输出信息浏览器
prompt(info)浏览器弹出输入框,用户可以输入浏览器

目录:

变量概述
变量的使用
变量的语法扩展
变量命名规范
交互变量案例

变量概述

一、什么是变量

白话:变量就是一个装东西的盒子。

通俗:变量是用于 存放数据的容器。我们 通过变量名获取数据 以及 数据修改


二、变量在内存中的存储

本质:变量 程序在内存中申请的一块用来存放数据的空间

类似我们酒店(内存)的房间(变量),一个房间就可以看做是一个变量。


变量的使用

变量在使用时分为两步:(1) 声明变量,(2) 赋值

一、声明变量

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

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

二、赋值

age = 10;	//给 age 这个变量赋值为10
  • = 用来把右边的值赋给左边的变量空间中 此处代表赋值的意思

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


三、变量的初始化

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

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


变量语法扩展

一、更新变量

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

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

二、同时声明多个变量

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

var age = 10,name = 'LZ',sex='1';

三、声明变量特殊情况

情况说明结果
var age; console.log(age);只声明,不赋值undefined
console.log(age)不声明,不赋值,直接使用报错
age=10,console.log(age);不声明,只赋值 (js中可以,但不推荐使用)10

变量的命名规范

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

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

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

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

  • 变量名必须有意义。nl(年龄) -> age

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


交互变量案例

要求:交换两个变量的值(实现思路:使用一个临时变量 用来做中间存储)

var s;	// 临时变量
var a = 1;
var b = 2;
s = a;
a = b;
b = s;

目标:

能够说出 5 种简单数据类型
能够使用 typeof获取变量的类型
能够说出 1~2 种转换位数值的方法
能够说出 1~2 种转换为字符串的方法
能够说出什么是隐式转换

目录

数据类型简介
简单数据类型
获取变量数据类型
数据类型转换

数据类型简介

一、为什么需要数据类型

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


二、变量的数据类型

变量是用来存储值的所在处,它们有名字和数据类型。变量的数据类型决定了如何将代表这些值的位存储到计算机的内存中。JavaScript是一种弱类型或者说动态语言。这意味着不同提前声明变量的类型,在程序运行过程中,类型会自动确定。

JS 把数据类型分为两类:

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

  • 复杂数据类型 (Object)


简单数据类型

JavaScript 中的简单数据类型及其说明如下:

简单数据类型说明默认值
Number数字型,包含 整型值和浮点型值,如21、0.210
Boolean布尔值类型,如 true、false,等价于 1 和 0false
String字符串类型,如"张三" 注意咱们 js 里面,字符串都带引号""
Underfinedvar a; 声明了变量 a 但是没有给值,此时 a = underfinedundefined
Nullvar a = null; 声明了变量 a 为空值null

一、数字型 Number

JavaScript 数字类型既可以用来保存整数值,也可以保存小数 (浮点数)。

var age = 3;   // 整数
var Age = 3.14;	// 小数
  1. 数字型进制

最常见的进制二进制八进制十进制十六进制

// 1.八进制数字序列范围:0~7
var num1 =o7;	//对应十进制的7
var num2 = o19;	//对应十进制的19
var num3 = o8;	//对应十进制的8
// 2.十六进制数字序列范围:0~9以及A~F
var num = oxA;

现阶段我们只需要记住,在JS中八进制前面加o,十六进制前面加ox


2.数字型范围

JavaScript中数值的最大和最小值

alert(Number.MAX_VALUE);	//1.7976e+308
alert(Number.MIN_VALUE);	//5e-324

3.数字型三个特殊值

alert(Infinity);	// Infinity
alert(-Infinity);	// -Infinity
alert(NaN);		// NaN
  • Infinity,代表无穷大,大于任何数值

  • -Infinity,代表无穷小,小于任何数值

  • NaN,Not a number,代表一个非数值


isNaN()

isNaN() 这个方法用来判断非数字,并且返回一个值,如果是数字返回的是false.

var a = 1;
console.log(isNaN(a))	//false

二、字符串型 String

字符串型可以是引号中的任意文本,其语法为 双引号 "" 和 单引号 ''.

var strMsg = "苹果";	// 使用双引号表示字符串
var strMsg2 = '香蕉';	// 使用单引号表示字符串
// 常见错误
var strMsg3 = 梨;	// 报错,没使用引号,会被认为是js代码,但js没有这些语法

因为 HTML 标签里面的属性使用的是双引号JS 这里我们更推荐使用单引号


字符串引号嵌套

JS可以用单引号嵌套双引号,或者用双引号嵌套单引号(外双内单,外单内双)

var strMsg ='你好"鲍勃"';	// 可以用''包含""
var strMsg =" 你好'鲍勃'";	// ""包含''
// 常见错误
var badQuotes ='What on earth?";	// 报错,不能单双引号搭配

2.字符串转义符

类似 HTML 里面的特殊字符,字符串中也有特殊字符,我们称之为转义符。

转义符都是 \ 开头的,常用的转义符机器说明如下:

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

  1. 字符串长度

字符串由若干字符组成的,这些字符的数量就是字符串的长度。通过字符串的 length 属性可以获取整个字符串的长度。

var strMsg = "苹果";
alert(strMsg.length);	// 显示 2

4.字符串拼接

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

  • 拼接前会把与字符串相加的任何类型转成字符串,再拼接成一个新的字s符串。

// 1.1 字符串"相加"
alert('hello'+''+'world');	//hello world
// 1.2 数值字符串"相加"
alert('100'+'100');		//100100
// 1.3 数值字符串 + 数值
alert('11'+12);			// 1112

三、布尔值 Boolean

布尔类型有两个值:true 和 false,其中 true 表示真 (对),而 false 表示 假 (错)。

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

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

四、Undefined 和 Null

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

var a
console.log(a);	// undefined
console.log('你好'+a);	//你好undefined
console.log(11+a);	//NaN
console.log(true + a); //NaN

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

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

获取变量数据类型

一、获取检测变量的数据类型

typeof用来检测变量的数据类型

var a =1;
console.log(typeof a);	// Number

二、字面量

字面量 在源代码中一个固定值的表示法,通俗来说,就是字面量 表示如何表达这个值

  • 数字字面量:8,9,10

  • 字符串字面量:"签到"

  • 布尔字面量:true,false


数据类型转换

一、什么是数据类型转换

使用表单、prompt 获取过来的数据 默认是字符串类型的,此时就不能直接简单的进行加法运算,而需要转换变量的数据类型。通俗来说,就是把一种数据类型的变量转换成另外一种数据类型。


二、转换为数字型 (重点)

方式说明案例
parseInt(string) 函数将string 类型转换成整数数值类型parseInt('12')
parseFloat(string)函数将string 类型转成浮点数值型parseFloat('3.14')
Number()强制转换函数将string 类型转换为数值型Number('12')
js 隐式转换 (- * /)利用算术运算隐式转换为数值型'12'-0 (先把'12'转换成number) 或 '123'-'120' (结果为3)
  • 注意 parseInt 和 parseFloat 单词的大小写,这2个是重点

  • 隐式转换是我们在进行算数运算的时候,JS自动转换为数据类型


三、转换为字符串

方式说明案例
toString()转成字符串var num = 1; alert(num.toString())
String()强制转换转成字符串var num = 1; alert(String(num))
加号拼接字符串和字符串拼接的结果都是字符串var num = 1; alert(num + '');
  • toString() 和 String()使用方式不一样。

  • 三种转换方式,我们更喜欢用第三种加号拼接字符串转换方式,第一种方式也称之为隐式转换。


四、转换为布尔型

方式说明案例
Boolean()函数其他类型转成布尔值Boolean('true');
  • 代表空、否定的值会被转换成 false,如''、0、NaN、null、underfined

  • 其余值都会被转换为 true

console.log(Boolean(''));	// false
console.log(Boolean(0));	// false
console.log(Boolean(NaN));	// false
console.log(Boolean(undefined));	// false
console.log(Boolean('苹果'));	// true
console.log(Boolean(12));	// true

五、简单和复杂数据类型

简单数据类型又叫做基本数据类型或者值类型,复杂数据类型又叫做引用数据类型。

  • 值类型:简单数据类型 / 基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型 string,number,boolean,undefined,null (返回的是一个空的对象)

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


六、堆栈空间分配区别:

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

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

注意:JavaScript中没有堆栈的概念,通过堆栈的方式,可以让大家更容易理解代码的一些执行方式,便于将来学习其他语言。


目录:

能够使用常用运算符
能够说出前置递增和后置递增的区别
能够说出运算符的优先级

目录:

运算符
算数运算符
递增递减运算符
比较运算符
逻辑运算符
赋值运算符
运算符优先级

运算符

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

JavaScript中常用的运算符有:

  • 算数运算符

  • 递增和递减运算符

  • 比较运算符

  • 逻辑运算符

  • 赋值运算符


算数运算符

一、算术运算符概述

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

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

二、浮点数的精度问题

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

var result = 0.1 + 0.2;	// 结果不是0.3,而是:0.30000000000000004
console.log(0.07*100);	// 结果不是 7,而是:7.00000000000000001

注意:% 取余运算符的主要用途余数为0,说明这个数能被整除


三、表达式和返回值

由变量、常量和函数调用按规则用运算符连接起来的式子 称为表达式

单个的常量、变量、函数调用也可以看作是表达式的特例

凡是合法的 表达式都有一个值,即运算结果,我们称为返回值

// 是由数字、运算符、变量等组成的式子 1+1
console.log(1+1);	//	2 就是返回值
在我们程序里面 2=1+1	把我们右边表达式计算完毕后将返回值给左边

递增和递减运算符

一、递增和递减概述

如果需要反复给数字变量添加或减去1,可以使用递增 (++) 和 递减 (--)运算符来完成。

在JavaScript中,递增 (++) 和 递减 (--) 既可以放在变量前面,也可以放在变量后面。放在变量前面时,我们可以称为前置递增 (递减) 运算符,放在变量后面时,我们可以称为后置递增 (递减)运算符。

注意:递增和递减运算符必须和变量配合使用。


二、递增运算符

前置递增运算符

++num 前置递增,就是自加1,类似于num = num +1,但是++num 写起来更简单。

使用口诀:先自加,后返回值


后置递增运算符

num++ 后置递增,就是自加1,类似于num=num+1,但是 num++写起来更简单。

使用口诀:先返回原值,后自加


比较运算符

一、比较运算符概述

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

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

逻辑运算符

一、逻辑运算符概述

概念:逻辑运算符是用来进行布尔值运算的运算符,其返回值也是布尔值。后面开发中经常用于多个条件的判断

逻辑运算符说明案例
&&"逻辑与",简称 "与" andtrue && false
||"逻辑或",简称 "或" ortrue || false
"逻辑非",简称 "非" not! true

逻辑与 && and:两侧都为 true 结果才是true,只要有一侧为false,结果就为false.

逻辑或 || or: 两侧都为false 结果才是假 false 只要有一侧为true,结果就是true.

逻辑非 ! not: 也叫做取反符,用来去一个布尔值相反的值,如 true 的相反值是false.

console.log(3>5 && 3>2);	//false	//逻辑与
console.log(3<5 || 3>4);	//true	//逻辑或

(这里用来我们的布尔值参与的逻辑运算)


二、短路运算 (逻辑中断)

短路运算的原理:当有多个表达式 (值) 时,左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值;

  1. 逻辑与

  • 语法:表达式1 && 表达式2

  • 如果第一个表达式的值为真,则返回表达式2

  • 如果第一个表达式为假,则返回表达式1

console.log(123 && 456);   //456	//除了0以外,其余数字都为真

三、为假的值有:

0,'' (空字符串),null,undefined,NaN

  1. 逻辑或

  • 语法:表达式1 || 表达式2

  • 如果第一个表达式的值为真,则返回表达式1

  • 如果第一个表达式为假,则返回表达式2

console.log(123 || 456);		// 123
console.log(0 || 456);			// 456
console.log(123 || 456 || 789);	//123

赋值运算符

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

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

其他运算符

一、三目运算符

语法:

表达式?表达式1:表达式2;

三元运算符执行思路:

  • 如果表达式的结果为true的话,那么返回就返回表达式1的值,如果表达式的结果是false的话,那么就返回表达式2的值.


二、一元运算符

常见的一元运算符有:

  1. 递增和递减运算符:++ 和 --,用于对操作数进行增加或减少 1。

  2. 正负号运算符:+ 和 -,用于表示正负数。

  3. 逻辑非运算符:!,用于对布尔值进行取反。


三、二元运算符

常见的二元运算符有:

  1. 算术运算符:+、-、*、/、%,用于执行加法、减法、乘法、除法和取模运算。

  2. 关系运算符:==、!=、>、<、>=、<=,用于比较两个操作数之间的关系,返回布尔值。

  3. 逻辑运算符:&&、||,用于执行逻辑与和逻辑或运算。

  4. 赋值运算符:=、+=、-=、*=、/=、%=,用于将右侧的值赋给左侧的变量。

  5. 位运算符:&、|、^、<<、>>、>>>,用于执行位操作。


运算符优先级

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

目标:

能够使用 if 分支语句
能够使用 switch 分支语句
能够使用 三元表达式

目录

流程控制
顺序流程控制
分支流程控制 if 语句
三元表达式
分支流程控制 switch 语句

流程控制

在一个程序执行的过程中,各条代码的执行顺序对程序的结果是有直接影响的。很多时候我们要通过控制代码的执行顺序来实现 要完成的功能。

简单理解:流程控制就是 来控制我们代码按照什么结构顺序来执行

流程控制主要有三种结构,分别是 顺序结构分支结构 循环结构,这三种结构代表三种代码执行的顺序。


顺序流程控制

顺序结构是程序中最简单,最基本的流程控制,它没有特定的语法结构,程序会按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。


分支流程控制

由上到下执行代码的过程中,根据不同的条件,执行不同的路径代码 (执行代码多选一的过程),从而得到不同的结果。

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

  • if 语句

  • switch 语句


一、if语句

语法结构

案例:判断闰年

接受用户输入的年份,如果是闰年就弹出闰年,否则弹出是平年

思路:能被4整除且不能被100整除或者能被400整除的是闰年。

var year = prompt('请输入闰年的年份:');
if(year%4==0 && year%100!=0 || year%400==0){
    alert('你输入的年份是闰年');
}else{
	alert('你输入的年份不是闰年')
}

if else if 语句 (多分支语句)

语法格式:

if(条件表达式){
	语句1;
}else if(条件表达式2){
	语句2;
}else if(条件表达式3){
	语句3;
}else{
	最后的语句;
}
  1. 执行思路:

    如果条件表达式1 满足就执行 语句1 执行完毕后,退出整个 if 分支语句。

    如果表达式1 不满足,则判断条件表达式2 满足的话,执行语句2,行完毕后,退出整个 if 分支语句。

    如果上面的所有条件表达式都不成立,则执行else里面的语句。

  2. 注意点:

    • 多分支语句还是多选一,最后只能有一个语句执行

    • else if 里面的条件理论上是可以任意多个的

    • else if 中间有个空格


二、switch 语句

语法结构

switch 语句也是多分支语句,它用于基于不同的条件来执行不同的代码。当要针对变量设置一系列的特定值的选项时,就可以使用switch.

switch(表达式){
	case value1:
		执行语句1;
		break;
	case values2: 
		执行语句2;
		break;
	...
	default:
		执行最后的语句;
}
  1. 执行思路:

利用我们的表达式的值 和 case 后面的选项值相匹配,如果匹配上,就执行该case里面的语句,如果都没有匹配上,那么执行default里面的语句。

案例:查询水果

用户在弹出框里面输入一个水果,如果有就弹出该水果的价格,没有就弹出"没有此水果"。

案例分析

  1. 弹出 prompt 输入框,让用户输入水果名词,把这个值取过来保存到变量中。

  2. 将这个变量作为 switch 括号里面的表达式。

  3. case 后面的值写几个不同的水果名称,注意一定要加引号,因为必须是全等匹配。

  4. 弹出不同价格即可。同样注意每个 case 之后加上 break,以便退出 switch 语句。

  5. 将default 设置为没有此水果

<script> 
var fruit = prompt('请输入你查询的水果:');
    switch(fruit){
        case '苹果':
            alert(6+'元/斤');
            break;
        case '梨':
            alert(4+'元/斤');
            break;
    default:
        alert('没有此水果');
        break;
    } 
</script>

3.注意事项

  1. 我们开发里面,表达式我们经常写成变量.

  2. 我们 num 的值 和 case 里面的值相匹配的时候全等,必须是值和数据类型一致才可以.

  3. break 如果当前的case里面没有break,则不会退出switch,而是继续执行下一个case.

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

  • swith...case 语句通常处理 case 为比较确定值的情况,而 if ...else...语句更加灵活,常用于范围判断(大于、等于某个范围)

  • switch 语句进行条件判断后执行到程序的条件语句,效率更高,而if...else语句有几种条件,就得判断多少次。

  • 当分支比较少时,if...else语句的执行效率比switch语句高。


三元表达式

三元表达式也能做一些简单的条件选择。由三元运算符组成的式子称为三元表达式。

  1. 语法结构

条件表达式 ? 表达式1 : 表达式2

如果条件表达式结果为真,则返回表达式1的值,如果表达式结果为假,则返回表达式2的值。

案例:数字补0

var time = prompt('请输入一个0~59之间的一个数字:');
 var result = time<10 ? '0' + time : time;
alert(result);

目标:

能够说出循环的目的
能够说出 for 循环的执行过程
能够使用断点调试来观察代码的执行过程
能够使用 for 循环完成累加求和等案例
能够使用双重 for 循环完成乘法表案例
能够说出 while 循环和 do while 循环的区别
能够说出 break 和 continue的区别

目录

循环
for循环
双重 for 循环
while 循环
do while 循环
continue break

循环

一、循环的目的

重复执行某些代码

  • 在实际问题中,有许多具有规律性的重复操作,因此在程序中要完成这类操作就需要重复执行某些语句。

二、JS 中的循环

在Js中,主要有三种类型的循环语句:

  • for 循环

  • while 循环

  • do...while循环


For 循环

在程序中,一组被重复执行的语句被称之为循环体能否继续重复执行取决于循环的终止条件由循环体及循环的终止条件组成的语句,被称为循环语句


一、语法结构

for 循环主要用于把某些代码循环若干次,通常跟计数有关系。其语法结构如下:

for(初始化变量(1);条件表达式(2);操作表达式(4)){
	// 循环体;(3)
}
  • 初始化变量:就是用var声明的一个普通变量,通常用于作为计数器使用

  • 条件表达式:就是用来决定每一次循环是否继续执行,就是终止条件

  • 操作表达式:是每次循环最后执行的代码,经常用于我们计数器变量进行更新(递增或者递减)

// 1.首先执行里面的计数器变量 var i = 1. 但是这句话在 for 里面只执行一次 index
// 2. 去 i <= 100 来判断是否满足条件,如果满足条件,就去执行循环体,不满足条件就退出循环
// 3.最后去执行 i++ i++是单独写的代码
-------------------------------------------------
for(var i =1;i <=10; i++){
	console.log('Hello!');
}

二、断点调试

断点调试是指自己在程序的某一行设置一个断点,调试运行到这一行就会停住,然后你可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行就显示错误,停下。

断点调试可以帮我们观察程序的运行过程

浏览器中按 F12 -->sources -->找到需要调试的文件 --> 在程序的某一行设置断点,重新刷新页面。

Watch:监视,通过 watch 可以监视变量的值的变化,非常的常用。

F11:程序单步执行,让程序一行一行的执行,这个时候,观察 watch中变量的值的变化。

代码调试的能力非常重要,只有学会了代码调试,才能学会自己解决bug的能力。初学者不要觉得调试代码非常麻烦就不去调试,知识点花点功夫肯定学的会,但是代码调试这个东西,自己不去练,永远都学不会。


三、for 循环重复不同的代码

for 循环还可以重复不同的代码这主要是因为使用了计数器计数器在每次循环过程中都会有变化。

for(var i =1; i<=10; i++){
	if(i==1){
		console.log('第'+i+'次');
	}else if(i==10){
		console.log('第'+i+'次')
	}
}

案例

要求用户输入班级人数,之后依次输入每个学生的成绩,最后打印出该班级总成绩以及平均成绩。

var sum = 0;
var average = 0;
var num = prompt('我们班有多少学生:');
for(var i=1; i<=num; i++){
  var gade = prompt('请输入第'+i+'个学生成绩:');
   sum+=parseFloat(gade);
}
  average = sum/num;
  alert(sum);
  alert(average);

通过追加字符串的方式,将数据一行展示

var str ='';
for(var i=1;i<=5;i++){
     str=str+'*';
}
alert(str);

双重 for 循环

很多情况下,单层 for 循环并不能满足我们的需求,比如我们要打印一个 5 行 5 列的图形、打印一个倒直角三角形等,此时就可以通过循环嵌套来实现。


一、语法结构:

// 1.我们可以把里面的循环看做是外层循环的语句
// 2.外层循环循环一次,里面的循环执行全部

for(外层的初始化变量;外层的条件表达式;外层的操作表达式){
	for(里层的初始化变量;里层的条件表达式;里层的操作表达式)
}

案例:

// 打印三角形
var str = '';
for(var i=1;i<=5;i++){   // 外层循环打印五行
   for(var j=1;j<=i;j++){   // 里层循环负责一行打印五个星星
    str+='*';
}
    str+='\n';
}
console.log(str);

// 打印倒三角形
// 核心算法:里层循环:j = i; j<10; j++
for(var i=1;i<=10;i++){   
   for(var j=i;j<=10;j++){   
       str+='*';
	}
str+='\n';
}
alert(str);

// 打印九九乘法表
var str ='';
for(var i=1;i<=9;i++){   
    for(var j=1;j<=i;j++){   
	// 1 * 2 =2;
    str += i +'*'+ j +'='+ i*j +'\t';

  }
    str+='\n';
}
console.log(str);

While循环

一、语法结构

// 1. while 循环语法结构   while  当...的时候
// 2. 执行思路  当条件表达式为true,则执行循环体,否则退出循环
// 3. 里面应该也有计数器,初始化变量
// 4. 里面应该也有操作表达式,完成计数器的更新,防止死循环

while(条件表达式){
	// 循环体;
	变量++;
}

// 弹出一个提示框,你爱我吗?如果输入我爱你,就提示结束,否则一直询问
var live = prompt('你爱我吗?');
while(live !='我爱你'){
     message = prompt('你爱我吗?');
}
alert('我也爱你!');

do while循环

一、语法结构

do{
	// 循环体
	变量++;
} while(条件表达式)

二、执行思路

  • 先执行一次循环体代码

  • 再执行条件表达式,如果结果为true,则继续执行循环体代码,如果为false,则退出循环,继续执行后面代码。

注意:先执行循环体,再判断,do...while循环语句至少会执行一次循环体代码。

案例

打印人的一生,从1岁到100岁

<script>
var i = 1;
do{
	console.log('你今年'+ i + '岁了');
    i++;
}while(i <= 100)
</script>

计算1~100之间所有的整数的和

<script>
var sum = 0;
var j = 1;
do {
	sum+=j;
	j++
}while(j <= 100)
console.log(sum);
</script>

  1. 弹出一个提示框,你爱我吗?如果输入我爱你,就提示结束,否则,一直询问

<script>
do {
	var message = prompt('你爱我吗?');
} while(message !== '我爱你')
    alert('我也爱你');
</script>

continue 与 break

一、continue 关键字

continue关键字 用于立即跳出本次循环,继续下一次循环。

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

二、break 关键字

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

for(var i=1; i<=5;i++){
	if(i==3){
		break;
	}
	console.log('循环第'+i+'次');
}

目标:

能够知道为什么要有数组
能够创建数组
能够获取数组种的元素
能够对数组进行遍历
能够给数组新增一个元素
能够独立完成冒泡排序的案例

目录

数组的概念
创建数组
获取数组中的元素
遍历数组
数组中新增元素
数组案例

数组的概念

问:之前学习的变量,只能存储一个值,如果我们想存储班级中所有学生的姓名,那么该如何存储呢?

答:可以使用数组 (Array)。数组可以把一组相关的数据一起存放,并提供方便的访问 (获取) 方式。

问:什么是数组呢?

答:数组 (Array) 是指一组数据的集合其中的每个数据被称作 元素在数组中可以存放任意类型的数据数组一种将一组数据存储在单个变量名下的优雅方式

// 普通变量一次只能存储一个值
var num = 10;
// 数组一次可以存储多个值
var arr = [1,2,3,4...];

创建数组

一、数组的创建方式

  • 利用 new 创建数组

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


二、利用 new 创建数组

var 数组名 = new Array();
var arry = new Array();
  • 注意:Array(),A要大写


三、利用字面量创建数组

// 1.使用数组字面量方式创建空的数组
var 数组名 = [];
// 2. 使用数组字面量方式创建带初始值的数组
var 数组名 = ['小白','小黑','瑞奇'];
  • 数组的字面量是方括号 []

  • 声明数组并赋值称为 数组的初始化

  • 这种字面量方式也是我们以后最多使用的方式


四、数组元素的类型

数组中可以存放任意类型的数据,例如:字符串,数字,布尔值等。


获取数组中的元素

一、数组的索引

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

var arr = ['小白','小黑','瑞奇'];
	索引号:   0      1     2

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

这里的访问就是获取得到的意思

// 定义数组
var arrStus = [1,2,3];
// 获取数组中的第2个元素
alert(arrStus[1]);	// 2

二、遍历数组

问:数组中的每一项我们怎么取出来?

答:可以通过"数组名[索引号]"的方式一项项的取出来。

var arr = ['red','green','blue'];
console.log(arr[0]);	// red
console.log(arr[1]);	// green
console.log(arr[2]);	// blue

问:怎么把数组里面的元素全部取出来?

规律:

从代码中我们可以发现,从数组中取出每一个元素时,代码时重复的,有所不一样的是索引值在递增。

答案就是循环


遍历:就是把数组中的每个元素从头到尾都访问一遍。

var arr = ['red','green','blue'];
for(var i = 0; i<arr.length; i++){
	console.log(arr[i]);
}

数组名.length"可以访问数组元素的数量 (数组长度)

 


三、数组中的最大值

// 1.声明一个保存最大元素的变量 max
// 2.默认最大值可以取数组中的第一个元素
// 3.遍历这个数组,把里面每个数组元素和 max 相比较

var arr = [2,4,1,5,21,11];
var max = arr[0];
for (var i = 1; i<arr.length; i++){
	if(arr[i]>max){
		max = arr[i];
	}
}
console.log(max);

四、数组转换为字符串

要求:将数组['red','green','blue','pink']转换为字符串,并且用 | 或其他符号分割。

输出:'red|green|blue|pink|'

// 案例分析
// 1.需要一个新变量用于存放转换完的字符串 str。
// 2.遍历原来的数组,分别把里面数据取出来,加到字符串里面。
// 3.同时在后面多加一个分隔符

var arr = ['red','green','blue','pink'];
var str ='';
var sep = '|'	// 声明一个变量来存放 '|';
for (var i = 0; i<arr.length; i++){
	str += arr[i] + sep;
}
console.log(str);

数组中新增元素

可以 通过修改 length 长度 以及 索引号增加数组元素


一、length 长度新增数组元素

  • 可以通过修改 length 长度来实现数组扩容的目的

  • length 属性是可读写的

var arr = ['red','green','blue','pink'];
arr.length = 5;	// 把我们数组的长度修改为了 5,里面应该有5个元素
console.log(arr[4]);	// undefined

其中索引号 4 的空间没有给值,就是声明变量未给值,默认值就是 undefined。


二、数组索引新增数组元素

  • 追加数组元素

var arr = ['red','green','blue','pink'];
arr[4] = 'yellow';
console.log(arr);
arr[0] = 'orange';	// 这里是替换原来的数组元素

案例

// 1.新建一个数组,里面存放10个整数 ( 1~10 )
var arr = [];
for (var i = 0; i<10; i++){
	arr[i] = i + 1;
}
console.log(arr);

// 2.将数组[2,0,6,1,77,0,52,10,25,7] 中大于等于 10 的元素选出来,放入新数组

// 方法1:
var arry = [2,0,6,1,77,0,52,10,25,7];
var nextArry = [];
var j = 0;
for (var i = 0; i<arry.length; i++){
	if(arry[i] >= 10){
	nextArry[j] = arry[i];
	j++;
	}
}
console.log(nextArry);

// 方法2:
var arry = [2,0,6,1,77,0,52,10,25,7];
var nextArry = [];
for (var i = 0; i<arry.length; i++){
	if(arry[i] >= 10){
	nextArry[nextArry.length] = arry[i];
	}
}
console.log(nextArry);

数组案例

一、删除指定数组元素

要求:将数组 [2,0,6,1,77,0,52,10,25,7]中的 0 去掉后,形成一个不包含 0 的新数组。

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

二、翻转数组

要求:将数组['red','green','blue','pink']的内容反过来存放。

输入['pink','blue','green','red']

// 将旧数组索引号第4个取过来(arr.length-1),给新数组索引号第0个元素(newArr.length)
// 我们采取 递减 的方式 i--
var arr = ['red','green','blue','pink'];
var newArr = [];
for(var i = arr.length-1; i >= 0; i--){
	newArr[newArr.length] = arr[i];
}
console.log(newArr);

三、冒泡排序

冒泡排序:是一种算法,把一系列的数据按照一定的顺序进行排列显示 (从小到大或从大到小)。

算法:观察程序执行过程,从而找到其中的规律,把它转化为代码。

案例分析:

先观察规律:

  1. 一共需要的躺数,我们用外层 for 循环

    • 五个数据我们一共需要走 4 趟

    • 长度就是 数组长度 减去 1 arr.length -1

  2. 每一趟交换次数,我们用里层 for 循环

    • 第一趟交换 4 次

    • 第一趟交换 3 次

    • 第一趟交换 2 次

    • 第一趟交换 1 次

    长度就是数组长度 减去 次数,但是我们次数是从 0 开始的, 所以 最终 arr.length -i -1


var arr = [5,2,4,1,3];
for (var i = 0; i <= arr.length-1; i++){	// 外层循环管趟数	
	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);

目录:

能够说出为什么需要函数
能够根据语法书写函数
能够根据需求封装函数
能够说出形参与实参的传递过程
能够使用函数的返回值
能够使用arguments获取函数的参数

目录

函数的概念
函数的使用
函数的参数
函数的返回值
arguments的使用
函数案例
函数的两种声明方式

函数的概念

在 JS 里面,可能会定义非常多的相同代码或者功能相似的代码,这些代码可能需要大量重复使用。虽然 for 循环语句也能实现一些简单的重复操作,但是比较具有局限性,此时我们就可以使用 JS 中的函数。

函数:就是封装了一段可被重复调用执行的代码块。通过此代码可以实现大量代码的重复使用。

// 函数 
function  getSum(num1,num2){
	var sum = 0;
	for (var i = num1; i <= num2; i++){
		sum +=i;
	}
	consloe.log(sum);
}
getSum(1,100);

目的:就是让大量代码重复使用


函数的使用

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

一、函数声明方式

// 1.利用函数关键字自定义函数(命名函数)
function 函数名(){
	// 函数体代码;
}
  • function声明函数的关键字,必须小写

  • 由于函数一般是为了实现某个功能才定义的,所以通常我们将函数名命名为动词,比如 getSum


// 2.函数表达式(匿名函数)
var fun = function(aru){
	console.log(aru);
};
fun('hello')
// (1) fun是变量名,不是函数名
// (2) 函数表达式声明方式跟变量声明差不多,只不过变量里面存的是值,而函数表达式里面存的是函数
// (3) 函数表达式也可以进行传递参数

二、调用函数

// 调用函数
函数名 ();	// 通过调用函数名来执行函数体代码
  • 调用的时候千万不要忘记添加小括号

  • 口诀:函数不调用,自己不执行

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


三、函数的封装

  • 函数封装:就是把一个或者多个功能通过函数的方式封装起来对外只提供一个简单的函数接口


函数参数

一、形参和实参

在声明函数时,可以在函数名称后面的小括号中添加一些参数这些参数被称为形参,而在调用该函数时,同样也需要传递相应的参数这些参数被称为实参

functuin 函数名(形参1,形参2...){
	// 函数体;
}
函数名(实参1,实参2);

二、函数形参与实参个数不匹配的问题

参数个数
实参个数等于形参个数输出正确结果
实参个数大于形参个数只取到形参的个数
实参个数小于形参个数多的形参定义为undefined,结果为NaN

函数的返回值

一、return 语句

有的时候,我们会希望函数将值返回给调用者,此时通过 return 语句就可以实现。

// 函数的返回值格式
function 函数名(){
	return 需要返回的结果;
}
函数名();
  • 只要函数遇到 return,就把后面的结果返回给函数的调用者,函数名() = return后面的结果

function getResult(){
	return 666;
}
console.log(getResult());	//getResult() = 666

// 利用函数求数组 [5,2,99,101,67,77]中的最大数值
function getArrMax(arr){
	var max = arr[0];
	for (var i=1; i<=arr.length; i++){
		if(arr[i] > max){
			max = arr[i];
		}
	}
	return max;
}
// getArrMax([5,2,99,101,67,77]);	// 实参是一个数组送过去
// 在我们实际开发中,我们经常用一个变量来接收函数的返回结果,使用更简单
var re = getArrMax([5,2,99,101,67,77]);
console.log(re);

二、return 终止函数

return 语句之后的代码不被执行。

// 1.return 终止函数
function getSum(num1,num2){
	return num1 + num2;
	alert('我是不会被执行的');	// 这句话不执行
}
console.log(getSum(1,2));

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

三、函数没有 return 返回 undefined

函数都是有返回值的

  1. 如果有 return,则返回 return 后面的值

  2. 如果没有 return,则返回 undefined


break,continue,return的区别

  • break:结束当前的循环体

  • continue:跳出本次循环,继续执行下次循环

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


arguments的使用

当我们不确定有多少个参数传递的时候,可以用 arguments 来获取。在 JavaScript 中,arguments 实际上它是当前函数的一个内置对象。所有函数都内置了一个 arguments 对象,arguments 对象中存储了传递的所有实参。

arguments 展示形式是一个伪数组,因此可以进行遍历。伪数组有以下特点:

  • 具有 length 属性

  • 按索引方式存储数据

  • 不具有数组的 push,pop等方法


// arguments的使用
function fn(){
	console.log(arguments);		// [1,2,3]里面存储了索引传递过来的实参
}
fn(1,2,3);

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

function getMax(){
	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));

案例

函数可以调用另外一个函数

因为每个函数都是独立的代码块,用于完成特殊任务,因此经常会用到函数相互调用的情况。

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

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

目标:

能够说出 JavaScript的两种作用域
能够区分全局和局部变量
能够说出如何在作用域中查找变量的值

目录:

作用域
变量的作用域
作用域链

作用域

一、JS的作用域

通常来说,一段程序代码中所用的的变量并不总是有效和可用的,而限定这个变量的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序的逻辑的局限性,增强了程序的可靠性,减少了名字冲突。

JS的作用域(es6)之前:全局作用域和局部作用域

// 全局作用域:整个script标签 或者 是一个单独的 js 文件
<script>
	var num = 10;
	console.log(num);
</script>

// 局部作用域(函数作用域) 在函数内部就是局部作用域,这个代码的名字只在函数内部起效果和作用
function fn(){
	// 局部作用域
	var num = 23;
	console.log(num);
}
fn();

二、变量的作用域

(1) 变量作用域的分类

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

  • 全局变量:在全局作用域下的变量

  • 局部变量:在局部作用域下的变量 (只能在函数内部使用)

function fun(){
  var num = 1;
}
fun();
console.log(num);	// 局部变量只能在函数内部使用,结果为 num is not defined

注意:

  • 在函数内部没有声明直接赋值的变量也属于全局变量

  • 函数的形参也可以看做是局部变量


全局变量和局部变量的区别:

  1. 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源

  2. 局部变量,当我们程序执行完毕就会销毁,比较节约内存资源


三、作用域链

  • 只要是代码,就至少有一个作用域

  • 写在函数内部的局部作用域

  • 如果函数中含有函数,那么在这个作用域中就又可以诞生一个作用域

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

// 一层一层查找(就近原则)
<script>
var num = 10;	// 全局作用域
function fn(){	// 外部作用域
	var num = 20;
	
	function fun(){	// 内部作用域
		console.log(num);
	}
    fun();
}
fn();	// 20
</script>

目标:

能够知道解析器运行 JS 分为哪两步
能够说出变量提升的步骤和运行过程
能够说出函数提升的步骤和运行过程

目录

预解析
变量预解析和函数预解析
预解析案例

预解析

JavaScript代码是由浏览器中的 JavaScript 解析器来执行的。JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析 和 代码执行。

  1. 预解析:JS引擎会把 js 里面的所有的 var 还有 function 提升到当前作用域的最前面。

  2. 代码执行:按照代码书写的顺序从上往下执行。


一、变量预解析

// 案例1
var num = 10;
fun();
function fun() {
	console.log(num);
	var num = 20;
}
// 相当于执行了以下操作
var num;
function fun() {
	var num;
	console.log(num);	// undefined
	num = 20;
}
num = 10;
fun();

二、函数与解析

// 案例2
var num = 10;
function fn() {
	console.log(num);
	var num = 20;
	console.log(num);
}
fn();
// 相当于执行了以下操作
var num;
function fn() {
	var num;
	console.log(num);	// undefined
	 num= 20;
	console.log(num);	// 20
}
num = 10;
fn();

目标:

能够说出为什么需要对象
能够使用字面量创建对象
能够使用构造函数创建对象
能够说出 new 的执行过程
能够遍历对象

目录:

对象
创建对象的三种方式
new 关键字
遍历对象属性

对象

一、什么是对象?

显示生活中:万物皆对象,对象是一个具体的事物,看得见摸得着的实物。例如,一本书,一辆汽车,一个数据库,一张网页都可以是对象。

在 JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数组、函数等。

对象是由属性方法组成的。

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

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


二、为什么需要对象

保存一个值时,可以使用变量,保存多个值 (一组值)时,可以使用数组,如果要保存一个人的完整信息呢?

例如:将"张三丰"的个人信息保存在数组中的方式为:

var arr = ['张三丰','男',128,164];

JS中对象表达结构更清晰,更强大。张三丰的个人信息在对象中的表达结构如下:

张三丰.姓名 = '张三丰';

张三丰.性别 = '男';

张三丰.年龄 = '18';

张三丰.身高 = 180;

创建对象的三种方式

在 JavaScript 中,现阶段我们可以采用三种方式创建对象 (object):

  • 利用字面量创建对象

  • 利用new Object创建对象

  • 利用构造函数创建对象


一、利用字面量创建对象

对象字面量:利用花括号{}里面包含了表达这个具体事物 (对象)的属性和方法。

var obj ={
	uname:'张三丰',
	age:18,
	sex:'男',
	sayHi:function(){
		console.log('Nice to meet you');	
	}
};
  • 里面的属性或者方法我们采取键值对的形式

  • 多个属性或者方法中间用逗号隔开的

  • 方法后面跟的是一个匿名函数


二、利用 new Object创建对象

跟我们前面学的 new Array()原理一致

var obj = new Object();
	obj.uname = '张三丰';
	obj.age = 18;
	obj.sayHi = function(){
		console.log('Nice to meet you');
	}

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

构造函数:是一种特殊的函数主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

// 利用构造函数创建对象
function 构造函数名(){	//构造函数名首字母要大写
	this.属性 = 值;	//this: 当前的
	this.方法 = function(){}
}
new 构造函数名();	//调用构造函数

// 我们需要创建四大天王的对象 相同的属性:名字,年龄,性别,相同的方法:唱歌
function  Star(uname,age,sex){
	this.name = uname;
	this.age = age;
	this.sex = sex;
	this.sing = function(sang){
		console.log(sang)
	}
}
var ldh = new Star('刘德华',18,'男');
console.log(ldh);
ldh.sing('冰雨');	//调用函数

注意:

  • 构造函数名首字母要大写

  • 构造函数不需要return就可以返回结果

  • 我们调用构造函数就必须使用 new


四、调用对象

调用对象的属性,我们采取 对象名.属性名

console.log(obj.uname);

调用属性还有一种方法对象['属性名']

console.log(obj['age']);

调用对象的方法,我们采取 对象名.方法名 ()

obj.sayHi();

new 关键字

new 在执行时会做四件事情

  1. 在内存中创建一个新的空对象。

  2. 让 this 指向这个新的对象。

  3. 执行构造函数里的代码,给这个新对象添加属性和方法。

  4. 返回这个对象 (所以构造函数里面不需要 return)


遍历对象属性

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

var obj ={
	name:'杰克',
	age:18
}
for (var k in obj){
	console.log(k);	// 得到的是属性名
	console.log(obj[k]);	// 得到的是属性值
}
// 我们使用 for in 里面的变量,我们喜欢写 k 或 key

构造函数与对象的区别

  • 构造函数,如 Star(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类 (class)

  • 创建对象,如 new Star(),特指某一个,通过new 关键字创建对象的过程我们也称为对象实例化


目标:

能够说出什么是内置对象
能够根据文档查询指定API的使用方法
能够使用 Math 对象的常用方法
能够使用 Date 对象的常用方法
能够使用 Array 对象的常用方法
额能够使用 String 对象的常用方法

目录:

内置对象
查文档
Math 对象
日期对象
数组对象
字符串对象

内置对象

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

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

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

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

  • JavaScript提供了多个内置对象:MathDateArrayString


查文档

MDN

学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过查文档学习,可以通过 MDN / W3C来查询。

Mozilla 开发网络 (MDN) 提供了有关开放网络技术 (Open Web)的信息,包括 HTML、CSS 和 万维网及 HTML5的应用的API。

MDN:MDN Web Docs


如何学习对象中的方法

  1. 查阅方法的功能

  2. 查看里面参数的意义和类型

  3. 查看返回值的意义和类型


Math 对象

一、Math概述

Math对象不是构造函数,它具有数学常数和函数的属性和方法。跟属性相关的运算 (求绝对值,取整、最大值等)可以使用Math中的成员。

Math.PI			//圆周率
Math.floor()	//向下取整	Math.floor(1.1)结果为1
Math.ceil()		//向上取整	Math.ceil(1.1)结果为2
Math.round()	//四舍五入版	就近取整	注意	-3.5  结果是 -3,.5特殊,往大的取
Math.abs()		//绝对值。会把字符串型 -1 转换为数字型
Math.max()		//求最大
Math.min()		//最小值

案例:利用对象封装自己的数学对象,里面有 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,2));

二、随机数方法

  • random() 返回一个随机的小数 0 <= x< 1

  • 这个方法里面不跟参数

// 我们想要得到两个数之间的随机整数 并且包含这2个整数
公式:Math.floor(Math.random()*(max - min + 1)) + min;
function getRandom(min,max){
	return Math.floor(Math.random() * (max - min + 1)) + min;
}

// 随机点名
var arr = ['扬州','北京','杭州','长沙'];
console.log(arr[getRandom(0,3)]);

// 猜数字游戏
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;
	}
}

日期对象

一、Date概述

  • Date 对象和 Math 对象不一样,他是一个构造函数,所以我们需要实例化后才能使用

  • Date 实例用来处理日期和时间


二、Date()方法的使用

获取当前时间必须实例化

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

Date()构造函数的参数

如果括号里面有时间,就返回参数里面的时间。例如日期格式字符串 '2020-10-01',就可以写成 new Date('2020-10-01') 或者 new Date('2020/10/01')


三、日期格式化

我们想要 2019-8-8 8:8:8格式的日期,要怎么办?

需要获取指定的部分,所以我们要手动的得到这种格式。

方法名说明代码
getFullYear()获取当前年dObj.getFullYear()
getMonth()获取当月 (0 - 11)dObj.getMonth() +1
getDate()获取当天日期dObj.getDate()
getDay()获取星期几 (周日0 到周六6 )dObj.getDay()
getHours()获取当前小时dObj.getHours()
getMinutes()获取当前分钟dObj.getMinutes()
getSeconds()获取当前秒dObj.getSeconds()

// 格式化日期	年月日
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var dates = date.getDate();
var arr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
var day = date.getDay();
console.log('今天是:' +year+ '年' + month + '月' + dates + '日' + arr[day]);

// 要求封装一个函数返回当前的时分秒 格式 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());

// 获取Date的毫秒数,不是当前时间的毫秒数,而是距离1970年1月1日过去了多少毫秒

// 1. 通过 valueOf(),getTime()
var date = new Date();
	console.log(date.valueOf());	// 就是我们现在时间	距离 1970.1.1 总的毫秒数
	console.log(date.getTime());

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

// 3.H5 新增的 获取总的毫秒数
console.log(Date.now());

案例:做一个倒计时效果

案例分析

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

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

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

// 转换公式如下:
d = parseInt(总秒数/60/60/24);	// 计算天数
h = parseInt(总秒数/60/60%24);	// 计算小时
m = parseInt(总秒数/60%60);	    // 计算分数
s = parseInt(总秒数%60);		// 计算当前秒数

// 倒计时效果
function countDown(time){
	var newTime = +new Date();	// 返回当前时间总的毫秒数
	var inputTime = +new Date(time);	// 返回用户输入时间总的毫秒数
	var times = (inputTime - newTime) / 1000;	// time是剩余时间总的毫秒数
	
	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 + '时' + s + '秒';
}
console.log(countDown('2023-8-1 18:00:00'));

数组对象

一、创建数组对象方式

  • 字面量方式

  • new Array()


// 1. 利用数组字面量
var arr = [1,2,3];
console.log(arr[0]);

// 2.利用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);

二、检测是否为数组

// 1.instanceof 运算符,它可以用来检测是否为数组
var arr = [];
var obj = {};
console.log(arr instanceof Array);	//ture
console.log(obj instanceof Array);	//false

// 2.Array.isArray(参数);		H5新增的方法	ie9以上版本才支持
console.log(Array.isArray(arr));
console.log(Array.isArray(obj));

三、添加删除数组元素

方法名说明返回值
unshift(参数1...)向数组的开头添加一个或更多元素,注意修改原数组并返回第一个元素的值
push(参数1...)末尾添加一个或多个元素并返回新的长度
shift()删除数组的第一个元素,数组长度减 1 ,无参数、修改原数组返回它删除的元素的值
pop()删除数组最后一个元素,把数组长度减 1 ,无参数、修改原数组并返回新的长度
// 添加数组元素
// 1.push()	末尾添加一个或多个元素
var arr = [1,2,3];
// arr.push(4,'pink');	// [1,2,3,4,'pink'];
console.log(arr.push(4,'pink'));  //5 (数组长度)

// 2.unshift()在我们数组的开头,添加一个或者多个数组元素
// arr.unshift(0,'red');  	//[0,'red',1,2,3,4,'pink']
console.log(arr.unshift('0'));	// 6 (数组长度)

// 删除数组元素
// 1.pop() 它可以删除数组的最后一个元素,pop()里面没有参数
var arr = [1,2,3];
arr.pop();	// 3 (返回删除的那个元素)

// 2.shift()
arr.shift();	// 1 (返回删除的那个元素)

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

var arr = [1500,1200,2100,1822];
var arr1 =[];
for (var i=0; i<arr.length; i++){
    if(arr[i] < 2000){
      //  arr1[arr1.length] = arr[i]
      arr1.push(arr[i])
    }
}
alert(arr1);

四、数组排序

方法名说明是否修改原数组
reverse()翻转数组中元素的顺序,无参数该方法会改变原来的数组,返回新数组
sort()对数组的元素进行排序该方法会改变原来的数组,返回新数组
// 1.翻转数组
var arr = ['pink','red','blue'];
arr.reverse(); 
console.log(arr);	//['blue','red','pink']

// 2.数组排序
var arr = [1,3,2,4];
arr.sort(function(a,b){
	return a - b;
});
alert(arr);		//[1,2,3,4]

// 当sort();	遇到[1,11,7,8,77]结果就不是[1,7,8,11,77],所以要用
数组名.sort(function(a,b){
	return a - b;	// 升序	// 降序 return b - a;
		
});

五、数组索引方法

方法名说明返回值
indexOf()数组中查找给定元素的第一个索引如果存在返回索引号,如果不存在,则返回 -1
lastIndexOf()在数组中的最后一个的索引如果存在返回索引号,如果不存在,则返回 -1
// 返回数组元素索引号方法	indexOf(数组元素)	作用就是返回该数组元素的索引号
// 它只返回第一个满足条件的索引号
// 它如果在该数组里面找不到元素,则返回的是 -1
var arr = ['red','green','blue','pink'];
	console.log(arr.indexOf('blue'));	// 2 (数组元素的索引号)
// 返回数组元素索引号方法 lastIndexOf(数组元素)
// 作用就是返回该数组元素的索引号,从后面开始查找
var arr = ['red','green','blue','pink','blue'];
	console.log(arr.lastIndexOf('red'));	// 0
	console.log(arr.lastIndexOf('blue'));	// 4 (从后往前找)

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

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

利用新数组 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'])
console.log(newArr);

六、数组转换为字符串

方法名说明返回值
toString()把数组转换为字符串,逗号分隔每一项返回一个字符串
join('分隔符')方法用于把数组中的所有元素转换为一个字符串返回一个字符串
// 数组转换为字符串
// 1. toString() 将我们的数组转换为字符串
var arr = [1,2,3];
console.log(arr.toString());	// 1,2,3

// 2. join('分隔符'),
var arr1 = ['green','blue','pink'];
console.log(arr1.join()); 		// green,blue,pink
console.log(arr1.join('-'));	//green-blue-pink

七、课下查询

方法名说明返回值
concat()连接两个或多个数组,不影响原数组返回一个新数组
slice()数组截取 slice(begin,end)返回被截取项目的新数组
splice()数组删除 splice(第几个开始,要删除个数)返回被删除项目的新数组。注意,这会影响原数组
  • slice() 和 splice() 目的基本相同


字符串对象

一、基本包装类型

为了方便操作基本数据类型,JavaScript 还提供了三个特殊的引用类型:StringNumberBoolean

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

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

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

// 1.生成临时变量,把简单类型包装为复杂数据类型
var temp = new String('andy');		
// (2)把临时变量的值给str
str = temp;		// str 存的就是一个对象
// (3) 销毁这个临时遍历
temp = null;

二、字符串的不可变

指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。

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

三、根据字符返回位置

字符串所有的方法,都不会修改字符串本身 (字符串是不可变的),操作完成会返回一个新的字符串。

方法名说明
indexOf('要查找的字符',开始的位置)返回指定内容的元字符串的位置,如果找不到就返回 -1,开始的位置是 index 索引号
LastIndexOf()从后往前找,只找到第一个匹配的
// 根据字符返回位置
var str = '改革春风吹满地,春天来了';
console.log(str.indexOf('春'));		// 2
consolog.log(str.indexOf('春',3));	// 8  (从索引号是 3 的位置开始往后查找)

案例:查找字符串 'abcoefoxyozzopp'中所有o 出现的位置以及次数

// 核心算法:
// 1.先查找第一个o的位置
// 2.然后只要indexOf()返回的结果不是-1就继续往后查找
// 3.因为indexOf()只能查找到第一个,所以后面的查找,
// 利用第二个参数,当前索引加1,从而继续查找
var str = "abcoefoxyozzopp";
var index = str.indexOf('o');	// 查找出第一个o 索引号为3
var num = 0;
while(index !== -1){            // 索引号3!===-1,继续循环
    console.log(index);	
    num++;
	index = str.indexOf('o', index + 1);		// index + 1 = 3+1
}
console.log('o出现的次数是' + num);

四、根据位置返回字符串

方法名说明使用
charAt (index)返回指定位置的字符 (index 字符串的索引号)str.charAt(0)
charCodeAt (index)获取指定位置处字符的ASCII码 (index索引号)str.charCodeAt(0)
str [index]获取指定位置处字符HTML5,IE8+支持 和charAt()等效
// 根据位置返回字符
// 1. charAt(index) 根据位置返回字符
var str = 'andy';
console.log(str.charAt(0));		// a

// 2.charCodeAt(index) 返回相应索引号的字符ASCII值,目的:判断用户按下了那个键
console.log(str.charCodeAt(0));		// 97 (a的ASCII码为97)
console.log(str[0]);	//	a

五、拼接以及截取字符串

方法名说明
concat(str1,str2,str3...)concat()方法用于连接两个或多个字符串,拼接字符串,等效于 +,+更常用
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(str.substr(2,2));		// 春风

六、替换字符串以及转换为数组

// 1. 替换字符 replace('被替换的字符','替换为的字符')
var str = 'andy';
console.log(str.replace('a','b'));		// bndy;

// 2. 字符转换为数组	split('分隔符')
var str2 = 'red,pink,blue';
console.log(str2.split(','));		// 看变量内的值用的是什么分隔开来的就用它
['red','pink','blue']
var str3 = 'red&pink&blue';
console.log(str3.split('&'));	

七、大小写转换

  • toUpperCase() // 转换大写

  • toLowerCase() // 转换小写


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值