提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
本文精细讲解JavaScript的基础语法,可以说是js初学者的学习笔记,较为基础,还融合了一些js的基础博客做出的学习笔记,整体全面且高效,需要注意的是,本文很基础,前面多为ES5的语法,ES6会在后面补充。本文会持续更新,直到完成JavaScript基础的学习。后续如果大家需要DOM,BOM,JQuary,ES6,7以及React,Node.js,小程序开发的博客的话,我也会更新滴
提示:以下是本篇文章正文内容,下面案例可供参考
一、JavaScript导读
1.1 什么是JavaScript(这里借鉴Js红宝书的内容,看一看就可以了)
1995年,JavaScript问世。当时,它的主要用途是代替Perl等服务器端语
言处理输入验证。在此之前,要验证某个必填字段是否已填写,或者某
个输入的值是否有效,需要与服务器的一次往返通信。网景公司希望通
过在其Navigator浏览器中加入JavaScript来改变这个局面。在那个普遍通
过电话拨号上网的年代,由客户端处理某些基本的验证是让人兴奋的新
功能。缓慢的网速让页面每次刷新都考验着人们的耐心。
从那时起,JavaScript逐渐成为市面上所有主流浏览器的标配。如今,
JavaScript的应用也不再局限于数据验证,而是渗透到浏览器窗口及其内
容的方方面面。JavaScript已被公认为主流的编程语言,能够实现复杂的
计算与交互,包括闭包、匿名(lambda)函数,甚至元编程等特性。不
仅是桌面浏览器,手机浏览器和屏幕阅读器也支持JavaScript,其重要性
可见一斑。就连拥有自家客户端脚本语言VBScript的微软公司,也在其
Internet Explorer(以下简称IE)浏览器最初的版本中包含了自己的
JavaScript实现。
从简单的输入验证脚本到强大的编程语言,JavaScript的崛起没有任何人
预测到。它很简单,学会用只要几分钟;它又很复杂,掌握它要很多
年。要真正学好用好JavaScript,理解其本质、历史及局限性是非常重要
的。
需要注意的是,JavaScript和Java没有任何关系,JavaScript只是为了蹭Java的热度起的名字,当然它之所以能蹭,是因为Java就是sun公司的呗
1.2 JavaScript的起源(即历史)
随着Web日益流行,对客户端脚本语言的需求也越来越强烈。当时,大
多数用户使用28.8kbit/s的调制解调器上网,但网页变得越来越大、越来
越复杂。为验证简单的表单而需要大量与服务器的往返通信成为用户的
痛点。想象一下,你填写完表单,单击“提交”按钮,等30秒处理,然后
看到一条消息,告诉你有一个必填字段没填。网景在当时是引领技术革
新的公司,它将开发一个客户端脚本语言来处理这种简单的数据验证提
上了日程。
1995年,网景公司一位名叫Brendan Eich的工程师,开始为即将发布的
Netscape Navigator 2开发一个叫Mocha(后来改名为LiveScript)的脚本
语言。当时的计划是在客户端和服务器端都使用它,它在服务器端叫
LiveWire。
为了赶上发布时间,网景与Sun公司结为开发联盟,共同完成LiveScript
的开发。就在Netscape Navigator 2正式发布前,网景把LiveScript改名为
JavaScript,以便搭上媒体当时热烈炒作Java的顺风车。
由于JavaScript 1.0很成功,网景又在Netscape Navigator 3中发布了1.1版
本。尚未成熟的Web的受欢迎程度创造了历史新高,而网景则稳居市场
领导者的位置。这时候,微软决定向IE投入更多资源。就在Netscape
Navigator 3发布后不久,微软发布了IE3,其中包含自己名为JScript(叫
这个名字是为了避免与网景发生许可纠纷)的JavaScript实现。1996年8
月,微软重磅进入Web浏览器领域,这是网景永远的痛,但它代表
JavaScript作为一门语言向前迈进了一大步。
微软的JavaScript实现意味着出现了两个版本的JavaScript:Netscape
Navigator中的JavaScript,以及IE中的JScript。与C语言以及很多其他编
程语言不同,JavaScript还没有规范其语法或特性的标准,两个版本并存
让这个问题更加突出了。随着业界担忧日甚,JavaScript终于踏上了标准
化的征程。
1997年,JavaScript 1.1作为提案被提交给欧洲计算机制造商协会
(Ecma)。第39技术委员会(TC39)承担了“标准化一门通用、跨平
台、厂商中立的脚本语言的语法和语义”的任务(参见TC39-ECMAScript)。TC39委员会由来自网景、Sun、微软、Borland、
Nombas和其他对这门脚本语言有兴趣的公司的工程师组成。他们花了
数月时间打造出ECMA-262,也就是ECMAScript(发音为“ek-mascript”)这个新的脚本语言标准。
1998年,国际标准化组织(ISO)和国际电工委员会(IEC)也将
ECMAScript采纳为标准(ISO/IEC-16262)。自此以后,各家浏览器均
以ECMAScript作为自己JavaScript实现的依据,虽然具体实现各有不
同。
1.3 JavaScript的组成
JavaScript目前主要由三部分组成
1.ECMAScript:也就是JavaScript的基础语法
2.DOM:全称叫做Document Object Model(页面文档模型)
可以通过DOM提供的接口对页面上的各种元素进行操作(大小,位置,颜色等),这里不去具体谈论DOM,在JavaScript基础语法学完后再去学习
3.BOM:全称Browser Object Model(浏览器对象模型)
可以与浏览器窗口进行互动的对象结构
可以操作浏览器窗口 ,例如:弹出框,控制浏览器跳转,获取分配率等,这里也是在基础学习完成后再进行BOM学习,由此可见JavaScript基础语法的重要性
1.4 JavaScript的书写方式
1.4.0 引号拓展问题
在JavaScript中括号里面的内容加引号时,可以用双引号,也可以使用单引号(当然,嵌套除外),而在HTML中括号里采用双引号,所以在JavaScript里面推荐使用单引号,以便将二者进行区分
1.4.1 行内
在HTML页面中的*</body*>标签里去写
代码如下(示例):
<input type="button" value="shaka" onclick="alert('Virgo')">
这里面的内容为HTML的内容,如果不会的话需要HTML的学习
这行代码可以在浏览器页面得到一个名为shaka的按钮,按下去会得到一个警示框,警示框输出Virgo,
alert是弹出警示框的意思,这点在1.6.1会解释
1.4.2 内嵌(也叫做标签引用)
在HTML的页面去书写script标签,然后在标签里输入内容
代码如下(示例):
<script>
alert('今天是个好日子');
</script>
弹出警示框,输出内容“今天是个好日子”
1.4.3外部(也叫做文件引用)
建立一个.js文件,在.js文件里面输入内容,这里命名为one.js
代码如下(示例):
one.js
alert('今天是个好日子');
然后在HTML界面中将其引入
代码如下(示例):
<script src="one.js">“注意这里不可以写任何代码,否则错误”</script>
这里的代码效果和1.4.2一致
1.5 JavaScript注释
所谓注释,就是解释代码内容
在js中,有两种注释方法
1.单行注释:// 快捷键为ctrl + /
代码如下(示例):
<script>
//这里是注释的内容
</script>
2.多行注释: /* */ 快捷键为shift + alt +a
代码如下(示例):
<script>
/*这里为注释内容
这里也是注释内容*/
</script>
快捷键在VSCode中是可以修改的,上面写的是默认的
1.6 JavaScript常用的输入输出语句
1.6.1 浏览器弹出警示框
浏览器弹出警示框,在上面用的就是这个,是可以直观展示给用户的
代码如下(示例):
<script>
alert('这是一个警示框');
</script>
1.6.2 控制台打印输出信息
输出在控制台上的,给我们程序员自己看的
代码如下(示例):
<script>
console.log('这是在控制台输出的');
</script>
打开浏览器后。按F12,即可打开控制台
1.6.3 浏览器页面输出
向浏览器页面中输出文本,类似于HTML
代码如下(示例):
<script>
document.write('这是在页面展示的文本');
</script>
1.6.4 输入框输入
浏览器弹出一个输入框,用户可以输入内容
代码如下(示例):
<script>
prompt('请您输入内容');
</script>
二、JavaScript基础语法(ECMAScript)
1.变量
1.1 什么是变量
本质:变量的本质是程序在内存中申请一块用来存放数据的空间
这个本质可能小白们听不太懂,用白话来说就是:我们需要存入数据,而这个数据需要一个容器来存放它,也就是说,变量就是用来存放数据的容器
1.2 变量是用来做什么的
上面说到了,变量是用来存数据的,它可以存入我们程序员写的代码内容,同时它也可以存入用户输入的内容,变量这个概念非常非常重要,以后可以说是,哪里都得用这个东西!很重要哦!
1.3 变量的写法以及初始化
变量的声明:需要一个关键字var来声明变量
代码如下(示例):
<script>
var name;//用var关键字来声明一个变量 name
</script>
变量的赋值:用等号进行赋值
代码如下(示例):
<script>
name = 'shaka';//接上面,用等号进行赋值
</script>
此时,一个变量name已经声明并且赋值完毕
我们发现这个声明和赋值可以一步完成,一步完成变量的声明和赋值,我们称其变量的初始化
代码如下(示例):
<script>
var name = 'shaka';//变量的初始化
</script>
1.4 变量的拓展
1 .更新变量,以最后一次为准
代码如下(示例):
<script>
var name = 'shaka';
var name = 'virgo';//此时我们更新了变量name
</script>
我们用控制台输出变量name验证结果
console.log(name);//注意我们输入的是变量。所以括号内不加引号
我们发现它是以最后一次输入为准
2 .声明多个变量,只需要写一个var关键字
代码如下(示例):
<script>
var name ='shaka';
age = 18;
address = '中国辽宁'
</script>
3. 特殊情况
(1)只声明,不赋值
(2)不声明,不赋值
(3)不声明,只赋值
代码如下(示例1):
<script>
var age;//只声明不赋值
console.log(age)//unfefined
</script>
代码如下(示例2):
<script>
console.log(age);//没声明,没赋值,直接使用
//会报错
</script>
代码如下(示例3):
<script>
age = 18;//没用var关键字声明
console.log(age);//输出18 可以执行,但是不提倡
</script>
1.5 变量的命名规范
(1)由字母,数字,下划线(_),美元符号($)组成
(2)不能以数字开头
(3)严格区分大小写
(4)不能是关键字,保留字 例如:var 、while、for等等(这个关键字和保留字在csdn可以查到全的,我这里就不再总结了)
(5)变量名最好有意义(能看懂),比如 name,age这种单词,或者是str等,方便观看
(6)驼峰命名法:首字母小写,后面单词首字母大写,例如:myFirstName
1.6 交换变量值(临时变量)黑马pink老师实例
一个变量apple1=’青苹果‘,一个变量apple2=‘红苹果’,要求把两个变量中的值进行互换
思路:
1.需要一个临时变量temp(暂时存放apple1里面的青苹果,一会再给apple2)
2.把apple1的值给临时变量temp
3.把apple2的值给apple1
4.把temp的值给apple2
图解如下
代码如下(示例):
<script>
var temp;//临时变量,不需要赋值
var apple1 = '青苹果';
var apple2 = '红苹果';
temp = apple1;//需要注意的是,赋值过程是把右边的值赋值给左边
apple1 = apple2;
apple2 = temp;
console.log(apple1);//青苹果
</script>
2.数据类型
2.1 为什么需要数据类型
在计算机中,不同数据所需占用的存储空间不同,便于把数据分成所需内存大小不同的数据,充分利用存储空间,所以有了数据类型。
2.2 变量的数据类型
在Java语言里我们声明一个变量时就知道了它是数据类型
代码如下(示例):
int num = 10;//显然,我们知道了这个num是int型
但是在我们JavaScript语言中,js变量的数据类型只有程序在运行过程中,根据等号右边的值才能够确定数据类型,可能这么说大家听不懂,给大家用代码演示一下
var num;//声明变量了。但是我们不确定它是哪种数据类型,因为没赋值
var num = 10;//现在我们知道了,num是数字型
Js是动态语言,所以相同的变量可用作不同的数据类型
代码如下(示例):
var x=6;//x为num型
var x = 'Bill';//x为String型
2.3 数据类型的分类
1.简单数据类型:Number,String,Boolean,Undefined,Null
2.复杂数据类型:例如Oject,这个会在后面章节讲
2.3.1 数字型Number
这个很简单,就是一个数字呗,需要注意的是Number里面包括整型(int)和浮点型(float)
但是这里有拓展
(1)数字型的范围:就是数字型的最大值和最小值,了解即可
代码如下(示例):
alert(Number.MAX_VALUE);//最大值,固定格式
alert(Number.MIN_VALUE);//最小值,固定格式
(2)数字型的三个特殊值
Infinity(无穷大)
-Infinity(无穷小)
NaN:全称Not a Number(代表一个非数值)
注意:这里可以用isNaN()这个方法来判断非数字,如果是数字返回false,反之返回true
代码如下(示例):
console.log(isNaN(12));//因为是数字,所以返回false
2.3.2 字符串型String
跟别的语言的String是一样的,简单理解为引号里就是String
1.字符串长度的检测获取用length
代码如下(示例):
var name = 'shaka';
console.log(name.length);//5
2.字符串的拼接用+号,在后面的内置对象里面我们会学别的方法,这里先用+号
代码如下(示例):
console.log('我'+18+'岁');//我18岁
String类型的练习题
要求:弹出输入框,用户输入年龄,然后警示框弹出用户年龄
分析
(1)弹出一个输入框(prompt),让用户输入年龄
(2)把用户输入的变量保存起来,把刚输入的年龄与所要输出的字符串拼接
(3)使用alert弹出警示框
代码如下(示例):
var age = prompt('请输入您的年龄');
var str = '您今年已经'+age+'岁了';
alert(str);
2.3.4 布尔型Boolean
也就是true(1)和false(0)
代码如下(示例):
var flag = true;
console.log(flag+1);//2 flag为false的话这里结果是1
2.3.5 Undefined和Null
undefined 是一个值为 undefined 的类型。
这个语言也定义了一个全局变量,它的值是 undefined,这个变量也被称为 undefined。 但是这个变量不是一个常量,也不是一个关键字。这意味着它的值可以轻易被覆盖。
这两者比较特殊在后面会详细说,这里知道有这两种数据类型即可
2.4 typeof获取数据类型
也许有人会问instanceof呢?这两者可有区别,准确知道instance of的用法需要知道后面的知识的铺垫,这里直接说大家也不会深刻了解,所以只讲判断基本数据类型的typeof
那么typeof怎么使用呢
代码如下(示例):
var num = 10;
console.log(typeof num); //number
var timer = null;
console.log(typeof timer); //object
其它的也是这么使用的
2.5 数据类型转换
大致分为三类
1.转换为字符串型
2.转换为数字型
3.转换为布尔型
2.5.1 转换成字符串型
三种方法
1.toString
代码如下(示例):
var num = 1;
alert(num.toString());//此时数字型1已经转换成字符串型
2.String()强制转换
代码如下(示例):
var num = 1;
alert(String(num));
3.加号拼接字符串(隐式转换)
代码如下(示例):
var num = 1;
alert(num+'字符串');
2.5.2 转换成数字型
1.parseInt(string)函数
代码如下(示例):
parseInt('18');//18
//需要注意的是如果是'3.14'的话,取整
parseInt('3.14');//3
2.parseFloat(string)函数
代码如下(示例):
console.log(typeof parseFloat('3.14'));//number
3.Number()强制类型转换
代码如下(示例):
console.log(typeof Number('12'));//number
4.Js隐式转换(- * /):隐式转换就是字符串通过运算符和数字型进行运算可以转换成数值型
代码如下(示例):
console.log(typeof ('12'-0));//number
2.5.3转换成布尔型
转换成布尔型需要运用布尔函数
Boolean()函数
- 代表空,否定的值会被转换成false,例如:NaN,null,undefined,空格
- 其余的值都会被转换成true
2.6 数据类型练习题
- 案例一:计算年龄
要求在页面中弹出一个输入框,我们在输入出生年份后,能计算到我们的年龄
分析:
(1)弹出一个输入框(prompt),让用户输入出生年份
(2)把用户输入的值用变量保存起来,然后用今年的年份减去变量值,结果为年龄
(3)弹出输入框(alert),输出
代码如下(示例):
var year = prompt('请您输入您的出生年份');
var age = 2022 - year;
alert('您今年已经'+age+'岁了');
- 案例二:简单加法器
要求:计算两个数的值,用户输入第一个值后,继续弹出第二个输入框输入第二个值,最后通过弹出窗口显示两次输入值相加的结果
案例分析:
(1)先弹出第一个输入框,提示用户输入第一个值,保存起来
(2)再弹出第二个输入框,提示用户输入第二个值,保存起来
(3)相加,并将结果赋值给新的变量(注意数据类型转换,因为用户在prompt中输入的内容都是字符串型)
(4)弹出警示框(alert),把计算的结果输出(输出结果)
代码如下(示例):
var num1 = prompt('请您输入第一个值');
var num2 = prompt('请您输入第二个值');
var result = parseFloat(num1) + parseFloat(num2);
alert('计算结果是:'+result);
2.7 简单类型和复杂类型(拓展)
简单类型又叫做基本数据类型或者值类型,复杂类型又叫引用类型
- 值类型:简单数据类型或基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型(String,Number,Boolean,Undefined,Null)
- 引用类型:复杂数据类型,在存储时变量存储的仅仅是地址(引用),因此叫引用数据类型,通过new关键字创建的对象(系统对象,自定义对象),例如:Object,Array,Date等
这里先当做了解即可,在后面基础学完会详细讲的
3 运算符
3.1 什么是运算符
运算符(operator):用来实现赋值,比较和执行运算功能的符号
3.2 运算符的分类
- 算数运算符
- 递增和递减运算符
- 比较运算符
- 逻辑运算符
- 赋值运算符
3.3 算数运算符
算数运算符就是我们经常用的:加(+)减(-)乘(*)除(/),以及一个很重要的取余(%)
这里需要注意,我们在进行浮点数的算数运算会出现问题,比如
代码如下(示例):
var num = 0.1+0.2;
console.log(num==0.3)//false
这里是因为浮点数的精度问题:浮点数的最高精度是17位小数
但是在进行算数运算时,其精度远不如整数
3.4 递增和递减运算符
在我们JavaScript中,++和- -,可以放前面,可以放后面,分别称为:前置递增(减),后置递增(减),但是,它们两个使用的效果是不一样的,下面,通过例子来演示两种效果
1.它们两个单独使用的话,效果是一样的
代码如下(示例):
var num = 10;
++num;//11
num++;//11
注意 :递增和递减运算符必须和变量配合使用
2.分开使用
代码如下(示例):
var num = 10;
console.log(num++ +10);//20
//先返回原值,后自加1
console.log(num);//11
代码如下(示例):
var num = 10;
console.log(++num +10);//21
//先加1,再返回值
console.log(num);//11
这里看不懂的话,自己打两遍就明白喽
3.4.0 递增和递减运算符案例
var e = 10;
var f = e++ + ++e;
console.log(f)//22
3.5 比较运算符(也叫做关系运算符)
其中==会默认转换数据类型
代码如下(示例):
console.log(18=='18');//true 只要里面只相等即可
全等:=== ,要求两侧的值还有数据类型完全一致才可以
代码如下(示例):
console.log(18==='18');//false
这里带着大家感受一下=,== 、===的区别
1.一个等号:用于赋值,把右边的值给左边
2、两个等号:用于判断,判断两边的值是否相等(有隐式转换)
3.三个等号:用于判断全等,判断两边的值和数据类型是否完全相同
3.6 逻辑运算符
逻辑运算符用来进行布尔值运算
- && :逻辑与 (and)
- || :逻辑或 (or)
- ! :逻辑非 (not)
1.逻辑与
- 语法:表达式1&&表达式2
- 如果第一个表达式为真,则返回表达式2
- 如果第二个表达式为假,则返回表达式1
代码如下(示例):
console.log(123&&456);//456
2.逻辑或
- 表达式1||表达式2
- 如果表达式1为真,则返回表达式1,如果为假,返回表达式2
代码如下(示例):
console.log(123||456);//123
代码如下(示例):
var num = 0;
console.log(123||num++);//123
console.log(num);//0
3.7 赋值运算符
- =:直接赋值 ,例如:
var num = '我是值';
- +=,-= :加减一个数后再赋值
var age = 10;
age += 5;//15
- *=,/=,%= :乘除,取模后再赋值
var age = 2;
age *= 5;//10
3.8 运算符优先级
从高到低排序
- 小括号 :()
- 一元运算符 :++,- -,!
- 算数运算符 :先* / %,后+ –
- 关系运算符 :> ,>=,<,<=
- 相等运算符 := =,!=,= = =,!==
- 逻辑运算符 :先&& 后||
- 赋值运算符 : =
- 逗号运算符 :,
3.9 什么是表达式呢
有的小伙伴可以都听过表达式,但是可能已经忘了它的基本概念,这里我带着大家复习一下
表达式 :由数字,运算符,变量等以能求得数值的有意义排列方法所得的组合
听着这个官方概念可能听不懂,简单来说 :表达式就是由数字,运算符,变量组成的式子。
这样是不是就听懂了。
3.10 返回值
表达式最终都会有一个结果返回给我们,我们称为返回值
4 JavaScript流程控制(条件语句)
4.1 什么是流程控制
流程控制的本质:在一个程序执行的过程中,各条代码的执行顺序对程序的结果是有直接影响的,很多时候我们要通过控制代码的执行顺序来实现我们要完成的功能
即 :控制我们的代码按照一定的结构顺序来执行
流程控制,也就是我们常说的 条件表达式
总的分为三种
- if表达式
- swith表达式
- 三元表达式
4.2 条件语句并不是循环
很多同学可能分不清条件语句和循环语句的区别,看到if,while,for还以为都是循环,实则不然,下面细讲条件语句了哦
4.3 if条件语句
语法结构
if(条件表达式){
//执行语句
}
if(条件表达式){
//执行语句
}else{
}
下面给大家一个经典案例来体会一下
4.3.1 if条件语句案例
要求:接受用户输入的年份,如果是闰年就弹出闰年,否则弹出平年
分析;
- 算法:能被4整除且不能整除100的为闰年,或者能够被400整除的就是闰年
- 弹出prompt输入框,让用户输入年份,把这个值取过来保存到变量中
- 使用if条件语句来判断是否是闰年,如果是则if,反之else
- 一定要注意里面的且(&&)还有或(||)的写法,同时注意判断整除的方法是取余为0
代码如下(示例):
var year = prompt('请输入年份');
if(year%4==0 && year%100!=0 || year%400==0){
alert('您输入的年份为闰年');
}else{
alert('您输入的年份为平年');
}
4.3.2 多分支语句
多分支语句就是利用多个条件来选择不同的语句来执行,得到不同结果
语法结构:
if(条件表达式1){
// 语句1
}else if(条件表达式2){
// 语句2
}
…
else{
//最后的语句
}
4.4 三元表达式
三元表达式也能做一些简单的条件选择,由三元运算符组成的式子叫三元表达式
语法结构:
条件表达式 ? 表达式1 : 表达式2
执行思路:
如果条件表达式结果为真,则返回表达式1,反之返回表达式2
var num = 10;
var result = num > 5 ? '是的' : '不是的';
console.log(result);//是的
4.4.1 三元表达式经典案例:数字补零
要求:用户输入数字,如果数字小于10,则在前面补零,比如01,09,如果大于10,则不需要补零
分析:
- 用户输入0-59中的一个
- 如果小于10,则补零
- 用一个变量接受这个返回值,输出
代码如下(示例):
var time = prompt('请输入0-59中任意一个数');
var result = time < 10 ? '0'+time : time;
alert(result);
4.5 swith条件语句
swith语句也是多分支语句,也可以实现多选一
语法结构:
swith(条件表达式){
case value1:
执行语句1;
break;
case value2;
执行语句2;
break;
…
default;
执行最后的语句;
}
语法结构swith是转换,开关的意思,case是小例子或者选项的意思
原理:利用我们的表达式的值和case后面的选项值相匹配,如果匹配上,就执行case里面的语句,如果都没匹配上,那么执行default里面的语句
var num = 3;
switch(num){
case 1:
console.log(1);
break;
case 3:
console.log(3);
break;
//输出3
}
注意:
- 开发里面,表达式我们经常写成变量
- 我们num的值和case里面的值相匹配的时候必须是全等,必须是值和数据类型一致才可以 num===3
- 如果case里面没有break,会执行下一个case
4.6 swith语句和if elseif语句的区别
- switch…case语句通常处理case为比较确定值的情况,而if…else…语句更灵活,常用于范围判断(大于,等于某个范围)
- swith语句进行条件判断后直接执行到程序的条件语句,效率更高,而if else语句有几种条件,就得判断多少次
- 当分支比较少时,if…else语句执行效率比swith语句高
5 循环(含大量案例,重点)
5.1 什么是循环
循环就是我们看到的,例如:for,while这种的就是循环
那么,循环是用来做什么的呢:在实际问题中,有许多具有规律性的重复操作, 因此在程序中要完成这类操作需要执行某些语句,即循环
5.2 JavaScript中常见三种类型循环
- for循环(最重点,最常用)
- while循环
- do…while循环
5.3 for循环
for循环主要用于把某些代码循环若干次,通常跟计数有关
语法结构:
for(初始化变量;条件表达式;操作表达式){
//循环体
}
初始化变量 :就是用var声明的一个普通变量,通常用于作为计数器使用
条件表达式 :就是用来决定循环是否执行(也就是终止条件)
操作表达式 :是每次循环最后执行的代码,经常用于我们计数器变量进行更新(递增或递减)
for(var i = 1; i<=00;i++){
console.log('你好哦');
}
我们可以让用户控制出输出的次数
var num = prompt('请输入次数');
for(var i =1 ; i<=num ; i++){
console.log('哈哈哈');
5.3.1 for循环练习
例1:我们想输出一个人1~100岁
for(var i = 1;i<=100;i++){
if(i==1){
console.log('这个人一岁啦,他出生了');
} else if (i==100){
console.log('这个人100岁了,他去世了');
} else {
console.log('这个人今年'+i+'岁了');
}
}
例2:求1~100之间所有整数的累加和
分析:
- 需要循环100次,所以需要一个计数器 i
- 需要一个存储结果的变量 sum ,但初始值为0
- 核心算法: sum=sum+i
var sum = 0;
for(var i = 1;i<=100;i++){
sum = sum + i;
}
console.log(sum);//5050
例3:求1~100所有数的平均值,需要一个sum变量和平均值average变量
var sum = 0;
var average = 0;
for(var i = 1;i<=100;i++){
sum = sum + i;
}
average = sum/100;
console.log(average);//50.5
例4:求1~100之间所有偶数和奇数的和,需要一个偶数变量even和一个奇数和变量odd
var even = 0;
var odd = 0;
for(var i = 1;i<=100;i++){
if(i%2==0){
even = even+i;
}else{
odd = odd+i;
}
}
console.log('1~100之间所有的偶数和是'+even);
console.log('1~100之间所有的奇数和是'+odd);
5.3.2 for循环经典案例
要求:用户输入班级人数,之后依次输入每个学生的成绩,最后打印出该班级总的成绩以及平均成绩
分析:
- 弹出输入框输入总的班级人数(num)
- 依次输入学生的成绩(保存起来score),此时我们需要用到for循环,弹出的次数跟班级总人数有关系,条件表达式i<=num
- 进行业务处理:计算成绩,先求总成绩(sum),之后求平均成绩(average)
- 弹出结果
var num = prompt('请输入班级的总人数:');
var sum = 0;//求和的变量
var average = 0;//求平均值的变量
for(var i =1;i<=num;i++){
var score = prompt('请您输入第'+i+'个学生的成绩');
//因为从prompt取过来的数据类型是字符串型,需要转换成数字型
sum = sum + parseFloat(score);
}
average = sum/num;
alert('班级总的成绩是'+sum);
alert('班级的平均分是'+average);
5.3.4 追加字符串
当一行打印多个字符时,我们采取追加字符串的方式,这样说不容易懂,直接看代码
我们打印出5个哈
var str = '';
for(var i = 1;i<=5;i++){
str = str + '哈'
}
console.log(str);
5.4 双重for循环
很多情况下,单层for循环并不能满足我们的需求,比如我们要打印一个5行5列的图形,打印一个倒直角三角形,此时我们可以通过循环嵌套来实现
语法结构:
for(外层的初始化变量;外层的条件表达式;外层的操作表达式){
for(里层的初始化变量;里层的条件表达式;里层的操作表达式){
//执行语句;
}
}
注意 :外层的循环循环一次,里面的循环会执行全部
例如:
for(var i =1;i<=3;i++){
console.log('这是外层循环第'+i+'次');
for(var j =1;j<=3;j++){
console.log('这是里层循环第'+j+'次');
}
}
5.4.1 双重for循环案例:打印五行五列的星星
var str ='';
for(var i = 0;i<=5;i++){//外层负责打印5行
for(var j = 0;j<=5;j++){//里层负责一行打印五个★
str = str + '★'
}
str = str +'\n';//每行打印五个★后需要换行
}
console.log(str);
5.4.2 双重for循环案例:打印倒三角形
分析
- 一共10行,每行★的个数不一样,因此用双重for循环
- 外层控制行数
- 里层:j=i;j<=10;j++
var str = '';
for(var i =1;i<=10;i++){
for(var j = i;j<=10;j++){
str = str + '★'
}
str += '\n'
}
console.log(str);
5.4.3 双重for循环案例:打印九九乘法表(重点!!!)
分析:
- 一共有9行,但是每行个数不一样,因此需要双重for循环
- 外层的for循环控制行数i,循环9次,可以打印9行
- 内层的for控制每行公式j
- 核心算法:每一行公式的个数正好和行数一致,j<=i
- 每行打印完毕,都需要重新换一行
var str = '';
for(var i = 1;i<=9;i++){//外层循环控制行数
for(var j = 1;j<=i;j++){//里层循环控制每一行的个数 j<=i
str += j +'×' + i + '=' + i*j + '\t';
}
str += '\n';
}
console.log(str);
5.5 while循环
while循环可以做一些更复杂的条件判断
语法结构:
while(条件表达式){
//循环体
}
注意:while循环里面也有计数器,里面也有操作表达式,完成计数器更新,防止死循环
5.5.1 while循环练习
例1:打印一个人的一生,从一岁到100岁
var i = 1;
while(i<=100){
console.log('这个人今年'+i+'岁了');
i++
}
例2:计算1~100整数和
var sum = 0;
var j = 1;
while(j<=100){
sum += j
j++
}
console.log(sum);//5050
5.6 do while循环
什么是do while循环呢,很多小伙伴都不太懂,就听过它跟while的区别是,do while至少运行一次,但是具体不懂原理,所以这里带着大家过一遍
语法结构:
do{
//循环体
}while(条件表达式)
例子
var i = 1;
do{
console.log('hello');
i++
}while(i<=100)
执行思路:跟while不同的地方在于 do while先执行一次循环体,再判断条件,如果条件为true则继续循环,否则退出循环
所以,do while至少会循环一次
5.6.1 do while循环练习
例1:打印人的一生 1~100岁
var i = 1;
do{
console.log('这个人今年'+i+'岁了');
i++
}while(i<=100)
例2:计算1~100之间整数和
var sum = 0;
var j = 1;
do{
sum += j;
j++
}while(j<=100)
console.log(sum);//5050
5.7 continue关键字
continue关键字用于立即跳出本次循环,继续下一次循环
例:吃5个包子,第3个有虫子,把第3个扔掉,继续吃4~5个
for(var i = 1;i<=5;i++){
if(i==3){
continue;//只要遇见continue就退出本次循环,直接跳到i++
}
console.log('我在吃第'+i+'个包子');
}
5.8 break关键字
break关键字跟continue关键字的区别是:break关键字用于跳出整个循环,就不继续执行了
例:吃5个包子,吃到第3个发现有半个虫子,剩下半个虫子不知道在哪了,所以决定剩下的都不吃了
for(var i = 1;i<=5;i++){
if(i==3){
break;
}
console.log('我正在吃第'+i+'个包子');
}
6 数组
6.1 数组的概念
数组(即Array)的概念:数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素,数组是一种将一组数据存储在单个变量名下的优雅方式
6.2 数组的作用
数组可以把一组相关的数据一起存放,并提供方便的访问(获取)方式
咱们简单理解就是:
之前咱们学过的普通变量一次只能存储一个值
var num = 10;
而数组一次可以存多个值
var arr = {1,2,3,4,5,6}
6.3 创建数组
有两种创建数组的方式
- 利用new关键字创建数组
- 利用数组字面量创建数组(常用)
1.利用new关键字创建
var arr = new Array();//创建了一个空的数组
2.利用字面量创建
var arr = [];//创建了一个空数组
var arr1 = [1,2,'shaka',true];//创建数组并存储数据
console.log(arr1);//输出
- 数组里面的数据用逗号分隔
- 数组里面的数据,我们称为数组元素
6.4 数组的索引
“索引”,就是下标,是我们用来访问数组元素的序号
注意: 数组索引从0开始
6.5 数组索引的作用
我们可以通过数组索引来访问,设置,修改对应的数组元素,可以通过数组名[索引] 的形式来获取数组中的元素
这里的访问就是获取得到的意思
var arr = [1,2,'shaka',true];
console.log(arr[2]);//shaka
console.log(arr[4]);//因为没有这个元素,所以输出结果是undefined
6.6 遍历数组(把数组中的元素全取出来)
规律:从数组中取出每一个元素时,代码是重复的,有所不一样的是索引值在递增,所以这里我们肯定要去用循环
遍历就是把数组中的每个元素从头到尾都访问一次
var arr = ['red','green','blue'];
for(var i = 0 ; i<3 ; i++){
console.log(arr[i]);
}
6.6.1 数组的长度
使用数组名.length 可以访问数组元素的数量(长度)
var arr = [1,2,3,4,5,6];
for(var i = 0; i<arr.length ; i++){
console.log(arr[i]);
}
6.7 练习题
例1:求数组[2,6,1,7,4]里面所有元素的和以及平均值
分析:
- 声明一个求和变量sum
- 遍历这个数组,把里面每个数组元素加到sum里面
- 用求和变量sum除以数组的长度就可以得到数组的平均值
var arr = [2,6,1,7,4];
var sum = 0;
var average = 0;
for(var i = 0; i<arr.length ; i++){
sum += arr[i];//这里注意我们加的是数组元素arr[i],不是计数器i
}
average = sum/arr.length;
console.log(sum,average);//想要输出多个变量,用逗号分隔
//输出结果:20 4
例2 :求数组[2,6,1,77,52,25,7]中的最大值
分析:
- 声明一个保存最大值的变量max
- 默认最大值可以取数组中的第一个元素
- 遍历这个数组,把里面每个数组元素和max相比较
- 如果这个数组元素大于max,就把这个数组元素存到max里面,否则继续下一轮比较
- 最后输出max
var arr = [2,6,1,77,52,25,7];
var max = arr[0];
for(var i = 1 ; i<arr.length ; i++){
if(arr[i]>max){
max = arr[i];
}
}
console.log('该数组最大值为:'+max);
6.8 数组中新增元素
有两种方式
1.通过修改length长度新增数组元素
var arr = ['red','green','blue'];
arr.length = 5;
console.log(arr);
console.log(arr[3]);
2.通过修改数组索引新增数组元素(常用)
var arr1 = ['red','green','blue'];
arr1[3] = 'pink';
arr1[4] = 'yellow';
console.log(arr1);
arr1[0] = 'black';
console.log(arr1);//替换了原来的数组元素
arr1 = 'hahaha';
console.log(arr1);//给数组名赋值的话,里面的数组元素都会被覆盖
1.使用循环来追加数组
2.声明一个空数组arr
3.循环中的计数器i可以作为数组元素介入
4.由于数组索引是从0开始的,因此计数器从0开始更合适,存入的数组元素要+1
var arr = [];
for(var i = 0 ; i< 10 ; i ++){
arr[i] = i + 1;
}
console.log(arr);
6.9 数组的经典案例
例子1:将数组[2,0,6,1,77,0,52,0,25,7]中大于等于10的元素筛选出来放入一个新数组
分析:
1.声明一个新数组用于存放新数组 newArr
2.遍历原来的旧数组,找出大于等于10的元素
3.依次追加给新数组 newArr
var arr = [2,0,6,1,77,0,52,0,25,7];
var newArr = [];
var j = 0;
for(var i = 0 ; i<arr.length ; i++){
if(arr[i]>10){
//新数组应该从0开始,依次递增
newArr[j] = arr[i];
j++;
}
}
console.log(newArr);
例子2:将数组[2,0,6,1,77,0,52,0,25,7]中的0去掉后,形成一个不包含0的数组
分析:
1.需要一个新数组用于存放筛选后的数据
2.遍历原来的数组,把不是0的数据添加到新数组里(采取数组名+索引的格式接受数据)
3.新数组里面的个数,用length不断累加
var arr = [2,0,6,1,77,0,52,0,25,7];
var newArr = [];
for(var i = 0 ; i<arr.length ; i++){
if(arr[i] != 0 ){
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
6.10 翻转数组
要求:将数组[‘red’,‘green’,‘blue’,‘pink’,‘purple’]的内容反过来存放
分析:
1.声明一个新数组newArr
2.把旧数组索引号第4个取过来(arr.length-1)给新数组索引号为0的元素
3.采取递减的方式
var arr = ['red','green','blue','pink','purple'];
var newArr = [];
for(var i = arr.length-1 ; i>=0 ; i--){
newArr[newArr.length] = arr[i]
}
console.log(newArr);
6.11 数组排序(冒泡排序)
冒泡排序,如果学过编程的小伙伴可能不陌生,它会涉及很多算法题和以后很多操作,非常重要哦!
那么冒泡排序是什么呢:冒泡排序是一种算法,把一系列的数据按照一定的顺序进行排列显示,它重复地走访要排序的数列,一次比较两个元素,如果它们的顺序错误,就把它们交换过来,走访数列的工作时重复地进行,直到不必再需要交换,也就是排序完成,这个算法的名字由来是因为越小的元素会经由于交换慢慢“浮”到数列的顶端
我们对此进行分析
1.一共需要的趟数,我们用外层for循环
5个数据我们需要走4趟,长度为数据长度-1,即arr.length-1
2.每一趟交换次数,我们用里层for循环
第一趟:4次
第二趟:3次
第三趟:2次
第四趟:1次
var arr = [4,1,2,3,5];
for(var i = 0 ; i<=arr.length ; i++){//外层for循环管趟数
for(var j = 0 ; j<=arr.length-i-1 ; j++){//里面循环管每一趟交换的次数
//内部交换两个变量的值,前一个和后面一个数组元素相比较
if(arr[j]>arr[j+1]){
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
console.log(arr);//12345
7 函数(非常非常重点!)
7.1 函数的概念
在JS里面,可能会定义非常多的相同代码或者功能相似的代码,这些代码可能需要大量重复使用,虽然for循环语句也能实现一些简单的重复操作,但是比较有局限性,这个时候我们就可以使用JS中的函数
这里用代妈给大家区别看一下
例:求1~100的累加和
for循环
var sum = 0;
for (var i = 0; i <= 100; i++) {
sum += i;
}
console.log(sum);
function函数
function getSum(num1,num2){
var sum = 0;
for(var i = num1 ; i<=num2 ; i++){
sum+=i;
}
console.log(sum);
}
getSum(1,100)
7.2 函数的使用
函数使用大致分为两步
1.声明函数
2.调用函数
1.声明函数
function函数名(){
//函数体
}
注意 :
- function为声明函数的关键字
- 函数是做某件事情,所以函数命名的时候一般是动词(例如getSum)
- 函数不调用的话自己是不执行的
2.调用函数
函数名();
7.3 函数的封装
函数的封装是把一个或多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口
简单来说:封装类似于将电脑配件组装到机箱中
7.4 函数的参数
我们可以通过函数的参数来执行不同的代码
7.4.1 形参和实参
我们在学习别的语言的时候也听过这两个词,这回我可以带着大家彻底了解这两概念了
function 函数名(形参1,形参2){//在声明函数的小括号里的是形参(形式上的参数)
}
函数名(实参1,实参2);//在调用的小括号里的是实参(实际的参数)
function cook(aru){
console.log(aru);
}
cook('土豆丝');
形参 :在函数定义的时候,当前并不知道是什么
实参 :在函数调用的时候传递的参数,实参是传递给形参的
7.4.2 参数的作用
在函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去
7.4.3 参数的应用例子
例:利用函数求任意两个数之间的和
function getSums(start,end){
var sum = 0;
for(var i = start ; i<=end ; i++){
sum += i;
}
console.log(sum);//5050
}
getSums(1,100);//随意输入自己想输入的数字即可
注意 :
- 如果实参的个数多于形参的个数,会取到形参的个数
- 如果实参个数小于形参个数的结果为undefined
7.4.4 参数小结
- 函数可以带参数也可以不带参数
- 声明函数时,函数名括号里面的是形参,形参的默认值是undefined
- 调用函数的时候,函数名括号里的为实参
- 多个参数之间用逗号分隔
- 形参的个数可以和实参个数不匹配,但是结果不可预计,所以我们尽量匹配
7.5 函数的返回值
return语句
语法结构:
function 函数名(){
return 需要返回的结果;
}
函数名();
function getResult(){
return 666;
}
getResult();
console.log(getResult());//666
- 函数只是实现某种功能,最终的结果需要返回给函数的调用者
- 只要函数遇到return,就把后面的结果返回给函数的调用者
- 函数名()=return后面的结果
7.5.1 函数的返回值练习
例:利用函数求任意一个数组中的最大值
求数组[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;
}
var re = getArrMax([5,2,99,101,67,77,]);
console.log(re);//101
7.6 return终止函数
- return后面的代码不会被执行
- return只能返回一个值,如果用逗号隔开多个值,以最后一个为准
- 函数有return,则返回return后面的值,如果没有,则返回undefined
7.7 break,continue,return的区别
- break:结束当前循环循环体(for,while)
- continue:跳出本次循环,继续执行下一次
- return:不仅可以退出循环,还能返回return语句中的值,同时还可以结束当前函数体内的代妈
7.7 arguments的使用
1.当我们不确定有多少个参数传递的时候,可以用arguments来获取
2.在JS中,arguments实际上它是当前函数的一个内置对象(对象在之后会说),所有的函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参
3.arguments展现形式是一个伪数组,因此可以遍历,伪数组 具有以下特点:
- 具有length属性
- 按索引方式存储数据
- 不具有数组的push,pop等方法
7.7.1 arguments练习
例1:利用函数求任意个数的最大值
function getMax(){
var max = arguments[0];
for(var i = 0 ; i<arguments.length ; i++){
if(arguments[i]>max){
max = arguments[i];
}
}
return max;
}
console.log(getMax(1,2,3,4,4,5));//5
例2 :利用函数封装方式翻转任意一个数组
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);//9,6,4,3,1
7.8 函数练习
例子1:利用函数封装的方式,对数组排序(冒泡排序)
function sort(arr) {
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]) {
var temp = arr[i];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
var arr1 = sort([1, 4, 2, 9]);
console.log(arr1);
例子2 :判断闰年:输入一个年份,判断是否为闰年(能被4整除不能被10整除或能被400整除的数)
function isRunYear(year){
//如果是闰年返回true,反之返回false
var flag = false;
if(year%4==0 && year%100!=0 || year%400==0){
flag = true;
}
return flag;
}
//传统写法
// var year = isRunYear(2000);
// console.log(year);
//简化写法
console.log(isRunYear(2000));
7.9 函数之间相互调用的问题
因为每个函数都是独立的代码块,用于完成特殊的任务,因此经常会用到函数相互调用的情况
例如:
function fn1(){
console.log(11);
fn2();//在fn1函数里调用了fn2函数
}
fn1();
function fn2(){
console.log(22);
又例如:
function fn1(){
console.log(111);
fn2();
console.log('fn1');
}
function fn2(){
console.log(222);
console.log('fn2');
}
fn1();
//111
//222
//fn2
//fn1
7.10 函数的两种声明方式
1.利用函数关键字自定义函数(命名函数)
function fn(){
}
fn();
2.函数表达式(匿名函数)
var 变量名 = function(){};
var fun = function (){
console.log('我是函数');
}
fun();
//fun是变量名,不是函数名
8 JavaScript作用域
8.1 作用域概述
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的 可用性的代码范围 就是这个名字的 作用域
作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突
JS的作用域(es6)之前分为:
1.全局作用域
2.局部作用域(也叫函数作用域)
8.2 变量作用域的分类
- 全局变量:全局作用域下的变量,全局下都可以使用(如果在函数内部,没直接声明赋值的变量也属于全局变量)
- 局部变量:局部作用域下的变量,函数内部使用
从执行效率上看: - 全局变量:只有浏览器关闭的时候才会销毁,比较占内存
- 局部变量:当我们程序执行完毕就会销毁,比较节省内存
8.3 作用域链
- 只要是代码,就至少有一个作用域
- 写在函数内部为局部作用域
- 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
- 根据内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作 作用域链
如图所示,当函数调用后,num先找离自己最近的var num20,如果找不到,再像链子一样往下找,找外面的varnum10,这里显然找到了最近的20,所以就不继续往下找了
8.4 作用域链练习
例子1:求结果是多少
function f1(){
var num = 123;
function f2(){
console.log(num);
}
f2();
}
var num = 456;
f1();//123
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);//4
console.log(b);//'22'
}
}
}
fn1();
这个如果能想明白基本就差不多啦!
9 JavaScript预解析
JS代码是由浏览器中的JavaScript解析器来执行的,JS解析器在运行JS代码的时候分为两步:
- 预解析:JS引擎会把JS里面所有var和function提升到当前作用域的最前面
- 代码执行:按照代码的书写顺序从上往下执行
预解析分为: - 变量预解析(也叫变量提升)
- 函数预解析(也叫函数提升)
直接看官方的解释不免有所看不懂,这里我用代码演示一下
console.log(num);//undefined
var num = 10;
我们知道这个输出结果是undefined,但是根本原理是什么呢,用代码演示一下
var num;
console.log(num);
num = 10;
以上两段代码是相等的,下面的代码是上面代码的真实形式
我们看到,本在后面的写的变量var num跑到上面去了,这就是所谓的 变量提升
再看下面这段代码:
fun();
var fun = function () {
console.log(22);
}
var fun;
fun();
fun = function () {
console.log(22);
}
9.1 变量提升和函数提升
变量提升:就是把所有变量声明提升到当前的作用域最前面,但是不提升赋值操作
函数提升:就是把所有函数声明提升到当前的作用域最前面,但是不调用函数
下面我会用大量代码演示这个概念
例子1:
fn();
function fn() {
console.log(11);//11
}
相当于:
function fn() {
console.log(11);//11
}
fn();
例子2:
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
//undefined
}
它为什么undefined了呢,那是因为它等同于下面这段代码:
var num;
function fun() {
var num;
console.log(num);
num = 20;
}
num = 10;
fun();
例子3 :
var num = 10;
function fn() {
console.log(num);
var num = 20;
console.log(num);
}
fn();
//undefin
//20
再看看它相当于什么代码吧
var num;
function fn() {
var num;
console.log(num);
num = 20;
console.log(num);
}
num = 10;
fn();
是不是基本明白了
再来最后一个例子4:
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
//undefined
//9
它相当于:
var a;
function f1() {
var b;
var a;
b = 9;
console.log(a);
console.log(b);
a = '123';
}
a = 18;
f1();
好了我相信你基本掌握了,那么来一个练习吧!
9.2 练习
求下列代码结果
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;//这个代码相当于:var a =9 ,b=9,c=9
console.log(a);
console.log(b);
console.log(c);
}
猜对答案了吗
这里给大家解读一下 var a = b = c = 9; 这行代码
可能有人觉得这是集体声明,但是并不是,集体声明的格式应该如下
var a = 9,b=9,c=9
相当于:
var a = 9;
var b = 9;
var c =9;
这才是集体声明的写法,一定要区别出来!
所以 var a = b = c = 9;这行代码,只有a是var,而b,c是直接赋值,没有var,所以!!!此处b,c为 全局变量 !
什么是全局变量?在8.2章节我有写过,忘了的小伙伴可以回去看看,就返现我特意写了一个 如果在函数内部,没直接声明赋值的变量也属于全局变量
好了,分析完了,看看它的真实代码吧
function f1() {
var a;
a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a);
这回明白了吧!
9.3 解决变量提升
如果大家能意识到变量提升带来的不变,那么大家就会慢慢发现ES5中有很多的问题不好处理,就拿提升变量这个问题来说,在之后学习的ES6,我们声明变量就不用var了。而是用let和const,这里不细讲了,在之后会写es6的文章
10 JavaScript对象
10.1 什么是对象
在JS中,对象是一组无序的相关属性和方法的集合,所有事物都是对象,例如:字符串,数组,函数等
什么是属性和方法
- 属性:事物的特征,在对象中用属性来表示(名词)
- 方法:事物的行为,在对象中用方法来表示(动词)
10.2 为什么需要对象
我们保存一个值,可以用变量,保存多个值,可以用数组,那么,如果要保存一个人的完整信息呢?
为此,我们引入了对象这个概念,JS中的对象表达结构更清晰,更强大
10.3 创建对象
创建对象,我们有三种方式
- 利用字面量创建对象
- 利用newObject创建
- 利用构造函数创建
10.3.1 利用字面量创建对象
对象字面量:就是花括号{}里面包含了表达这个具体事物(对象)的属性和方法
var obj = {
uname: 'shaka',
age: 21,
sex: '男',
sayHi: function () {
console.log('hi~');
}
}
console.log(obj);
- 里面的属性或方法采取键值对的形式;键:属性名,值:属性值
- 多个属性或者方法之间用逗号分隔
- 方法冒号后跟的是一个匿名函数(匿名函数在函数章节有说过,在7.10)
10.3.2 利用new Object创建对象
var obj = new Object();//创建一个空对象
obj.uname = 'shaka';
obj.age = 21;
obj.sex = '男';
obj.sayHi = function () {
console.log('hi~');
}
console.log(obj);
注意:
- 利用等号赋值的方法,添加属性和方法
- 每个属性和方法之间用分号结尾
10.3.3 利用构造函数创建对象
在前面两种方式一次只能创建一个对象,所以我们这里有了用函数创建的方法
这里函数里面封装的不是不同代码,而是对象
构造函数就是把我们对象里面一些相同属性和方法抽象出来封装到函数里面
语法格式如下:
function 构造函数名(){
this.属性 = 值 ;
this.方法 = function(){}
}
new 构造函数名();
例子:创建四大天王对象
相同的属性:名字,年龄,性别
相同的方法:唱歌
<body>
<script>
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.name);//刘德华
console.log(ldh['sex']);//男
var zxy = new Star('张学友', 19, '男');
ldh.sing('冰雨');//冰雨
</script>
</body>
注意:
- 构造函数名字首字母大写
- 构造函数不需要return就可以返回结果
- 我们调用构造函数,必须用new
- 只要new Star()调用函数就创建一个对象
- 属性和方法之前必须加this
10.4 使用对象
- 使用对象的属性采取:对象名.属性名:obj.uname
- 调用还有一种方法:对象名[‘属性名’]:obj[‘age’]
- 调用属性的方法:对象名.方法名:obj.sayHi()
10.5 构造函数和对象
- 构造函数:明星 ——泛指的某一大类,类似于Java中的类(class)
- 对象:刘德华——具体的事物
- 我们利用构造函数创建对象的过程也称作对象的实例化(把虚变实)
10.6 new关键字
执行过程
- new构造函数可以在内存中创建一个空的对象
- this就会指向给这个空对象
- 执行构造函数里面的代码,给这个函数添加属性和方法
- 返回这个对象(所以不需要return)
10.7 遍历对象
遍历对象这里不可以用for循环了,因为里面的属性是无序的
我们采取一种全新的方式:for…in语句
for…in语句用于数组或对象的属性进行循环操作(最好是用于对象)
语法格式:
for(变量 in 对象){
}
例子:
<body>
<script>
var obj = {
name: 'shaka',
age: 21,
sex: '男'
}
for (var k in obj) {
console.log(k);//k是变量,输出得到属性名
console.log(obj[k]);//得到属性值
}
</script>
</body>
11 JavaScript内置对象
11.1 什么是JS的内置对象
- 我们首先要知道,JS中的对象分为三种:自定义对象、内置对象、浏览器对象
- 前两种是JS基础内容,属于ECMAScript,第三个是JS独有的,会在JSAPI(DOM、BOM)中讲解
- 内置对象是指JS语言中自带的一些对象,这些对象供开发者使用,并提供了一些常用的,或是最基本而必须的功能(属性和方法)
- 内置对象的优点是帮助我们快速开发
- 常用的内置对象:Math,Date,Array,String
11.2 学会查文档MDN
查找文档:学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过查文档学习,可以通过MDN/W3C来查询。
Mozilla 开发者网络(MDN)提供了有关开放网络技术(Open Web)的信息,包括 HTML、CSS 和万维网及 HTML5 应用的 API。
MDN:https://developer.mozilla.org/zh-CN/
这个网站非常重要,相信我,你以后会经常来的!
11.3 如何学习对象中的方法
- 查阅该方法的功能
- 查看里面参数的意义和类型
- 查看返回值的意义和类型
- 通过demo进行测试
11.4 Math数学对象
Math对象不是一个构造函数,所以不需要new来调用,而是直接使用里面的属性和方法即可
<script>
console.log(Math.PI);
console.log(Math.max(1, 99, 3));
console.log(Math.max(1, 99, 'shaka'));
console.log(Math.max());
</script>
绝对值方法
console.log(Math.abs(1));
console.log(Math.abs('-1'));//隐式转换
console.log(Math.abs('shaka'));//NaN
三个取整方法
console.log(Math.floor(1.9));
console.log(Math.ceil(1.1));
console.log(Math.round(1.5));
console.log(Math.round(-1.1));
console.log(Math.round(-1.5));
Math.floor()向下取整,往最小了取值
Math.ceil()向上取整,往最大了取值
Math.round()四舍五入,其它数字都是四舍五入,但是5特殊,它往大了取
随机数方法:Math.random()
返回随机的一个小数,取值范围[0,1)
console.log(Math.random());
这个方法里面不含参数
现在有一个需求:想得到两个数之间的随机整数,并且包括这两个整数
公式: Math.floor(Math.random()*(max-min+1))+min
我们给它封装起来
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
console.log(getRandom(1, 10));
有什么用呢?可以用来做随机点名
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
var arr = ['shaka', 'virgo', 'hhhh']
console.log(arr[getRandom(0, arr.length - 1)]);
11.4.1 封装自己的数学对象
利用对象封装自己的数学对象,里面有PI最大值和最小值
代码如下(示例):
11.5 Date日期对象
日期对象Date()是一个构造函数,所以必须使用new来调用创建我们的日期对象
var date = new Date()
console.log(date);
注意:
- 如果没有参数,返回当前系统的当前时间
- 参数的常用写法:数字型(2019,10,01)或字符串型(‘2019-10-1 8:8:8’)
var date1 = new Date(2022, 10, 1)
console.log(date1);
注意返回的是11月,不是10月
var date1 = new Date('2022-10-1 8:8:8')
console.log(date1);
返回的是10月
Date概述:
- Date对象和Math对象不一样,它是一个构造函数,需要实例化后使用
- Date实例用来处理日期和时间
Date()方法的使用:
- 无参数:获取当前时间
- 有参数:两种写法,见上面
总结
提示:这里对文章进行总结:
例如:以上就是
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/79728.html