JavaScript基础、DOM以及BOM笔记(一)

计算机编程基础

1. 编程语言

1.1 编程

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

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

从事编程的人员,就是**程序员**。但是一般程序员都比较幽默,为了形容自己的辛苦工作,也成为“码农”,或者“程序猿”/“程序媛“

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

1.2 计算机语言

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

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

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

x     0=00000000  1=00000001  2=00000010  3=00000011  4=00000100	    5=00000101  6=00000110  7=00000111  8=00001000  9=00001001    10=00001010

1.3 编程语言

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

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

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

  • **汇编语言**和机器语言实质是相同的,都是直接对硬件操作,只不过指令采用了英文缩写的标识符,容易识别和记忆。
  • **高级语言**主要是相对于低级语言而言,它并不是特指某一种具体的语言,而是包括了很多编程语言,常用的有c语言、c++、Java、c#、Python、PHP、JavaScript、Go语言、Objective-C、Swift等。
	C语言:pust("你好");
	PHP: echo "你好";
	Java: System.out.printIn("你好");
	JavaScript: alert("你好");	

1.4 翻译器

高级语言所编制的程序不能直接被计算机识别,必须经过转换才能被执行,为此,我们需要一个翻译器。

翻译器可以将我们所编写的源代码转换为机器语言,这也被称为二进制化。记住1和0。

1.5 编程语言和标记语言区别

  • **编程语言**有很强的逻辑和行为能力。在编程语言里,你会看到很多if else、for、while等具有逻辑性和行为能力的指令,这是主动的。
  • 标记语言(HTML)不用于向计算机发出指令,常用于格式化和链接。标记语言的存在是用来被读取的,他是被动的。

总结

  1. 计算机可以帮助人类解决某些问题
  2. 程序员利用编程语言编写程序发出指令控制计算机来实现这些任务
  3. 编程语言有机器语言、汇编语言、高级语言
  4. 高级语言需要一个翻译器转换为计算机识别的机器语言

2. 计算机基础

2.1 计算机组成

计算机由硬件和软件组成

硬件分为:

  1. 输入设备:鼠标、键盘、手写板、摄像头等。
  2. 输出设备:显示器、打印机、投影仪等
  3. CPU:负责处理数据与运算
  4. 硬盘和内存:负责存储数据、硬盘永久存储数据,内存暂时存储数据

软件分为:

  1. 系统软件:Windows、Linux、macOS
  2. 应用软件:浏览器、QQ、VsCode、Sublime、Word

2.2 数据存储

  1. 计算机内部使用二进制0和1来表示数据。
  2. 所有数据,包括文件、图片等最终都是以二进制数据(0和1)的形式存放在硬盘中的。
  3. 所有程序,包括操作系统,本质都是各种数据,也以二进制数据的形式存放在硬盘中。平时我们所说的安装软件,其实就是把程序文件复制到硬盘中。
  4. 硬盘、内存都是保存的二进制数据。

2.3 数据存储单位

bit<byte<kb<GB<TB<…

  • 位(bit):1bit可以保存一个0或者1(最小的存储单位)
  • 字节(Byte):1B = 8b
  • 千字节(KB):1KB = 1024B
  • 兆字节(MB):1MB = 1024KB
  • 吉字节(GB):1GB = 1024MB
  • 太字节(TB):1TB = 1024GB

2.4 程序运行

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

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

1. 初始JavaScript

1.1 JavaScript 历史

  • 布兰登·艾奇(Brendan Eich,1961年~)。
  • 神奇的大哥在1995年利用10天完成JavaScript设计。
  • 网景公司最初命名为LiveScript,后来在与Sun合作之后将其改名为JavaScript。

1.2 JavaScript是什么

  • JavaScript是世界上最流行的语言之一,是一种运行在客户端的脚本语言(script是脚本的意思)
  • 脚本语言:不需要编译,运行过程中由js解释器(js引擎)逐行来进行解释并执行
  • 现在也可以基于Node.js技术进行服务器端编程

为了阅读方便,我们后面把JavaScript简称为JS

1.3 JavaScript的作用

  • 表单动态校验(密码强度检测)(js产生最初的目的)
  • 网页特效
  • 服务端开发(Node.js)
  • 桌面程序(Electron)
  • App(Cordova)
  • 控制硬件-物联网(Ruff)
  • 游戏开发(cocos2d-js)

1.4 HTML/CSS/JS 的关系

HTML/CSS标记语言–描述类语言

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

ECMAScript:JavaScript、JScript

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

2. DOM——文档对象模型

文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言的**标准编程接口**。

通过DOM提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)。

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

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

1.6 js初体验

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

1. 行内式js

	<input type="button" value="点我试试" onclick="alert('Hello World')"/>
  • 可以将单行或少量js代码写在HTML标签的事件属性中(以on开头的属性),如:onclick
  • 注意单双引号的使用:在HTML中我们推荐使用双引号,js中我们推荐使用单引号
  • 可读性差,在html中编写js大量代码时,不方便阅读;
  • 引号易错,引号多层嵌套匹配时,非常容易弄混;
  • 特殊情况下用

2. 内嵌js

	<script>
        alert('Hello World');
	</script>
  • 可以将多行js代码写到<script>标签中
  • 内嵌js是学习时常用的方式

3. 外部js文件

	<script src="my.js"></script>
  • 利于HTML页面代码结构化,把大段js代码独立到html页面之外,即美观,也方便文件级别的复用
  • 引用外部js文件的script标签中间不可以写代码
  • 适合于js代码量比较大的情况

2. js注释

	// 1. 单行注释 ctrl + /
	// 2. 多行注释  默认的快捷键 shift + alt + a
	// 2. 多行注释  vscode中修改多行注释的快捷键:ctrl + shift + /

3. JavaScript输入输出语句

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

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

1. 变量概述

1.1什么是变量

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

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

1.2变量在内存中的存储

本质:变量是程序在内存中申请的一块用来存放数据的空间。
类似我们酒店的房间,一个房间就可以看做是一个变量。

2.变量的使用

变量在使用时分为两步:

  1. 声明变量
  2. 赋值

2.1 声明变量

// 声明变量

	var age; // 声明一个名称为age的变量
  • **var**是JS的一个关键字,用来声明变量(variable变量的意思)。使用该关键字声明变量之后,计算机会自动为变量分配
    内存空间,不需要程序猿管
  • age是程序猿定义的变量名,我们要通过变量名来访问内存中分配的空间

2.2 赋值

	age = 10;//给age这个变量赋值为10
  • = 用来把右边的值赋给左边的变量空间中 此处代表赋值的意思
  • 变量值是程序猿保存到变量空间里的值

2.3 变量的初始化

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

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

案例:变量的使用

有个叫卡卡西的人在旅店登记的时候前台让他填一张表,这张表里的内容要存到电脑上,表中的内容有:姓名、年龄、
邮箱、家庭住址和工资,存储之后需要把这些信息显示出来,所显示的内容如下:
我叫旗木卡卡西,我住在火影村,我今年30岁了,我的邮箱是kakaxi@itcast.cn,我的工资2000

  1. 弹出一个输入框,提示用户输入姓名。
  2. 弹出一个对话框,输出用户刚才输入的名字。
  // var myname = '旗木卡卡西';
        // var address = '火影村';
        // var age = 30;
        // var email = 'kakaxi@itcast.cn';
        // var gz = 2000;
        // alert(myname);
        // alert(address);
        // alert(age);
        // alert(email);
        // alert(gz);


        // 1.用户输入姓名  存储到一个 myname的变量里面
        var myname = prompt('请输入您的名字');
        // 2.输出这个用户名
        alert(myname);

2.4 变量语法拓展

1.更新变量

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

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

2.同时声明多个变量

	// 同时声明多个变量时,只需要写一个var,多个变量名之间使用英文逗号隔开。
	var age = 10;  
	var name = 'zs',
        sex = 2;

3.声明变量的特殊情况

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

2.5 变量命名规范

  1. 由字母(A-Za-z)、数字(0-9)、下划线(_)、美元符号($)组成,如usrAge,num01,_name
  2. 严格区分大小写。var app;和 var App;是两个变量
  3. 不能以数字开头。18age是错误的
  4. 不能是关键字、保留字。例如:var for while
  5. 变量名必须有意义。MMD、BBD nl->age
  6. 遵守驼峰命名法。首字母小写,后面单词的首字母需要大写。myFirstNmae
  7. 推荐翻译网站:有道 爱词霸

案例:课堂练习

交换两个变量的值

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

 //js 是编程语言有很强的逻辑性在里面:实现这个要求的思路  先怎么做后怎么做
        //1.我们需要一个临时变量帮我们
        //2.把apple1 给我们的临时变量 temp 
        //3.把apple2 里面的苹果给apple1
        //4.把临时变量里面的值 给 apple2 
        var temp; //声明了一个临时变量为空
        var apple1 = '青苹果';
        var apple2 = '红苹果';
        temp = apple1; // 把右边给左边

2.6 小结

  • 为什么需要变量?
    • 因为我们一些数据需要保存,所以需要变量
  • 变量是什么?
    • 变量就是一个容器,用来存放数据的。方便我们以后使用里面的数据
  • 变量的本质是什么?
    • 变量是内存里的一块空间,用来存储数据
  • 变量怎么使用?
    • 我们使用变量的时候,一定要声明变量,然后赋值
  • 什么是变量的初始化?
    • 声明变量并赋值我们称之为变量的初始化
  • 变量命名规范有哪些?
    • 变量名尽量要规范,见名知意——驼峰命名法
  • 交换两个变量值的思路?
    • 学会交换2个变量

数据类型

1. 数据类型简介

1.1 为什么需要数据类型

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

简单来说,数据类型就是数据的类别型号。比如姓名“张三”,年龄18,这些数据的类型是不一样的。

1.2 变量的数据类型

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

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

在代码运行时,变量的数据类型是由js引擎**根据 = 右边变量值的数据类型来判断的**,运行完毕之后,变量就确定了数据类型。

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

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

1.3 数据类型的分类

js把数据类型分为两类:

  • 简单数据类型(Number, String, Boolean, Undefinde, Null)
  • 复杂数据类型(object)

2. 简单数据类型

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

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

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

2.2 数字型 Number

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

	var age = 21;		// 整数
	var Age = 21.3747;	// 小数
1. 数字型进制
	// 1. 八进制数字序列范围:0~7
	var num1 = 07;	// 对应十进制的7
	var num2 = 019;	//对应十进制的19
	var num3 = 08;	// 对应十进制的8
	// 2. 十六进制数字序列范围0~9以及A~F
	var num = 0xA; 

现阶段我们只需要记住,在js中八进制前面加0,十六进制前面加0x

2. 数字型范围

JavaScript中数值的最大和最小值

	alert(Number.MAX_VALUE);	// 1.7976931348623157e+308
	alert(Number.MIN_VALUE);	// 5e-324
3.数字型三个特殊值
	alert(Infinity);	// Infinity
	alert(-Infinity);	// -Infinity
	alert(NaN);			// NaN
  • Infinity,代表无穷大,大于任何数值
  • -Infinity,代表无穷小,小于任何数值
  • NaN,Not a number,代表一个非数值
4. isNaN()

用来判断一个变量是否为非数字的类型,返回true或者false

	var userAge = 21;
	var isNum = isNaN(userAge);
	console.log(isNum);		// false,21不是一个非数字
	var userName = "andy";
	console.log(isNaN(userName));	// true,"andy"是一个非数字

2.3 字符串型 String

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

	var strMsg = "我爱北京天安门~";	// 使用双引号表示字符串
	var strMsg = '我爱吃猪蹄~';		// 使用单引号表示字符串
	// 常见错误
	var strMsg3 = 我爱大肘子			// 报错,没使用引号,会被认为是js代码,但是js没有这些语法

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

1. 字符串引号嵌套

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

	var strMsg = '我是"高富帅"程序猿';	// 可以用''包含""
    var strMsg2 = "我是'高富帅'程序猿";	// 也可以用""包含''
	// 常见错误
	var badQuotes = 'What on earth?;" // 报错,不能单双引号搭配
2. 字符串转义符

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

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

转义符解释说明
\n换行符,n是 newline的意思
\ \斜杠\
\ ’’ 单引号
\ "" 双引号
\ttab 缩进
\b空格,b是blank的意思
案例:弹出网页警示框

酷热难耐,火辣的太阳底下,我挺拔的身姿,成为了最为独特的风景。

我审视四周,这里,是我的舞台,我就是天地间的王者。

这一刻,我豪气冲天,终于大喊一声:“收破烂啦~”

3. 字符串长度

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

	var strMsg = '我是帅气多金的程序猿!';
	alert(strMsg.length);  	// 显示11
4. 字符串拼接
  • 多个字符串之间可以使用 + 进行拼接,其拼接方式为**字符串 + 任何类型 = 拼接之后的新字符串**
  • 拼接前会把与字符串相加的任何类型转成字符串,再拼接成一个新的字符串
	// 1.1 字符串"相加"
    alert('hello' + 'world')  // hello world
    // 1.2 数值字符串"相加"
    alert('100' + '100'); // 100100
    // 1.3 数值字符串 + 数值
    alert('11' + 12); // 1112

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

5. 字符串拼接加强
	console.log('素晴' + 18);  // 素晴18
    console.log('素晴' + 18 + '岁'); // 素晴18岁
    var age = 18;
    console.log('素晴' + age + '岁');
  • 我们经常会将字符串和变量来拼接,因为变量可以很方便地修改里面的值
  • 变量是不能添加引号的,因为加引号的变量会变成字符串
  • 如果变量两侧都有字符串拼接,口诀“引引加加”,删掉数字,变量写加中间
案例:显示年龄

弹出一个输入框,需要用户输入年龄,之后弹出一个警示框显示“您今年xx岁啦“(xx表示刚才输入的年龄)

案例分析

这是利用js编写一个非常简单的交互效果程序。

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

  1. 你喜欢我吗? --> 这是**用户输入**
  2. 女孩想了想 --> 这是**程序内部处理**
  3. 喜欢!!! --> 这是**输出结果**

那么在程序中药如何实现呢?

  1. 弹出一个输入框(prompt),让用户输入年龄(用户输入
  2. 把用户输入的值用变量保存起来,把刚才输入的年龄与要输出的字符串拼接(程序内部处理
  3. 使用alert语句弹出警示框(输出结果

2.4 布尔型 Boolean

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

2.5 Undefined和Null

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

	var variable;
    console.log(variable);
    console.log(variable + 'pink'); // undefinedpink
    console.log(variable + 1); // NaN undefined和数字相加最后的结果是NaN

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

	// Null 空值
    var space = null;
    console.log(space + 'pink');  // nullpink
    console.log(space + 1);  // 1

3. 获取变量数据类型

3.1 获取检测变量的数据类型

type可用来获取检测变量的数据类型

3.2 字面量

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

  • 数字字面量:8,9,10
  • 字符串字面量:‘黑马程序员’,“大前端”
  • 布尔字面量:true,false

4.数据类型转换

4.1 什么是数据类型转换

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

我们通常会实现3种方式的转换:

  • 转换为字符串类型
  • 转换为数字型
  • 转换为布尔型

4.2 转换为字符串

方式说明案例
toString()转成字符串var num = 1; alert(num.toString());
String() 强制转换转成字符串var num = 1; alert(String(num))
加号拼接字符串和字符串拼接的结果都是字符串var num = 1; alert(num + ‘我是字符串’);
  • toString()和String()的使用方式不一样
  • 三种转换方式,我们更喜欢用第三张加号拼接字符串转换方式,这一种方式也称之为隐式转换。
 // 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 + '');

4.3 转换为数字型(重点)

方式说明案例
parseInt(string) 函数将string类型转成整数数值型parseInt(‘78’)
parseFloat(string) 函数将string类型转成浮点数数值型parseFloat(‘3.14’)
Number() 强制转换函数将string类型转换为数值型Number(‘12’)
js隐式转换( - * / )利用算术运算隐式转换为数值型‘12’ - 0
  • 注意parseInt和parseFloat 单词的大小写,这2个是重点
  • 隐式转换是我们在进行算术运算的时候,JS自动转换了数据类
  		// var age = prompt('请输入您的年龄');
        // 1. parseInt(变量) 可以把 字符型的转换为数字型   得到的是整数
        // console.log(age);
        console.log(parseInt(age));
        console.log(parseInt('3.14')); // 3 取整
        console.log(parseInt('3.98')); // 3 取整
        console.log(parseInt('120px')); // 120 会去掉px单位
        console.log(parseInt('ren120px')); // NaN
        // 2. parseFloat(变量) 可以把 字符型的转换为数字型   得到的是小数 浮点数
        console.log(parseFloat('3.14')); // 3.14
        console.log(parseInt('120px')); // 120 会去掉px单位
        console.log(parseInt('ren120px')); // NaN
        // 3. 利用 Number(变量)
        var str = '123';
        console.log(Number(str));
        console.log(Number('12'));
        // 4. 利用了算数运算 - * /  隐式转换
        console.log('12' - 0); // 12
        console.log('123' - '120');
        console.log('123' * 1);
案例:计算年龄

此案例要求在页面中弹出一个输入框,我们输入出生年份后,能计算出我们的年龄。

  1. 弹出一个输入框,让用户输入出生年份( 用户输入
  2. 把用户输入的值用变量保存起来,然后用今年的年份减去变量值,结果就是现在的年龄(程序内部处理
  3. 弹出警示框(alter),把计算的结果输出(输出结果
	var year = prompt('请输入您的出生年份');
    var age = 2020 - year; // year 取过来的是字符串型  但是这里用的减法  有隐式转换
    alert('您今年' + age + '岁了');

4.4 转换为布尔型

方式说明案例
Boolean()函数其他类型转换成布尔值Boolean(‘true’)
  • 代表否定的值会被转换为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('---------------------------------------------------------------');
        console.log(Boolean('小白'));
        console.log(Boolean('李柏'));
        console.log(Boolean(250));
案例:简单加法器

案例分析

  1. 先弹出一个输入框,提示用户输入第一个值 保存起来
  2. 再弹出第二个输入框,提示用户输入第二个值 保存起来
  3. 把这两个值相加,并将结果赋给新的变量(注意数据类型转换)
  4. 弹出警示框(alert),把计算的结果输入(输出结果
 // var num1 = prompt('请输入第一个值:');
        // var num2 = prompt('请输入第二个值:');
        // var num3 = prompt('请输入第三个值:');
        // var result = num1 * num2 - num3;
        // alert('结果是:' + result)

扩展阅读

1. 解释型语言和编译型语言

1. 概述

计算机不能直接理解任何机器语言以外的语言,所以必须要把程序员所写的程序语言翻译成机器语言才能执行程序。程序语言翻译成机器语言的工具,被称为翻译器。

编程语言
翻译器
机器语言(二进制)
  • 翻译器翻译的方式有两种:一个是编译,另外一个是解释。两种方式之间的区别在于翻译的时间点不同
  • 编译器是在代码执行之前进行翻译,生成中间代码文件
  • 解释器是在运行时进行及时解释,并立即执行(当编译器以解释方式运行的时候,也称之为解释器)
Java编译器(javac.exe)
运行时编译(即使编译器程序)
编译型语言Java
中间代码文件login.class
机器语言
执行
JavaScript(解释器)
解释型语言JavaScript
机器语言
执行

类似于请客吃饭:

  • 编译语言:首先把所有菜做好,才能上桌吃饭
  • 解释语言:好比吃火锅,边吃边涮,同时进行

2. 标识符、关键字、保留字

1. 标识符

标识符:就是指开发人员为变量、属性、函数、参数取得名字。

标识符不能是关键字或保留字

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.保留字

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

包括: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. 课后作业

  1. 给同桌讲讲交换两个变量的值 算法(不管他愿不愿听)
  2. 依次询问并获取用户的姓名、年龄、性别、并打印用户信息
	var name = prompt('请输入您的姓名');
    var age = prompt('请输入您的年龄');
    var gander = prompt('请输入您的性别');
    alert('您的姓名:' + name + '\n 您的年龄:' + age + '\n 您的性别:' + gander + '')

JavaScript运算符

1. 运算符

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

JavaScript中常用的运算符有:

  • 算数运算符
  • 递增和递减运算符
  • 比较运算符
  • 逻辑运算符
  • 赋值运算符

2. 算数运算符

2.1 算数运算符概述

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

2.2 浮点数的精度问题

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

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

所以:不要直接判断两个浮点数是否相等!

2.3 课堂提问

1.我们怎么判断一个数能够被整除呢?

它的余数是0就说明这个数能被整除,这就是% 取余运算符的主要用途

2.请问1 + 2 * 3结果是?

结果是7,注意算术运算符优先级的,先乘除,后加减,有小括号先算小括号里面的

2.4 表达式和返回值

表达式:是由数字、运算符、变量等以能求得数值的有意义排列方法所得的组合

简单理解:是由数字、运算符、变量等组成的式子

表达式最终都会有一个结果,返回给我们,我们称为返回值

3. 递增和递减运算符概述

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

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

1. 前置递增运算符

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

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

2. 后置递增运算符

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

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

3. 前置递增和后置递增小结

  • 前置递增和后置递增运算符可以简化代码的编写,让变量的值 + 1比以前写法更简单
  • 单独使用时,运行结果相同
  • 与其他代码联用是,执行结果会不同
  • 后置:先原值运算,后自加(先人后己)
  • 前置:先自加,后运算(先己后人)
  • 开发时,大多使用后置递增/减,并且代码独占一行,例如:num++;或者num–;

4. 比较运算符

4.1 比较运算符概述

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

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

4.2 =小结

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

5. 逻辑运算符

5.1 逻辑运算符概述

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

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

5.2 逻辑与&&

两边都是true才返回true,否则返回false

5.3 逻辑非(!)也叫作取反符,用来取一个布尔值相反的值,如true的相反值是false

	var isOK = true;
	console.log(!isOk);   // false

5.4 短路运算(逻辑中断)

1. 逻辑与

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

  • 语法:表达式1 && 表达式2
  • 如果第一个表达式的值为真,则返回表达式2
  • 如果第一个表达式的值为假,则返回表达式1
2. 逻辑或
  • 语法:表达式1 || 表达式2
  • 如果第一个表达式的值为真,则返回表达式1
  • 如果第一个表达式的值为假,则返回表达式2
	console.log(123 || 456);            // 123
    console.log( 0 || 456);             // 456  
    console.log( 123 || 456 || 789);    // 123

6. 赋值运算符

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

赋值运算符说明案例
=直接赋值var userName = ‘我是值’;
+=、-=加、减一个数后再赋值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;

7. 运算符优先级

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

练习1

	console.log( 4 >= 6 || '人' != '阿凡达' && !(12 * 2 == 144) && true);
    var num = 10;
    console.log(5 == num / 2 && (2 + 2 * num).toString() === '22');

练习2

	var a = 3 > 5 && 2 < 7 && 3 == 4;
    console.log(a);  // false

    var b = 3 <= 4 || 3 > 1 || 3 != 2;
    console.log(b); // true

    var c = 2 === '2';
    console.log(c); // false

    var d = !c || b && a;
    console.log(d);  // true

JavaScript流程控制-分支

1. 流程控制

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

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

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

NO
YES
顺序结构
顺序执行
A
B
分支结构
条件执行
判断
A
B
循环结构
循环执行
A
判断
C

2. 顺序流程控制

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

顺序结构
顺序执行
A
B

3. 分支流程控制 if语句

3.1 分支结构

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

分支结构
条件执行
判断
A
B

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

  • if语句
  • switch语句

3.2 if语句

1. 语法结构
	// 条件成立执行代码,否则什么也不做
	if (条件表达式) {
		// 条件成立执行的代码语句
    }
	// 1. if的语句结构 如果if
    if (条件表达式) {
        // 执行语句
    }
    // 2. 执行思路 如果if里面的条件表达式结果为真true则执行大括号里面的执行语句
    // 如果if条件表达式结果为假则不执行大括号里面的语句则执行if语句后面的代码

语句可以理解为一个行为,循环语句和分支语句就是典型的语句。一个程序由很多歌语句组成,一般情况下,会分割成一个一个的语句。

2. 执行流程
true
false
判断条件
执行语句
其他语句
案例:进入网吧

弹出一个输入框,要求用户输入年龄,如果年龄大于等于18岁,允许进入网吧。

案例分析
  1. 弹出prompt输入框,用户输入年龄,程序把这个值取过来保存到变量中
  2. 使用if语句来判断年龄,如果年龄大于18就执行if大括号里面的输出语句

3.3 if else语句(双分支语句)

执行流程
true
false
判断条件
执行语句1
执行语句2
其他语句
案例:判断是否为闰年

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

案例分析
  1. 算法:能被4整除不能整除100的为闰年(如2004就是闰年,1901不是闰年)或者能够被400整除的就是闰年
  2. 弹出prompt输入框,让用户输入年份,把这个值取过来保存到变量中
  3. 使用if语句来判断是否是闰年,如果是闰年,就执行if大括号里面的输出语句,否则就执行else里面的输出语句
  4. 一定要注意里面的且&&还有或者||的写法,同时注意判断整除的方法是取余为0
 // var year = prompt('请输入年份');
        // if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
        //     alert('今年是闰年');
        // } else {
        //     alert('今年是平年');
        // }
        var str = '';
        for (var i = 1; i <= 10; i++) {
            for (var j = 1; j <= i; j++) {
                str += '☆';
            }
            str += '\n';
        }
        console.log(str);
独立完成案例:判断是否中奖

接收用户输入的姓名,来判断是否中奖,如果输入的是刘德华,则提示中了5块钱,否则提示没有中奖。

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

执行流程
true
false
true
false
条件表达式1
执行语句1
其他语句
条件表达式2
执行语句2
条件表达式n
执行语句n
案例:判断成绩级别

要求:接收用户输入的分数,根据分数输出对应的等级字母A、B、C、D、E。

其中:

  1. 90分(含以上),输出:A
  2. 80分(含)~90分(不含),输出:B
  3. 70分(含)~80分(不含),输出:C
  4. 60分(含)~70分(不含),输出:D
  5. 60分(不含)以下,输出:E
案例分析
  1. 按照从大到小判断的思路
  2. 弹出prompt输入框,让用户输入分数,把这个值取过来保存到变量中
  3. 使用多分支if else if语句来分别判断输出不同的值

4. 三元表达式

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

案例:数字补0

用户输入数字,如果数字小于10,则在前面补0,比如01,09,如果数字大于10,则不需要补,比如20。

案例分析
  1. 用户输入0~59之间的一个数字
  2. 如果数字小于10,则在这个数字前面补0,(加0)否则不做操作
  3. 用一个变量接收这个返回值,输出

5. 分支流程控制 switch语句

5.1 语法结构

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

	switch (表达式) {
        case value1:
            // 表达式等于value1时要执行的代码;
            break;
        case value2:
            // 表达式等于value2时要执行的代码;
            break;
        ...$
        default:
            // 表达式不等于任何一个value时要执行的代码;
    }
案例:查询水果

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

案例分析
  1. 弹出prompt输入框,让用户输入水果名称,把这个值取过来保存到变量中。
  2. 将这个变量作为switch括号里面的表达式。
  3. case后面的值写几个不同的水果名称,注意一定要加引号,因为必须是全等匹配。
  4. 弹出不同价格即可。同样注意每个case之后加上break,以便退出switch语句。
  5. 将default设置为没有此水果。

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

  1. 一般情况下,它们两个语句可以相互替换
  2. switch…case语句通常处理case为比较确定值的情况,而if…else…语句更加灵活,常用于范围判断(大于、等于某个范围)
  3. switch语句进行条件判断后直接执行到程序的条件语句,效率更高。而if…else语句有几种条件,就得判断多少次。
  4. 当分支比较少时,if…else语句的执行效率比switch语句高。
  5. 当分支比较多时,switch语句的执行效率比较高,而且结构更清晰。

5.3 作业

  1. 判断时间段。比如用户输入12点弹出中午好;用户输入18点弹出傍晚好;用户输入23点弹出深夜好
  2. 比较两个数的最大值(用户依次输入2个值,最后弹出最大的那个值)
  3. 用户输入一个数,来判断是奇数还是偶数
  4. 根据用户输入的值(数字1到数字7),返回星期几
  5. 接收班长口袋里的钱数?若大于等于2000,请大家吃西餐。若小于2000,大于等于1500,请大家吃快餐。若小于1500,大于等于1000,请大家喝饮料。若小于1000,大于等于500,请大家吃棒棒糖。否则提醒班长下次把钱带够

循环

1. 循环

循环目的

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

1. js中的循环

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

  • for循环
  • while循环
  • do…while循环

2. for循环

2.1 断电调试:

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

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

浏览器中按f12 --> sources --> 找到需要调试的文件 --> 在程序的某一行设置断电

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

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

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

今天学的代码调试非常的简单,只要求同学们记住代码调试的这几个按钮的作用皆可,后面还会学到很多的代码调试技巧。

2.2 for循环重复相同的代码

	 var num  = prompt('请输入您要循环的次数')
    for (var i = 0; i < num; i++) {
        console.log('您好');
    }

2.3 for循环重复不相同的代码

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

2.4 for循环重复某些相同操作

for循环因为有了计数器的存在,我们还可以重复的执行某些操作,比如做一些算术运算。

课堂案例:求1-100之间所有整数的累加和
案例分析
  1. 需要循环100次,我们需要一个计数器 i
  2. 我们需要一个存储结果的变量sum,但是初始值一定是0
  3. 核心算法:1 + 2 + 3 + 4…,sum = sum + i;
	var sum = 0;  // 求和的变量
    for (var i = 1; i <= 100; i++) {
        // sum = sum + i
        sum += i;
    }
    console.log(sum);
课堂案例2:求学生成绩

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

案例分析
  1. 弹出输入框输入总的班级人数(num)
  2. 依次输入学生的成绩(保存起来score),此时我们需要用到for循环,弹出的次数跟班级总人数有关系 条件表达式 i <= num
  3. 进行业务处理:计算成绩。先求总成绩(sum),之后求平均成绩(average)
  4. 弹出结果
一行打印5个星星

☆☆☆☆☆

我们采取追加字符串的方式,这样可以打印到控制台上。

3. 双重for循环

3.1 双重for循环概述

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

3.2 打印五行五列星星

	var str = ''	
	for (var i = 1; i <= 5; i++) {  // 外层循环负责打印五行
        for (var j = 1; j <= 5; j++) {  // 里层循环负责一行打印5个星星
            str += '★'
        }
        // 如果一行打印完毕5个星星就要另起一行 加 \n
        str += '\n'
    }
    conso

核心:

  1. 内层循环负责一行打印5个星星
  2. 外层循环负责打印5行
课堂案例1:打印n行n列的星星

要求用户输入行数和列数,之后在控制台打印出用户输入行数和列数的星星。

	var rows = prompt('请您输入行数:')
    var cols = prompt('请您输入列数:')
    var str = ''
    for (var i = 1; i <= rows; i++) {  // 外层循环负责打印五行
        for (var j = 1; j <= cols; j++) {  // 里层循环负责一行打印5个星星
            str += '★'
        }
        // 如果一行打印完毕5个星星就要另起一行 加 \n
        str += '\n'
    } 
    console.log(str);
课堂案例2:打印倒三角

案例分析

  1. 一共有10行,但是每行的星星个数不一样,因此需要用到双重for循环
  2. 外层的for控制行数i,循环10次可以打印10行
  3. 内层的for控制每行的星星个数j
	var str = ''
	for (var i = 1; i <= 10; i++) { 
        for (var j = i; j <= 10; j++) {  
            str += '★'
        }
        str += '\n'
    }
    console.log(str);
课堂案例3:打印九九乘法表
案例分析
  1. 一共有9行,但是每行的个数不一样,因此需要用到双重for循环
  2. 外层的for循环控制行数i,循环9次,可以打印9行
  3. 内层的for循环控制每行公式j
  4. 核心算法:每一行公式的个数正好和行数一致,j <= i;
	var str = ''
    var result = ''
    for (var i = 1; i <= 9; i++) { 
        for (var j = 1; j <= i; j++) {
            // 1 × 1 = 1
            result = j + '×' + i + '=' + i * j
            str += result + '\t'
        }
        str += '\n'
    }

    console.log(str);
3.3 for循环小结
  • for循环可以重复执行某些相同代码
  • for循环可以重复执行些许不同的代码,因为我们有计数器
  • for循环可以重复执行某些操作,比如算术运算符加法操作
  • 随着需求增加,双重for循环可以做更多,更好看的效果
  • 双重for循环,外层循环一次,内层for循环全部执行
  • for循环是循环条件和数字直接相关的循环
  • 分析要比写代码更重要
  • 一些核心算法想不到,但是要学会,分析它执行过程
  • 举一反三,自己经常总结,做一些相似的案例

4. while循环

while语句可以在条件表达式为真的前提下,循环执行指定的一段代码,直到表达式不为真时结束循环。

while语句的语法结构如下:

	while (条件表达式) {
        // 循环体代码
    }
执行思路:
  1. 先执行条件表达式,如果结构为true,则执行循环体代码;如果为false,则退出循环,执行后面的代码
  2. 执行循环体代码
  3. 循环体代码执行完毕后,程序会继续判断执行条件表达式,如条件仍为true,则会继续执行循环体,知道循环条件为false时,整个循环过程才会结束
课堂案例1:
  1. 打印人的一生,从1岁到100岁
  2. 计算1 ~ 100之间所有整数的和
案例分析
  1. 弹出输入框,要求用户输入。
  2. 判断条件比较复杂我们使用while循环
  3. while循环语句中的条件表达式只要输入的不是我爱你,就一直循环。

5. do while循环

do… while语句其实是while语句的一个变体。该循环会先执行一次代码块,然后对条件表达式进行判断,如果条件为真,就会重复执行循环体,否则退出循环。

do…while语句的语法结构如下:

	// do while 循环 语法结构
    do {
        // 循环体
    } while(条件表达式)
执行思路:
  1. 先执行一次循环体代码
  2. 再执行条件表达式。如果结果为true,则继续执行循环体代码,如果为false,则退出循环,继续执行后面代码

注意:先执行循环体,再判断,我们会发现do…while循环语句至少会执行一次循环体代码

循环小结

  • js中循环有for、while、do while
  • 三个循环很多情况下都可以相互替代使用
  • 如果是用来计次数,跟数字相关的,三者使用基本相同,但是我们更喜欢用for
  • while和do…while可以做更复杂的判断条件,比for循环灵活一些
  • while和do…while执行顺序不一样,while先判断后执行,do…while先执行一次,再判断执行
  • while和do…while执行次数不一样,do…while至少会执行一次循环体,而while可能一次也不执行
  • 实际工作中,我们更常用for循环语句,它写法更简洁直观,所以这个要重点学习

6. continue break

6.1 continue关键字

continue 关键字用于立即跳出本次循环继续下一次循环(本次循环体中continue之后的代码就会少执行一次)

例如,吃5个包子,第三个有虫子,就扔掉第三个,继续吃第四个第五个包子,其代码实现如下:

	// continue 关键字
    for (var i = 1; i <= 5; i++) {
        if (i == 3) {
            continue // 只要遇见continue就退出本次循环,直接跳到i++
        }
        console.log('我正在吃第' + i + '个包子');
    }

6.2 break关键字

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

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

	for (var i = 1; i <= 5;i++) {
        if (i == 3) {
            break;
        }
        console.log('我正在吃第' + i + '个包子');
    }

JavaScript命名规范以及语法格式

1. 标识符命名规范

  • 变量、函数的命名必须要有意义
  • 变量的名称一般用名词
  • 函数的名称一般用动词

2. 操作符规范

	// 操作符的左右两侧各保留一个空格
	for (var i = 1; i <= 5; i++) {
		if (i == 3) {
			break; // 直接退出整个for循环,跳到整个for循环下面的语句
        }
        console.log('我正在吃第' + i + '个包子')
    }

作业

	1.1-100之间所有数的总和与平均值
    2.1-100之间所有偶数的和
    3.100以内7的倍数的总和
  	4. 使用for循环打印矩形,要求每次只能输出一个☆
    	☆☆☆☆
		☆☆☆☆
		☆☆☆☆
		☆☆☆☆
    5.使用for循环打印三角形
    	☆
		☆☆
		☆☆☆
		☆☆☆☆
		☆☆☆☆☆

数组

1. 数组的概念

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

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

问:什么是数组呢?

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

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

2. 创建数组

2.1 数组的创建方式

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

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

2.2 利用 new 创建数组

	var 数组名 = new Array();
	var arr = new Array();  // 创建一个新的空数组
  • 这种方式暂且了解,等学完对象再看
  • 注意Array(),A要大写

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

	// 1. 使用数组字面量方式创建空的数组
	var 数组名 = [];
	// 2. 使用数组字面量方式创建带初始值的数组
	var 数组名 = ['小白', '小黑', '大黄', '瑞奇'];
  • 数组的字面量是方括号[]
  • 声明数组并赋值称为数组的初始化
  • 这种字面量方式也是我们以后最多使用的方式

2.4 数组元素的类型

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

	var arrStus = ['小白', 12, true, 28.9];	

2.5 提问

  1. 数组的作用是什么?
  2. 创建数组我们有两种方式?哪一种我们最常用?
  3. 什么是数组元素?数组里面类型有限制吗?

3. 获取数组元素

3.1 数组的索引

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

​ var arr = [‘小白’, ‘小黄’, ‘大黄’, ‘瑞奇’]

​ 索引号: 0 1 2 3

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

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

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

定义一个数组,里面存放星期一、星期二….直到星期日(共七天),在控制台输出:星期日

4. 遍历数组

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

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

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

规律:

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

答案就是循环

遍历:就是把数组中的每个元素从头到尾都访问一次(类似我们每天早上学生的点名)

课堂案例1:遍历数组

请将 [‘关羽’, ‘张飞’, ‘马超’, ‘赵云’, ‘黄忠’, ‘刘备’, ‘姜维’];数组里的元素依次打印到控制台。

课堂案例2:数组求和及平均值

求数组[2, 6, 1, 7 4]里面所有元素的以及平均值

案例分析
  1. 声明一个求变量sum
  2. 遍历这个数组,把里面的每个数组元素加到sum里面
  3. 用求和变量sum除以数组的长度就可以得到数组的平均值。

课堂案例3:数组最大值

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

案例分析
  1. 声明一个保存最大元素的变量max。
  2. 默认最大值可以取数组中的第一个元素
  3. 遍历这个数组,把里面每个数组元素和max相比较。
  4. 如果这个数组元素大于max就把这个数组元素存到max里面,否则继续下一轮比较。
  5. 最后输出这个max。
课堂案例4:数组转换为分割字符串

要求将数组[‘red’, ‘green’, ‘blue’]

输出:‘red|green|blue|’

5. 数组中新增元素

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

5.1 通过修改length长度新增数组元素

  • 可以通过修改length长度来实现数组扩容的目的
  • length属性是可读写的
	var arr = ['red', 'green', 'blue', 'pink']
    arr.length = 7;
    console.log(arr);
    console.log(arr[4]);
    console.log(arr[5]);
    console.log(arr[6]);

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

5.2 通过修改数组索引号新增数组元素

  • 可以通过修改数组索引的方式追加数组元素
  • 不能直接给数组名复制,否则会覆盖以前的数据
	var arr = ['red', 'green', 'blue', 'pink']
    arr[4] = 'hotpink';
	conlose.log(arr);

这种方式也是最常用的一种方式。

案例:数组存放1~10个值
案例分析
  1. 使用循环来追加数组
  2. 声明一个空数组arr
  3. 循环中计数器i可以作为数组元素存入
  4. 由于数组的索引是从0开始的,因此计算器从0开始更合适,存入的数组元素要+1
		 var arr = [];
         for (i = 0; i < 100; i++) {
             arr[i] = i + 1;
         }
         console.log(arr);
案例:筛选数组

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

案例分析
  1. 声明一个新的数组用于存放新数据newArr
  2. 遍历原来的旧数组,找出大于等于10的元素
  3. 依次追加给新的数组newArr
		var arr = [2, 5, 7, 0, 6, 98, 0, 12, 34, 32, 0, 23, 0, 22, 21, 10, 14];
        var newArr = [];
        var j = 0;
        for (i = 0; i < arr.length; i++) {
            if (arr[i] > 10) {
                // 新数组应该从0开始依次递增
                // newArr[newArr.length] = arr[i];
                newArr[j] = arr[i];
                j++;
            }
        }
        console.log(newArr);
        for (i = 0; i < arr.length; i++) {
            if (arr[i] != 0) {
                newArr[newArr.length] = arr[i];
            }
        }
        console.log(newArr);
案例1:删除指定数组元素

要求:将数组[2, 5, 7, 0, 6, 98, 0, 12, 34, 32, 0, 23, 0, 22, 21, 10, 14]中的0去掉后,形成一不包含0的新数组。

案例分析
  1. 需要一个新数组用于存放筛选之后的数据
  2. 遍历原来的数组,把不是0的数据添加到新数组里面(此时主要采用数组名 + 索引的格式接收数据
  3. 新数组里面的个数,用length不断累加。
	var arr = [2, 5, 7, 0, 6, 98, 0, 12, 34, 32, 0, 23, 0, 22, 21, 10, 14];
    var newArr = [];
	for (i = 0; i < arr.length; i++) {
        if (arr[i] != 0) {
            newArr[newArr.length] = arr[i];
        }
    }
    console.log(newArr);
案例2:翻转数组

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

输出:[‘purple’, ‘pink’, ‘blue’, ‘green’, ‘red’]

案例分析
  1. 声明一个新数组 newArr
  2. 把旧数组索引号第四个取过来(arr.length - 1),给新数组索引号第零个元素(newArr.length)
  3. 采取递减的方式 i–
遍历数组
 var arr = [2, 81, 24, 26, 84, 687, 2548, 24, 234, 34564, 465, 46, 1, 564664, 0.1];
        var max = arr[0];
        var min = arr[0];
        for (i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            } else if (arr[i] < min) {
                min = arr[i];
            }
        }
        console.log('最大的数为:' + max);
        console.log('最小的数为:' + min);
案例:数组排序(冒泡排序)

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

案例分析
  1. 一共需要的趟数 我们用外层for循环
    1. 5个数据我们一共需要走4趟
    2. 长度就是数组长度减去1 arr.length - 1
  2. 每一趟交换次数我们用里层for循环
    1. 第一趟交换4次
    2. 第二趟交换3次
    3. 第三趟交换2次
    4. 第四趟交换1次
    5. 长度就是数组长度减去次数
    6. 但是次数是从0开始的,所以最终arr.length - i - 1
  3. 交换2个变量就好了
	var arr = [5, 4, 3, 2, 1];
        for (i = 0; i <= arr.length - 1; i++) { // 外层循环管趟数
            for (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);
简易ATM机
//         2.1 简易ATM
//  shuru = prompt("请输入操作:\n 1.存钱\n2.取钱\n3.显示余额\n4.退出");
//  qian = 100;
// while(qian>=10){
//     if(shuru == '1'){
//         var msg = prompt("请输入存钱金额");
//     msg = parseInt(msg);
//     qian = qian + msg;
//     alert('余额为'+qian);
//     shuru = prompt("请输入操作:\n 1.存钱\n2.取钱\n3.显示余额\n4.退出");
//     }
//     if(shuru == '2'){
//     var msg = prompt("请输入取钱金额");
//     msg = parseInt(msg);
//     qian = qian - msg;
//     alert('余额为'+qian);
//      shuru = prompt("请输入操作:\n 1.存钱\n2.取钱\n3.显示余额\n4.退出");
//     }
//     if(shuru == '3'){
//     alert('余额为'+qian);
//     shuru = prompt("请输入操作:\n 1.存钱\n2.取钱\n3.显示余额\n4.退出");
//     }
//     if(shuru == '4'){
//         shuru = false;
//         break;
//     }
// }

函数

1. 函数的概念

在js里面,可能会定义非常多的相同代码或者功能相似的代码,这些代码可能需要大量重复使用。

虽然for循环语句也能实现一些简单的重复操作,但是比较具有局限性,此时我们就可以使用js中的函数

// 3.函数就是封装了一段可以被重复执行调用的代码块
        function getSum(num1, num2) {
            var sum = 0;
            for (var i = num1; i <= num2; i++) {
                sum += i;
            }
            console.log(sum);
        }
        getSum(1, 100);

2. 函数的使用

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

2.1 声明函数

	// 声明函数
	function 函数名() {
		// 函数体代码
    }
  • function是声明函数的关键字,必须小写
  • 由于函数一般 是为了实现某个功能才定义的,所以通常我们将函数名命名为动词,比如getSum

2.2 调用函数

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

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

2.3 函数的封装

  • 函数的封装把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口
  • 简单理解:封装类似于将电脑配件整合组装到机箱中(类似快递打包)

2.4 提问

  1. 函数是做什么的(作用)?
  2. 声明函数用什么关键字?
  3. 如何调用函数?
  4. 封装是什么意思?
// 函数使用分为两步:    声明函数    和  调用函数
        // 1.声明函数
        // function 函数名() {
        //     // 函数体
        // }
        // function sayHi() {
        //     console.log('hi~~~');
        // }
        // (1) function 声明函数的关键字 全部小写
        // (2) 函数是做某件事情,函数名一般是动词 sayHi
        // (3) 函数不调用自己不执行
        // 2.调用函数
        // 函数名();
        // sayHi();

        function getSum() {
            var sum = 0;
            for (var i = 1; i <= 100; i++) {
                sum += i;
            }
            console.log(sum);
        }
        getSum();

3. 函数的参数

3.1 形参和实参

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

参数说明
形参形式上的参数 函数定义的时候 传递的参数 当前并不知道是什么
实参实际上的参数 函数调用的时候传递的参数 实参是传递给形参的

参数的作用:函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去。

3.2 函数形参和实参个数不匹配问题

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

3.3 小结

  • 函数可以带参数也可以不带参数
  • 声明函数的时候,函数名括号里面的是形参,形参的默认值为undefined
  • 调用函数的时候,函数名括号里面的是实参
  • 多个参数中间 用逗号分隔
  • 形参的个数可以和实参个数不匹配,但是结果不可预计,我们尽量要匹配

4. 函数返回值

4.1 return 语句

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

4.2 return 终止函数

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

	function add(num1, num2) {
        // 函数体
        return num1 + num2;  // 注意:return后的代码不执行
        alert('我不会被执行,因为前面有return')
    }
    var resNum = add(21, 6); // 调用函数,传入两个实参,并通过resNum接收函数返回值
    console.log(resNum);

4.3 return的返回值

return只能返回一个值。如果用逗号隔开多个值,以最后一个为准。

4.4 函数没有return返回undefined

函数都是有返回值的

  1. 如果有return则返回return后面的值
  2. 如果没有return则返回undefined

4.5 break,continue,return的区别

  • break:结束当前的循环体(如for、while)
  • continue:跳出本次循环,继续执行下次循环(如for、while)
  • return:不仅可以退出循环,还能够返回return语句中的值,同时还可以结束当前的函数体内的代码

5. arguments的使用

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

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

  • 具有length属性
  • 按索引方式存储数据
  • 不具有数组的push,pop等方法
 // 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() 等等
利用函数求任意个数的最大值
        // 利用函数求任意个数的最大值
        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));
利用函数翻转任意数组
 // 利用函数翻转任意数组 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, 3, 4, 6, 9]);
        console.log(arr1);
        var arr2 = reverse(['red', 'pink', 'blue']);
        console.log(arr2);
利用函数冒泡排序 sort 排序
 // 利用函数冒泡排序 sort 排序
        function sort(arr) {
            var temp = 0
            for (var i = 0; i < arr.length - 1; i++) {
                for (var j = 0; j < arr.length - i - 1; j++) {
                    if (arr[j] > arr[j + 1]) {
                        temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
            return arr;
        }
        var arr1 = sort([1, 4, 2, 9]);
        console.log(arr1);
        var arr2 = sort([11, 7, 22, 999]);
        console.log(arr2);
利用函数判断闰年
 // 利用函数判断闰年
        function isRunYear(year) {
            // 如果是闰年我们返回 true  否则 返回 false 
            var flag = false;
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                flag = true;
            }
            return flag;
        }
        console.log(isRunYear(2000));
        console.log(isRunYear(1999));

6. 函数案例

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

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

	function fn1() {
        console.log(111);
        fn2()
        console.log('fn1');
    }

    function fn2() {
        console.log(222);
        console.log('fn2');
    }
    fn1();
输出当前年份2月份的天数
 // 用户输入年份,输出当前年份2月份的天数
        function backDay() {
            var year = prompt('请您输入年份:');
            if (isRunYear(year)) { // 调用函数需要加小括号
                alert('当前年份是闰年2月份有29天');
            } else {
                alert('当前年份是平年2月份有28天');
            }
        }
        backDay();


        // 判断是否为闰年的函数
        function isRunYear(year) {
            // 如果是闰年我们返回 true  否则 返回 false 
            var flag = false;
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                flag = true;
            }
            return flag;
        }
函数的2中声明方式
// 函数的2中声明方式
        // 1. 利用函数关键字自定义函数(命名函数)
        function fn() {

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

        }
        fun('pink老师');
        // (1) fun是变量名 不是函数名  
        // (2) 函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值 而 函数表达式里面存的是函数
        // (3) 函数表达式也可以进行传递参数

JavaScript作用域

1. 作用域

1.1 作用域概述

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

 // 1.JavaScript作用域 : 就是代码名字(变量)在某个范围内起作用和效果 目的是为了提高程序的可靠性更重要的是减少命名冲突
        // 2. js的作用域(es6)之前 : 全局作用域   局部作用域 
        // 3. 全局作用域: 整个script标签 或者是一个单独的js文件
        var num = 10;
        var num = 30;
        console.log(num);

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

        }
        fn();

2. 变量的作用域

2.1 变量作用域的分类

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

  • 全局变量
  • 局部变量

2.2 全局变量

  • 在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)
  • 在全局作用域下var声明的变量是全局变量
  • 特殊情况下,在函数内不使用var声明的变量也是全局变量(不建议使用)

2.3 局部变量

  • 在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)
  • 在函数内部var声明的变量是局部变量
  • 函数的形参实际上就是局部变量

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

  • 全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
  • 局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间

变量的作用域

  // 变量的作用域: 根据作用域的不同我们变量分为全局变量和局部变量
        // 1. 全局变量: 在全局作用域下的变量 在全局下都可以使用
        // 注意 如果在函数内部 没有声明直接赋值的变量也属于全局变量
        var num = 10; // num就是一个全局变量
        console.log(num);

        function fn() {
            console.log(num);

        }
        fn();
        // console.log(aru);

        // 2. 局部变量   在局部作用域下的变量   后者在函数内部的变量就是 局部变量
        // 注意: 函数的形参也可以看做是局部变量
        function fun(aru) {
            var num1 = 10; // num1就是局部变量 只能在函数内部使用
            num2 = 20;
        }
        fun();
        // console.log(num1);
        // console.log(num2);
        // 3. 从执行效率来看全局变量和局部变量
        // (1) 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
        // (2) 局部变量 当我们程序执行完毕就会销毁, 比较节约内存资源

js中没有块级作用域

 // js中没有块级作用域  js的作用域: 全局作用域  局部作用域  现阶段我们js 没有 块级作用域
        // 我们js 也是在 es6 的时候新增的块级作用域
        // 块级作用域 {}   if {}  for {}
        // java 
        // if(xx) {
        //     int num = 10;
        // }
        // 外面的是不能调用num的
        if (3 < 5) {
            var num = 10;
        }
        console.log(num);

3. 作用域链

  • 只要是代码,就至少有一个作用域
  • 写在函数内部的局部作用域
  • 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
  • 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链

作用域链

// 作用域链  : 内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 这种结构我们称为作用域链   就近原则
        var num = 10;

        function fn() { // 外部函数
            var num = 20;

            function fun() { // 内部函数
                console.log(num);

            }
            fun();
        }
        fn();
作用域链案例
案例1分析
0级链
1级链
2级链
全局作用域
f1
num=456
num=123
f2
console.log(num);
 // 案例1 : 结果是几?
        function f1() {
            var num = 123;

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

        // 案例2 :结果是几?
        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();

预解析

1. 预解析

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

 		// 1问  
        console.log(num);



        // 2问
        console.log(num); // undefined  坑 1
        var num = 10;
        // 相当于执行了以下代码
        // var num;
        // console.log(num);
        // num = 10;



        // 3问  
        function fn() {
            console.log(11);
        }
        fn();




        // 4问
        fun(); // 报错  坑2 
        var fun = function() {
                console.log(22);

            }
            // 函数表达式 调用必须写在函数表达式的下面
            // 相当于执行了以下代码
            // var fun;
            // fun();
            // fun = function() {
            //         console.log(22);

        //     }

        // 1. 我们js引擎运行js 分为两步:  预解析  代码执行
        // (1). 预解析 js引擎会把js 里面所有的 var  还有 function 提升到当前作用域的最前面
        // (2). 代码执行  按照代码书写的顺序从上往下执行
        // 2. 预解析分为 变量预解析(变量提升) 和 函数预解析(函数提升)
        // (1) 变量提升 就是把所有的变量声明提升到当前的作用域最前面  不提升赋值操作
        // (2) 函数提升 就是把所有的函数声明提升到当前作用域的最前面  不调用函数
预解析案例
 // 预解析案例
        // 案例1
        // var num = 10;
        // fun();

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

        // // function fun() {
        // //     var num;
        // //     console.log(num);
        // //     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);
        // //     num = 20;
        // //     console.log(num);
        // // }
        // // num = 10;
        // // fn();
        // // 案例3
        // var a = 18;
        // f1();

        // function f1() {
        //     var b = 9;
        //     console.log(a);
        //     console.log(b);
        //     var a = '123';
        // }
        // 相当于以下代码
        // var a;

        // function f1() {
        //     var b;
        //     var a;
        //     b = 9;
        //     console.log(a);
        //     console.log(b);
        //     a = '123';
        // }
        // a = 18;
        // f1();
        // 案例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;
        //     a = b = c = 9;
        //     // 相当于 var  a  = 9; b = 9; c = 9; b 和 c 直接赋值 没有var 声明 当 全局变量看
        //     // 集体声明  var a = 9, b = 9, c = 9;
        //     console.log(a);
        //     console.log(b);
        //     console.log(c);
        // }
        // f1();
        // console.log(c);
        // console.log(b);
        // console.log(a);

对象导读

1. 对象

1.1 什么是对象

现实生活中:万物皆对象,对象是一个具体的事物,看得见摸的着的实物。例如,一本书,一辆汽车,一个人可以是"对象",一个数据库,一张网页、一个与远程服务器的连接也可以是"对象"。

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

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

  • 属性:事物的**特征,在对象中用属性**来表示(常用名词)
  • 方法:事物的**行为,在对象中用方法**来表示(常用动词)

1.2 什么是对象

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

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

	var arr = ['张三疯','男',128,154];

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

	张三疯.姓名 = '张三疯';		   person.name = '张三疯';
	
	张三疯.性别 = '男';           person.sex = '男';

	张三疯.年龄 = 128;		     person.age = 128;
	
	张三疯.身高 = 154;		     person.height = 154;

2.创建对象的三种方式

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

  • 利用字面量创建对象
  • 利用new Object创建对象
  • 利用构造函数创建对象

2.1 利用字面量创建对象

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

{}里面采取**键值对**的形式表示

  • 键:相当于属性名
  • 值:相当于属性值,可以是任意类型的值(数组类型、字符串类型、布尔类型,函数类型等)
对象的调用
  • 对象里面的属性调用:对象.属性名,这个小点.就理解为“
  • 对象里面属性的另一种调用方式:对象['属性名'],注意方括号里面的属性**必须加引号**,我们后面会用
  • 对象里面的方法调用:对象.方法名(),注意这个方法名字后面**一定加括号**
 // 利用对象字面量创建对象 {}
        // var obj = {};  // 创建了一个空的对象
        var obj = {
            uname: '张三疯',
            age: 18,
            sex: '男',
            sayHi: function() {
                console.log('hi~');
            }
        }
        // (1) 里面的属性或者方法我们采取键值对的形式  键 属性名: 值  属性值
        // (2) 多个属性或者方法用逗号隔开的
        // (3) 方法冒号后面跟的是一个匿名函数
        // 2. 使用对象
        // (1) 调用对象的属性  我们采取  对象名.属性名  . 我们理解为  的
        console.log(obj.uname);
        // (2) 调用属性还有一种方法  对象名['属性名']
        console.log(obj['age']);
        // (3) 调用对象的方法  sayHi  对象名.方法名()  千万别忘记添加小括号
        obj.sayHi();
练习:请按照要求写出对象

请用对象字面量的形式创建一个名字为可可的狗对象。

具体信息如下:

  • 姓名:可可
  • 类型(type):阿拉斯加犬
  • 年龄:5岁
  • 颜色:棕红色
  • 技能:汪汪汪(bark),演电影(showFilm)
变量、属性、函数、方法总结
  • 变量:单独声明赋值,单独存在
  • 属性:对象里面的变量成为属性,不需要声明,用来描述该对象的特征
  • 函数:单独存在的,通过“函数名()”的方式就可以调用
  • 方法:对象里面的函数成为方法,方法不需要声明,使用“对象.方法名()”就可以调用,方法用来描述该对象的行为和功能。

2.2 利用new Object创建对象

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

 // 利用 new Object 创建对象
        var obj = new Object();  // 创建了一个空的对象
        obj.uname = '张三疯';
        obj.age = 18;
        obj.sex = '男';
        obj.sayHi = function() {
            console.log('hi~');
        }
        // (1) 我们是利用 等号 = 赋值的方法 添加对象的属性和方法
        // (2) 每个属性和方法之间用分号结束
        console.log(obj.uname);
        console.log(obj['sex']);
        obj.sayHi();
练习:请按照要求写出对象

请用newObject形式创建一个鸣人对象。

具体信息如下:

  • 姓名:鸣人

  • 性别:男

  • 年龄:19岁

  • 技能(skill):影分身术

var obj = new Object();
        obj.uname = '鸣人';
        obj.sex = '男';
        obj.age = 18;
        obj.skill = function() {
            console.log('影分身术');
        }

2.3 利用构造函数创建对象

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

		// 因为我们一次创建一个对象,里面很多的属性和方法是大量相同的,我们只能复制
		// 因此我们可以利用函数的方法重复这些相同的代码,我们就把这个函数成为构造函数
		// 又因为这个函数不一样,里面封装的不是普通代码,而是对象
		// 构造函数就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面



		// 利用构造函数创建对象
        // 我们需要创建四大天王的对象  相同的属性: 名字  年龄  性别    相同的方法:唱歌
        // 构造函数的语法格式
        // function 构造函数名() {
        //     this.属性 = 值;
        //     this.方法 = function() {}
        // }
        // new 构造函数名();
        function Star(uname, age, sex) {
            this.name = uname;
            this.age = age;
            this.sex = sex;
            this.sing = function(song) {
                console.log(song);
            }
        }
        var ldh = new Star('刘德华',18,'男');  // 调用函数返回的是一个对象
        console.log(typeof ldh);
        console.log(ldh.name);
        console.log(ldh['age']);
        ldh.sing('冰雨');
        var zxy = new Star('张学友',19,'男');
        console.log(zxy.name);
        console.log(zxy.age);
        zxy.sing('李兰香');


        // 1. 构造函数名字首字母要大写
        // 2. 我们构造函数不需要return 就可以返回结果
        // 3. 我们调用构造函数必须使用 new
        // 4. 我们只要new Star() 调用函数就创建了一个对象 ldh {}
        // 5. 我们的属性和方法前面必须添加this 

2.4 构造函数和对象

  • 构造函数,如Stars(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class)
  • 创建对象,如new stars(),特指某一个,通过new关键字创建对象的过程我们也称为对象实例化
// 1. 构造函数  明星 泛指的某一大类     它类似于 Java里的 类(class)
        function Star(uname,age,sex) {
            this.name = uname;
            this.age = age;
            this.sex = sex;
            this.sing = function(song) {
                console.log(song);
            }
        }
        // 2. 对象  是一个具体的事物  刘德华 == {name: "刘德华", age: 18, sex: "男", sing: ƒ}
        var ldh = new Star('刘德华',18,'男');  // 调用函数返回的是一个对象
        console.log(ldh);
        // 3. 我们利用构造函数创建对象的过程我们也称为对象的实例化

3.new关键字

new在执行时会做四件事情:
  1. 在内存中创建一个新的空对象。
  2. 让this指向这个新的对象。
  3. 执行构造函数里面的代码,给这个新对象添加属性和方法。
  4. 返回这个新对象(所以构造函数里面不需要return)。
New和构造函数确认了眼神
  1. 他们俩生了一个宝宝
  2. 这个宝宝必须是亲生的this指向
  3. 教孩子读书一肚子墨水
  4. 长大挣钱回报父母

4.遍历对象属性

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

  var obj = {
            name: 'pink老师',
            age: 18,
            sex: '男',
            fn: function() {}
        }
        // console.log(name);
        // console.log(age);
        // console.log(sex);
        // for in 遍历对象
        // for (变量 in 对象) {

        // }
        for (var k in obj) {
            console.log(k);     // k 变量 输出  得到的是  属性名
            console.log(obj[k]); // obj[k] 得到是  属性值
        }
        // 我们使用 for in 里面的变量 我们喜欢写 k 或者 key 

小结

  1. 对象可以让代码结构更清晰
  2. 对象复杂数据类型object
  3. 本质:对象就是一组无序的相关属性和方法的集合
  4. 构造函数泛指某一大类,比如这个苹果,不管是红苹果还是绿苹果,都统称为苹果
  5. 对象实例特指一个事物,比如这个苹果、正在给你们讲课的pink老师等

作业

  1. 创建一个电脑对象,该对象要有颜色、重量、品牌、型号,可以看电影、听音乐、打游戏和敲代码
  2. 创建一个按钮对象,该对象中需要包含宽,高,背景颜色和点击行为
  3. 创建一个车的对象,该对象要有重量、颜色、牌子,可以载人、拉货和耕田

内置对象导读

1. 内置对象

  • JavaScript 中的对象分为3种:自定义对象、内置对象、浏览器对象
  • 前面两种对象是JS基础内容,属于ECMAScript;第三个浏览器对象属于我们JS独有的,我们JS API讲解
  • **内置对象**就是JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)
  • JavaScript提供了多个内置对象:Math、Date、Array、String等

2.查文档

2.1 MDN

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

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

MDN:https://developer.mozilla.org/zh-CN/

2.2 如何学习对象中的方法

  1. 查阅该方法的功能
  2. 查看里面参数的意义和类型
  3. 查看返回值的意义和类型
  4. 通过demo进行测试

3.Math对象

案例:封装自己的数学对象

利用对象封装自己的数学对象 里面有PI最大值和最小值

 //  利用对象封装自己的数学对象  里面有 PI 最大值和最小值
        var myMath = {
            PI: 3.141592653,
            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 = function() {
                    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));

3.1 Math概述

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

Math.PI					// 圆周率
Math.floor()			// 向下取整
Math.ceil()				// 向上取整
Math.round()			// 四舍五入版 就近取整
Math.abs()				// 绝对值
Math.max()/Math.min()	// 求最大和最小值
// 1. 绝对值方法
        console.log(Math.abs(1)); // 1
        console.log(Math.abs(-1)); // 1
        console.log(Math.abs('-1')); // 隐式转换 会把字符串型 -1 转换为数字型
        console.log(Math.abs('pink'));  // NaN
        // 2. 三个取整方法
        // (1) Math.floor()  地板  向下取整  往最小了取值
        console.log(Math.floor(1.1));  // 1
        console.log(Math.floor(1.9));  // 1
        // (2) Math.ceil()  ceil 天花板 向上取整  往最大了取值
        console.log(Math.ceil(1.1));  // 2
        console.log(Math.ceil(1.9));  // 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

3.2 Math对象random()

// 1. Math对象随机数方法   random() 返回一个随机的小数  0 <= x < 1  [0,1)
        // 2. 这个方法里面不跟参数
        // 3. 代码验证
        // console.log(Math.random());
        // 4. 我们想要得到两个整数之间的随机整数  并且包含这两个整数
        // Math.floor(Math.random() * (max - min + 1)) + min;
        function getRandom(max,min) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }
        // 5. 随机点名  
        var arr = ['张三','张三丰','张三疯子','李四','李思思','奶茶','柔柔'];
        // console.log(arr[0]);
        console.log(arr[getRandom(0,arr.length - 1)]);
案例:猜数字游戏

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

  1. 如果大于该数字,就提示,数字大了,继续猜;
  2. 如果小于该数字,就提示数字小了,继续猜;
  3. 如果等于该数字,就提示猜对了,结束程序。
案例分析
  1. 随机生成一个1~10的整数 我们需要用到Math.random()方法。
  2. 需要一直猜到正确为止,所以一直循环。
  3. 用while循环合适更简单。
  4. 核心算法:使用if else if 多分支语句来判断大于、小于、等于。
  // 猜数字游戏
        function getRandom(max, min) {
            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;  // 退出整个循环结束程序
            }
        }

4.日期对象

4.1 Date概述

  • Date对象和Math对象不一样,它是一个构造函数,所以我们需要实例化后才能使用
  • Date实例用来处理日期和时间

4.2 Date()方法的使用

  1. 获取当前时间必须实例化
var now = new Date();
console.log(now);
2.Date()构造函数的参数

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

		// Date() 日期对象 是一个构造函数 必须使用new 来调用创建我们的日期对象
        var arr = new Array();  // 创建一个数组对象
        var obj = new Object();  // 又创建了一个对象实例   
        // 1. 使用Date  如果没有参数 返回当前系统的当前时间
        var date  = new Date();
        console.log(date);
        // 2. 参数常用写法  数字型  2020, 11, 28 或者是字符串型  '2020-11-28 15:00:00'
        var date1 = new Date(2020,11,28);
        console.log(date1);
        var date2 = new Date('2020-10-02 15:00:00');
        console.log(date2);

4.3 日期格式化

我们想要2020-11-28 8:8:8格式的日期,要怎么办呢?

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

方法名说明代码
getFullYear()获取当年dObj.getFullYear()
getMonth()获取当月(0-11)dObj.getMonth()
getDate()获取当天日期dObj.getDate()
getDay()获取星期几(周日0到周六6)dObj.getDay()
getHours()获取当前小时dObj.getHours()
getMinutes()获取当前分钟dObj.getMinutes()
getSeconds()获取当前秒数dObj.getSeconds()
 // 格式化日期 时分秒
        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());

4.4 获取日期的总的毫秒形式

Date对象是基于1970年1月1日(世界标准时间)起的毫秒数

为什么计算机起始时间从1970年开始?

我们经常利用总的毫秒数来计算时间,因为它更精确

		// 获取Date总的毫秒数(时间戳)  不是当前时间的毫秒数 而是距离1970年1月1日过了多少毫秒         
        // 1. 通过 valueOf() getTime()
        var date = new Date();
        console.log(date.getTime());  // 现在的时间距离 1970.1.1 总的毫秒数
        console.log(date.valueOf());
        // 2. 简单的写法 (最常用的写法)
        var date1 = +new Date();
        console.log(date1);
        // 3. H5新增的 获取总的毫秒数
        console.log(Date.now());
        date3 = Date.now();
        console.log(date3);
案例:倒计时效果

做一个倒计时效果

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

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

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

    转换为公式如下:

    • d = parseInt(总秒数 / 60 / 60 / 24); // 计算天数
    • h = parseInt(总秒数 / 60 / 60 % 24) // 计算小时
    • m = parseInt(总秒数 / 60 % 60); // 计算分数
    • s = parseInt(总秒数 % 60); // 计算当前秒数
unction countDown(time) {
            var nowTime = +new Date();  // 返回的是当前时间总的毫秒数
            var inputTime = +new Date(time);    // 返回的是用户输入的时间总的毫秒数
            var times = (inputTime - nowTime) / 1000;   // times是剩余时间总的秒数
            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('2020-12-19 8:00:00'));

5.数组对象

5.1 数组对象的创建

  • 字面量方式
  • 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);

5.2 检测是否为数组

 // 翻转数组
        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));
        // 检测是否为数组
        // (1) instanceof  运算符 它可以用来检测是否为数组
        var arr = [];
        var obj = {};
        console.log(arr instanceof Array);
        console.log(obj instanceof Array);
        // (2) Array.isArray(参数);     H5新增的方法  ie9以上的版本支持
        console.log(Array.isArray(arr));
        console.log(Array.isArray(obj));

5.3 添加删除数组元素的方法

方法名说明返回值
push(参数1…)末尾添加一个或多个元素,注意修改原数组并返回新的长度
pop()删除数组最后一个元素,把数组长度减1 无参数、修改原数组返回它删除的元素的值
unshift(参数1…)向数组的开头添加一个或更多元素,注意修改原数组并返回新的长度
shift()删除数组的第一个元素,数组长度减1 无参数、修改原数组并返回第一个元素的值
 // 添加删除数组元素方法
        // 1. push() 在我们数组的末尾 添加一个或者多个数组元素 push 推
        var arr = [1, 2, 3];
        console.log(arr.push(4, 'pink'));
        // (1) push 是可以给数组追加新的元素
        // (2) push() 参数直接写 数组元素就可以了
        // (3) push完之后 返回的是新数组的长度
        // (4) 原数组也会发生变化
        // 2. unshift() 在我们数组的开头 添加一个或者多个数组元素
        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) 原数组也会发生变化
案例:筛选数组

有一个包含工资的数组[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]);
            }
        }

5.4 数组排序

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

        // 数组排序 (冒泡排序)
        var arr1 = [1,3,4,7,1,66,55,11];
        arr.sort(function(a, b) {
            // return a - b;  升序的顺序排列
            return b - a;  // 降序的顺序排列 
        });
        console.log(arr1);

5.5 数组索引方法

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

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

案例分析
  1. 目标:把旧数组里面不重复的元素选取出来放到新数组中,重复的元素只保留一个,放到新数组中
  2. 核心算法:我们遍历旧数组,然后拿着旧数组元素去查询新数组,如果该元素没有在新数组里出现过,我们就添加,否则就不添加
  3. 我们怎么知道该元素有没有存在?利用 新数组.indexOf(数组元素) 如果返回是 -1 就说明新数组里面没有该元素

旧数组 [‘c’, ‘a’, ‘z’, ‘a’, ‘x’, ‘a’, ‘x’, ‘c’, ‘b’]

新数组 [ ]

        // 有一个数组['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'],要求取出数组中重复的元素
        // 1. 目标:把旧数组里面不重复的元素选取出来放到新数组中,重复的元素只保留一个,放到新数组中
        // 2. 核心算法:我们遍历旧数组,然后拿着旧数组元素去查询新数组,如果该元素没有在新数组里出现过,我们就添加,否则就不添加
        // 3. 我们怎么知道该元素有没有存在?利用 新数组.indexOf(数组元素) 如果返回是 - 1 就说明新数组里面没有该元素
        // 封装一个去重的函数 unique
        function unique(arr) {
            var newArr = [];
            for (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(demo);

5.6 数组转换为字符串

方法名说明返回值
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

5.7 课下查询

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

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

6.字符串对象

6.1 基本包装类型

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

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

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

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

		// (1) 把简单数据类型包装为复杂数据类型
        var temp = new String('andy');
        // (2) 把临时变量的值 赋给 str
        str = temp;
        // (3) 销毁这个临时变量
        temp = null;

6.2 字符串的不可变

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

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

6.3 根据字符串返回位置

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

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

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

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

6.4 根据位置返回字符(重点)

方法名说明使用
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(3));
        // 遍历所有的字符
        for(var i = 0; i < str.length; i++) {
            console.log(str.charAt(i));
        }
        //  2. charCodeAt(index)  返回相应索引号的字符ASCII值 目的: 判断用户按下了哪个键
        console.log(str.charCodeAt(0));
        // 3. str[index] H5  新增的
        console.log(str[0]);
案例:返回字符位置

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

案例:核心算法
  1. 核心算法:利用charAt() 遍历这个字符串
  2. 把每个字符都存储给对象,如果对象没有该属性,就为1,如果存在了就+1
  3. 遍历对象,得到最大值和该字符
// 有一个对象   来判断是否有该属性 对象{'属性名'}
        var o = {
            age: 18
        }
        if (o['age']) {
            console.log('里面有该属性');
        } else {
            console.log('没有该属性');
        }

        // 1. 核心算法:利用charAt() 遍历这个字符串
        // 2. 把每个字符都存储给对象,如果对象没有该属性,就为1,如果存在了就 + 1
        // 3. 遍历对象,得到最大值和该字符

        var str = 'abcoefoxyozzopp';
        var obj = {};
        for (var i = 0; i < str.length; i++) {
            var chars = str.charAt(i);  // chars 是字符串的每一个字符
            if (obj[chars]) { // obj[chars] 得到的是属性值
                obj[chars]++;
            } else {
                obj[chars] = 1;
            }
        }
        console.log(obj);
        // 2. 遍历对象
        var max = 0;
        var ch = '';
        for (var k in obj) {
            // k 得到的是 属性名
            // obj[k] 得到的是属性值
            if (obj[k] > max) {
                max = obj[k];
                ch = k;
            }
        }
        console.log('出现最多的字符是:' + ch);
        console.log('出现的次数为:' + max);

6.5 字符串操作方法(重点)

方法名说明
concat(str1,str2,str3…)concat()方法用于连接两个或多个字符串。拼接字符串,等效于+,+更常用
substr(start,length)从start位置开始(索引号),length 取的个数 重点记住这个
slice(start,end)从start位置开始,截取到end位置,end取不到(他们两都是索引号)
substring(start,end)从start位置开始,截取到end位置,end取不到 基本和slice相同 但是不接受负值
 // 1. 替换字符串 replace('被替换的字符', '替换为的字符')
        var str = 'andy';
        // 有一个字符串  'abcoefoxyozzopp'  要求把所有的 o 替换为 * 
        var str1 = 'abcoefoxyozzopp';
        while (str1.indexOf('o') !== -1) {
            str1 = str1.replace('o','*');
        }   
        console.log(str1);

        console.log(str.replace('a', 'b'));
        // 2. 字符转换为数组 split('分隔符')
        var str2 = 'red, pink, blue';
        console.log(str2.split(','));
        var str3 = 'red&pink&blue';
        console.log(str3.split('&'));

6.6 课下查询

  • toUpperCase() // 转换大写

  • toLowerCase() // 转换小写

作业

给定一个字符串,如:“abaasfffggghhjjkkgfddsssss3444343”,问题如下:

  1. 字符串的长度
  2. 取出指定位置的字符,如:0,3,5,9等
  3. 查找指定字符是否在以上字符串中存在,如:i, c, b等
  4. 替换指定的字符,如:g替换为22,ss替换为b等操作方法
  5. 截取指定开始位置到结束位置的字符串,如:取得1-5的字符串
  6. 找出以上字符串中出现次数最多的字符和出现的次数

JavaScript简单类型与复杂类型

1.简单类型和复杂类型

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

  • 值类型: 简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型

string,number,boolean,undefined,null

  • 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用), 因此叫做引用数据类型

通过new关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等

2.堆和栈

堆栈空间分配区别:

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

简单数据类型存放到栈里面

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

复杂数据类型存放到堆里面

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

3.简单数据类型的内存分配

  • 值类型(简单数据类型):string,number,Boolean,undefined,null
  • 值类型变量的数据直接存放在变量(栈空间)中

4.复杂类型的内存分配

  • 引用类型(复杂数据类型):通过new关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等
  • 引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中

5.简单类型传参

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

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

6.复杂类型传参

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

  	
        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. 这个输出什么?  张学友
p
0xaaabbb
new Person('刘德华')
name = '张学友'
x
0xaaabbb
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值