前言
一.初识JavaScript
1.JavaScript是什么
-
JavaScript
是世界上最流行的语言之一,是一种运行在客户端上的脚本语言(Script是脚本的意思)。 -
脚本语言是指不需要进行编译,运行过程中直接由(
js引擎)
逐行来进行解释并执行。 -
现在的js也可以基于
Node.js
技术进行服务器编程。
2.JavaScript可以做什么
-
表单动态校验(密码强度校验)–js产生最初的目的
-
网页特性
-
做服务端开发(Node.js)
-
桌面程序(Electron)
-
App(Cordova)
-
控制硬件–物联网(Ruff)
-
游戏开发(cocos2d-js)
3.HTML/CSS/JS三者的关系
HTML/CSS(标记语言):
-
HTML
用来决定网页的结构和内容(相当于我们人的身体)。 -
CSS
用来美化网页,呈现给用户(相当于给人穿上了衣服,化了妆)。
JS(脚本语言):
- 实现业务逻辑和页面控制,使得静态的网页能够"动起来"(相当于人可以行走,有各种动作)。
4.浏览器执行JS简介
浏览器:分为渲染引擎和JS引擎。
-
渲染引擎:用来解析HTML/CSS,俗称内核。比如chrome浏览器的blink,老版本的webkit。
-
JS引擎:也称为
JS解释器
。用来读取页面中JavaScript的代码,对其处理后运行。比如chrome浏览器 的V8。
浏览器本身并不会执行JS代码,而是通过JS引擎(解释器)来执行JS代码。JS引擎执行代码时逐行解释每一句源码(转换为机器语言),然后由计算机去执行,所以JavaScript归为脚本语言,由解释器逐行解释运行。
5.JS的组成
JavaScript由三部分组成:ECMAScript
、DOM
、BOM
。
1.ECMAScript
是由ECMA国际(原欧洲计算机制造商协会)进行标准化的一门编程语言、这种语言在万维网上应用广泛,它往往被称为JavaScript(网景公司的)或JScript(微软公司的),实际上后两者都是ECMAScript语言的实现和扩展。
ECMAScript:规定了JS的编程语法和基础核心知识,是所有浏览器厂商共同遵守的一套JS语法工业标准。
2.DOM(文档对象模型)
文档对象模型(简称DOM
),是W3C组织推荐的处理可扩展标记语言的标准编程接口。通过DOM提供的接口可以对页面上的各种元素进行操作(如大小、位置、颜色等)。
3.BOM(浏览器对象模型)
浏览器对象模型(简称BOM
),它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等。
6.JS初体验
1.JS的书写方式
JS的书写方式有三种,分别是:行内式
、内嵌式
、外部式
。
<!-- 行内式 -->
<input type="button" value="点我一下试试" onclick="alert('hello world!')"> -->
- 可以将单行或者少量js代码写在HTML标签的事件属性中(以on开头的属性),如: onclick;
<!-- 2.内嵌式 -->
<script>
alert('hello world!')
</script>
- 可以将多行JS代码写到<script>标签中
<!-- 3.外部式 -->
<script src="./hellowold.js"></script>
- 把大段代码独立写到JS文件,然后引用外部JS文件到HTML的结构中。
2.JS的注释
在JavaScript中,有两种类型的注释:单行注释
、多行注释
。
1.单行注释:
// 这是一个单行注释
- 以双斜杠
//
开头,从该符号后面的字符一直到该行的末尾都被视为注释。
2.多行注释:
/*
这是一个多行注释
可以包含多行内容
*/
- 以
/*
开头,*/
结束,中间的所有内容都被视为注释。
3.JS的输入/输出语句
// prompt 输入
prompt('请输入手机号');
// alert 弹出警示框 (给用户看到的)
alert('你好');
//console.log (输出打印信息)
console.log('hello world');
二.JS中的变量
变量
就是程序在内存中申请的一块用来存储数据的空间
(变量就是用来存储数据的)。
1.变量的定义
var 变量名 = 值
,如:
// 1.变量的声明和赋值
var age;
age = 18;
console.log(age);
// 2.变量的初始化(声明的同时赋值)
var myname = 'PanCc';
console.log(myname);
2.变量的命名
1.由字母
、数字
、下划线
、美元$
符组成,不能以数字开头:
var a0_$ = 1;
console.log(a0_$); // 1
2.严格区分大小写:
var app = '抖音';
var App = '快手';
console.log(app, App); // '抖音' '快手'
3.不能是关键字(var等)、保留字(for,if,while等):
// var var = 20; 报错
// console.log(var); Unexpected token 'var'
4.变量名必须有意义,不能乱起。
5.遵循驼峰命名,如: myFirstName。
6.不适用name,name有特殊含义。
3.变量的使用
- 案例1: 弹出一个输入框, 提示用户输入名字。 2.弹出一个对话框,输出用户刚才输入的名字。
// 1.声明变量--存储用户输入的信息
var name = prompt('请输入姓名:');
// 2.输出变量
alert(name);
- 案例2: 交换两个变量的值。
// apple1: 青苹果 apple2:红苹果 现在要交换两个变量的值, 让apple1: 变成红苹果, apple2: 变成青苹果
var temp;
var apple1 = '青苹果';
var apple2 = '红苹果';
temp = apple1;
apple1 = apple2;
apple2 = temp;
console.log(apple1);
console.log(apple2);
- 先声明一个临时变量temp
- apple1的值赋给临时变量temp
- apple2的值赋给变量apple1
- temp存储的值赋给变量apple2
4.变量的扩展
1.修改变量的值
var name = '旋涡鸣人';
console.log(name);
name = '佐助';
console.log(name) // '佐助'
- 还是用的同一个内存空间,只是变量的值改变了。
2.同时声明多个变量
var name = '鸣人',
age = 18,
address = '木叶';
console.log(name, age, address); // 鸣人, 18, 广西
3.声明变量的特殊情况
// (1) 变量只声明,未赋值
var sex;
console.log(sex); // undefined
// (2) 变量未声明,只赋值(能正常输出)
tel = 10010;
console.log(tel); // 10010
// (3)变量未声明,未赋值
email;
console.log(email); // 报错: email is not defined
三.数据类型
JavaScript中变量的数据类型分为: ·简单数据类型
、复杂数据类型
。
- 简单数据类型: 数字(
Number
)、字符串(String
)、布尔(Boolean
)、空(null
)、未定(undefined
) - 复杂数据类型: 对象(
object
)、数组(Array
)、函数(function
)
js变量的数据类型只有在程序运行过程中,根据=
号右边的值才确定。
var num; // 此时并不不能确定变量的数据类型是什么
var num = 10; // 10 (数字型)
var str = 'pan' // 'pan' (字符型)
javaScript 拥有动态类型。这意味着相同的变量可用作不同的类型。
var s = 100;
s = 'pan';
console.log(s); // 'pan'
1.简单数据类型
1.1数字型(Number)
(1) 数字型的初始化
var num = 10; //数字型
var PI = 3.14; //数字型
(2) 八进制 0~7
程序中数字前面加0
表示八进制
var num1 = 010;
console.log(num1); // 8
(3) 十六进制 0~9 a~f
数字的前面加0x
,表示十六进制
var num2 = 0x9;
console.log(num2); // 9
var num3 = 0xa;
console.log(num3); // 10
0x
表示十六进制 然后例如a
,就是数字10
(4) 数字型的最大值/最小值
console.log(Number.MAX_VALUE); // 1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 5e-324
(5) 无穷大(Infinity)/无穷小(-Infinity)
console.log((Number.MAX_VALUE * 2)); // Infinity
console.log((-Number.MAX_VALUE * 2)); // -Infinity
(6) 非数字(NaN)
console.log('pan' - 100); // NaN
(7) isNaN()
用来判断是否为非数字型,是数字型则返回false
,不是数字型则返回true
console.log(isNaN(10)); // false
console.log(isNaN('pan')) // true
1.2字符串型(String)
(1) 字符串的初始化
var str1 = '刘备';
var str2 = "关羽";
- 字符串用引号括起来,可以是单引号,也可以是双引号(推荐使用单引号)
(2) 嵌套的字符串
//外单内双
var str3 = 'pan是一位优秀的"程序猿"';
console.log(str3);
//外双内单
var str4 = "pan是一位优秀的'程序猿'";
console.log(str4);
- 字符串嵌套可以是外单内双或者外双内单
(3) 字符串的转义字符
// \n:换行符
var str5 = "东临碣石,以观沧海\n水何澹澹,山岛竦峙";
console.log(str5);
- 字符串的转义字符用反斜杠
\
开头 \n
: 换行符\\
: 斜杠\\'
: 单引号\"
: 双引号\t
: 缩进\b
: 空格
(4) 获取字符串的长度
var str1 = 'minemine'.length;
console.log(str1) // 8
str.length()
可以获取到字符串的长度
(5) 字符串的拼接
var str3 = '东隅已逝,' + '桑榆非晚';
console.log(str3); // 东隅已逝,桑榆非晚
- 使用
+
号拼接字符串
(6) 字符串和其他类型的相加
var str4 = 'pan is' + 18;
console.log(str4); // pan is18
var str5 = '12' + 12;
console.log(str5); // 1212 本质上就是变成了 '12' + '12'
- 字符串和其他类型的相加,最后都会转为字符串
- 任何类型和字符串相加结果都会变成字符串
交互式编程:
交互式编程的三要素: 1.用户输入
,2.程序内部处理
, 3.输出结果
age = prompt('请输入您的年龄:'); // (1.用户输入)
str = '您今年' + age + '岁啦'; // (2.程序内部处理)
alert(str); // (3.输出结果)
1.3布尔型(Boolean)
(1) 布尔型的初始化
var flag1 = true;
console.log(flag1); // true
var flag2 = false;
console.log(flag2); // false
boolean
类型的值只有true
和false
(2) boolean类型与数字型相加
var flag3 = true + 1;
console.log(flag3); // 2
var flag4 = false + 1;
console.log(flag4); // 1
boolean
类型与数字型进行运算时,true
是1false
是0
(3) boolean类型与字符串进行相加
var flag5 = true + '000';
console.log(flag5); // flag000
boolean
类型与字符串进行相加,得到的是字符串
1.4未定义型(Undefined)
(1) undefined表示未定义的数据类型
var a;
console.log(a); // undefined
(2) undefined和数字型相加
var b = undefined;
console.log(b + 1); // NaN
undefined
和数字型相加 得到的是NaN
(not a number
表示不是数字)
(3) undefined和字符串相加
var a = undefined;
console.log(a + 'ccc'); // undefinedccc
undefined
和字符串相加,得到的是字符串
1.5空类型(Null)
(1) null表示空值
var n = null;
console.log(s); // null
(2) null和数字型相加
var n = null;
console.log(n) // 1
null
和数字型相加,得到的是数字型
(3) null和字符串相加
var n = null;
console.log(n +'ccc'); // nccc
null
和字符串相加,得到的是字符串
在JavaScript中,我们是怎么判断数据是什么类型的呢?
使用type of
可以获取到变量的数据类型:
var num = 10;
console.log(typeof num); // number
var str = 'pan';
console.log(typeof str); // string
var flag = true;
console.log(typeof flag); // boolean
var udf;
console.log(typeof udf); // undefined
var n = null;
console.log(typeof n); // object
通过typeof
, 我们能知道prompt()
获取到的值是字符串型的(string
)
acct = prompt('请输入您的账号:');
console.log(typeof acct); // string
- 除了
typeof
能检测到变量的数据类型外,我们还可以通过字面量
的形式判断数据类型,也可以在控制抬值的字体颜色
看出来数据类型。
2.数据类型转换
2.1.数据类型转换(转换为字符串)
(1) tostring()
var num = 10;
var str = num.toString();
console.log(str, typeof str); // 10 string
- 使用
变量.tostring()
的方式将数字型转换为字符串型
(2) String()
var num2 = 100;
str2 = String(num2);
console.log(str2, typeof str2); // 100 string
- 使用
String(变量)
的方式将数字型转换为字符串型
(3) 隐式转换
var num3 = 1000;
str3 = num3 + '';
console.log(str3, typeof str3); // 1000 string
- 当有
+
号拼接时,都会隐式转换为字符串
打印用户信息案例:
// 案例:依次询问并获取用户的姓名,年龄,性别,并打印用户的完整信息
str_name = prompt('请输入您的姓名:');
age = prompt('请输入您的年龄:');
sex = prompt('请输入您的性别:');
alert('您的姓名:' + str_name + '\n您的年龄:' + age + '\n您的性别:' + sex);
prompt()
返回的是字符串型,使用+
可以拼接字符串
2.2数据类型转换(转换为数字型)
(1) parseInt(string)
console.log(parseInt('3.14')); // 3 取整
console.log(parseInt('3.99')); // 3 忽略小数点后面的数,不会进位
console.log(parseInt('120px')); // 120 取到数值 忽略掉后面的单位
console.log(parseInt('rem120px')); // NaN
parseInt(string)
将字符串型转换为数字型,得到整数
(2) parseFloat(string)
console.log(parseFloat('3.14')); // 3.14
console.log(parseFloat('3.99')); // 3.99
console.log(parseFloat('120px')); // 120
console.log(parseFloat('rem120NaN')); // NaN
parseFloat(string)
将字符串型转换为数字型,得到浮点数
(小数
)
(3) Number(string)
var str = '123';
console.log(Number(str)); // 123
console.log(Number('123')); // 123
Number(string)
将字符串型转换为数字型
(4) 隐式转换
var str2 = '100' - 1;
console.log(str2); // 99
console.log('102' - '100'); // 2
console.log('2' * 2); // 4
console.log('2' / 2); // 1
- 当有
- * /
进行运算时,都会隐式转换为数字型
计算年龄案例:
// 案例: 在页面中弹出一个输入框,我们输入出生年份后,能计算出我们的年龄,最后弹出窗口显示
var year = prompt('请输入您的出生年份:');
var age = 2023 - year;
alert('您的年龄是:' + age + '岁');
year
取到的是字符串型 这里用到了-
号运算 有隐式转换 转成了数字型
简单加法器案例:
// 案例: 计算两个数的值,用户输入第一个值后,继续弹出第二个输入框并输入第二个值,然后通过弹出窗口
var first = prompt('请输入第一个值:');
var second = prompt('请输入第二个值:');
var result = parseFloat(first) + parseFloat(second);
alert('相加后的结果为:' + result);
first
、second
取到的值都是字符型(string
) 使用了parseFloat()
进行转换,得到的结果是数字型
2.3数据类型转换(转换为布尔型)
(1) Boolean()
console.log(Boolean('')); // false
console.log(Boolean(0)); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
四.运算符
JavaScript中的运算符有: 算术运算符
、自增自减运算符
、比较运算符
、逻辑运算符
、赋值运算符
。
1.算术运算符
运算符 | 描述 | 例子 |
---|---|---|
+ | 加 | 1+1 输出结果为 2 |
- | 减 | 1-1 输出结果为 0 |
* | 乘 | 1*2 输出结果为 2 |
/ | 除 | 4/2 输出结果为 2 |
% | 取余数 | 5%3 输出结果为 2 |
console.log(1 + 1); // 2
console.log(1 - 1); // 0
console.log(1 * 2); // 2
console.log(4 / 2); // 2
console.log(5 % 3); // 2
console.log(3 % 5); // 3
浮点数避免直接进行运算
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.07 * 100); // 7.000000000000001
- 浮点数用来运算会有偏差(因为计算机最终会转为
二进制
进行运算)
不要直接判断两个浮点数是否相等
var num = 0.1 + 0.2;
console.log(num == 0.3); // false num和0.3比较,并不相等
算术运算符的优先级
var num2 = 1 + 2 * 4;
console.log(num2); // 9
- 先
乘除
后加减
,有括号就先括号
2.自增自减运算符
运算符 | 描述 | 例子 |
---|---|---|
++a | 前置自增运算符(先自增后运算) | ++a 等价于 a = a + 1 |
a++ | 后置自增运算符(先运算后自增) | a++ 等价于 a = a - 1 |
–a | 前置自减运算符(先自减后运算) | –a 等价于 a = a - 1 |
a– | 后置自减运算符(先运算后自减) | a-- 等价于 a = a - 1 |
自增运算符:++a
var a = 1;
++num; // 相当于num = num + 1
console.log(a); // 2
var sum = 10;
console.log(++sum + 10); // 21 先自增,后运算
++a
表示先自增1,后运算
自增运算符:++a
var num2 = 10;
num2++; // 相当于num = num + 1
console.log(num2); // 11
var sum2 = 10;
console.log(sum2++ + 10); // 20 (先返回值然后成了10+10) 先返回,后自增
console.log(sum2); // 11 后自增
a++
表示先运算,后自增1
自减运算符:--a
var a = 1;
--a;
console.log(a); // 0
--a
表示先自减1,后运算
自减运算符:a--
var a = 1;
--a;
console.log(a); // 0
a--
表示先运算1,后自减1
扩展:
++a
和a++
如果单独的使用,效果都是一样,都相当于a = a + 1
。
--a
和a--
如果单独的使用,效果都是一样,都相当于a = a - 1
。
3.比较运算符
运算符 | 描述 | 例子 |
---|---|---|
> | 大于,左侧大于右侧,则条件结果为true,否则为false | a=1,b=2则(a>b),为false |
< | 小于,左侧小于右侧,则条件结果为true,否则为false | a=1,b=2则(a<b),为true |
>= | 大于等于,左侧大于等于右侧,则条件结果为true,否则为false | a=2,b=3则(a>=b),为false |
<= | 小于等于,左侧小于右侧,则条件结果为true,否则为false | a=2,b=3则(a<=b),为true |
== | 相等,如果两个操作数的结果相等,则条件结果为true,否则为false | a=5,b=5则(a==b),为true |
!= | 不等于,如果两个操作数的结果不相等,则条件结果为true,否则为false | a=5,b=5,则(a!=b),为false |
=== | 全等于,左侧全等于右侧(要同时满足值和数据类型都相等才为true,否则为false) | a=5,b=‘5’,则(a===b),为false |
console.log(1 > 2); // false
console.log(1 < 2); // true
console.log(2 >= 3); // false
console.log(2 <= 3); // true
console.log(5 == 5); // true
console.log(5 != 5); // false
console.log(5 === '5'); // false
在程序中等于符号是 ==
不等于符号是!=
console.log(3 == 3); // true
console.log(4 != 3); // true
==
符号有隐式转换
console.log(3 == '3'); // true
console.log(3 != 3); // false
==
号默认会把字符串型转为数字型
===
代表全等于
console.log(3 === 3); // true
console.log(3 === '3'); // false
数值
和数据类型
都相等要一模一样才是全等于
=
、==
、===
三者的区别:
=
是赋值==
是判断(判断两边值是否相等,此时有隐式转换)===
全等(【判断两边是否全等,数值
和数据类型
都相等才为true
)
4.逻辑运算符
运算符 | 表达式 | 描述 | 例子 |
---|---|---|---|
&& | a && b | 与运算,全真则为true,有假则为False | true && true,为true |
|| | a ||b | 或运算,有真则为true,全假则为false | false || false,为false |
! | !a | 非运算,非真即假 | !true,为false |
逻辑运算符: 与(&&
)、或(||
)、非(!
)
// 逻辑与 &&
console.log(1 > 2 && 2 < 4); // false
console.log(1 < 2 && 2 < 4); // true
// 逻辑或 ||
console.log(1 > 2 || 2 < 4); // true
console.log(1 > 2 || 2 > 4); // false
// 逻辑非 !
console.log(!true); // false
console.log(!false); // true
在javascript中,用布尔值参与的逻辑运算是:true && false
,那么如果是直接用表达式(123 && 456
)来参与逻辑运算会是怎样呢?
如果直接用表达式如(123&&456
)来参与的逻辑运算,我们称为短路运算
(逻辑中断
)。
短路与(&&
)和短路或(||
)
// 1.逻辑与的短路运算(若表达式1为ture,则结果为表达式2,若表达式1为false,则结果为表达式1)--为true则结果为下一个表达式
console.log(123 && 456); // 456
console.log(0 && 456); // 0
console.log(0 && 123 * 2 && 456 + 100); // 0
// 2.逻辑或的短路运算(若表达式1的结果为true,则结果为表达式1,若表达式1的结果为false,结果为表达式2)--为false则结果为下一个表达式
console.log(123 || 456); // 123
console.log(0 || 456); // 456
console.log(0 || 10 + 10 || 456 * 2 || 100 + 100); // 20
// 3. '' 0 null undefined NaN 都表示假,其余都为真
console.log('' && 456 && 789); // ''
console.log('' || 456 || 789); // 456
// 4. 逻辑中断会影响我们程序运行的结果(重要)
var num = 0;
console.log(123 || num++); // 123
console.log(num); // 0 逻辑或为真时,则结果是表达式1,后面的表达式2(num++)就忽略了,所以num的值为0
5.赋值运算符
运算符 | 描述 | 例子 |
---|---|---|
= | 直接赋值 | c = 1 |
+= | 加法赋值运算符 | c += 1 等价 c = c+1 |
-= | 减法赋值运算符 | c -= 1 等价 c = c-1 |
*= | 乘法赋值运算符 | c *= 1 等价 c = c*1 |
/= | 除法赋值运算符 | c /= 1 等价 c = c /1 |
%= | 取余赋值运算符 | c %=1 等价 c = c%1 |
var num = 10;
num += 10; // 相当于:num = num + 10;
console.log(num); // 20
var num2 = 5
num2 -= 5; // 相当于: num2 = num2 - 5;
console.log(num2) // 0
运算符的优先级顺序
1.小括号:()
2.一元运算符: ++ -- !
3.算术运算符 : 先* /
后 + -
4.关系运算符: > >= < <=
5.等于: == != === !==
6.逻辑运算符: 先&&
后||
7.赋值运算符: =
8.逗号 :,
注意: 一元运算符中逻辑非(!
)优先级最高
// 练习1: 逻辑运算符权重比较低,所以我们先从逻辑运算符划分好一共有几部分
console.log(4 > 6 || '人' != '阿凡达' && !(12 * 2 == 144) && true) // 4部分 f || t && t && t true
var num = 10;
console.log(5 == num / 2 && (2 + 2 * num).toString() === '22'); // 2部分 t && t true
// 练习2:
var a = 3 > 5 && 2 < 7 && 3 == 4;
console.log(a); // f && t && f false
var b = 3 <= 4 || 3 > 1 || 3 != 2;
console.log(b) // t || t || t true
var c = 2 === '2';
console.log(c); // f false
var d = !c || b && a;
console.log(d); // t || f true
五.流程控制
流程控制是编程中的重要概念,它允许程序根据不同的条件执行不同的操作。在 JavaScript 中,流程控制分为: 顺序结构
、分支结构
、循环结构
。
1.顺序结构
顺序结构是指代码按照从上到下的顺序依次执行。
例如下面的代码就是一个简单的顺序结构:
var a = 10;
var b = 100;
console.log(b);
console.log(a);
- 代码从上到下,按顺序的进行执行,先输出
b
,再输出a
2.分支结构
分支结构是指代码由上到下执行的过程中,根据不同的条件,执行不同的路径,从而得到不同的结果。在JavaScript中,分支结构可以用if
条件语句、switch
条件语句和三元表达式
来实现。
2.1 if条件语句
// 语法
if (条件表达式) {
执行语句;
...
}
- 若表达式成立(为
true
),则执行if块里的代码。若表达式不成立(为false
),则不执行if块
里的代码
示例:
/* 网吧上网案例
弹出一个输入框,要求用户输入年龄,如果年龄大于等于18岁,允许上网
*/
var age = prompt('请输入您的年龄:');
if (age >= 18) {
alert('祝你上网愉快!');
}
- 弹出
prompt()
输入框,用户输入年龄后,用变量age
进行保存 - 用
if
条件语句判断age
,若age>=18
,则执行if块
里的代码,不满足条件则不执行if
语句
2.2 if-else双分支条件语句
// 语法:
if(条件表达式) {
执行语句1;
...
} else {
执行语句2;
...
}
- 若表达式的结果为
true
,则执行if块
里的代码,若表达式得结果为false
,则执行else
里的代码 - 要么执行
if块
中的代码,要么执行else块
中的代码,最终只能执行其中一个2选1
示例:
/* 判断闰年案例:
判断用户输入的年份是否为闰年,如果是闰年则输出闰年,不是则输出是平年
*/
var year = prompt('请输入要检测的年份:');
if (year % 4 == 0 && year % 100 !== 0 || year % 400 == 0) {
alert(year + '年是闰年');
} else {
alert(year + '年是平年');
}
- 能够被4整除并且不能被100整除的为闰年,或者能够被400整除的就是闰年; 判断整除的方法是取余为0
prompt()
弹出输入框提示用户输入年份,用户输入后,用year
变量进行保存- 用
if
判断year
是否满足为闰年条件,条件成立则执行if块
中的代码,条件不成立则执行else块
中的代码
2.3 if else if多分支条件语句
// 语法
if (条件表达式1) {
// 语句1;
} else if (条件表达式2) {
// 语句2;
} else if (条件表达式3) {
// 语句3;
} else {
// 以上条件都不成立执行此处代码
}
- 根据多个条件来选择不同的语句执行,得到不同的结果的过程(适用于多重条件
多选1
) - 若
条件表达式1
满足则执行语句1
,执行结束后退出整个if
分支语句 - 若
条件表达式1
不满足,则判断条件表达式2
,满足则执行语句2
,以此类推 - 若以上的条件表达式都不成立,则执行
else
里面的语句
示例:
/* 判断成绩级别案例:
接收用户输入的分数,根据分数输出对应的等级A、B、C、D、E。*/
var score = prompt('请输入您的分数:');
if (score >= 90) {
alert('A');
} else if (score >= 80) {
alert('B');
} else if (score >= 70) {
alert('C');
} else if (score >= 60) {
alert('D');
} else {
alert('E');
}
2.4 三元表达式
// 语法
条件表达式?表达式1:表达式2
- 条件表达式结果为
true
,则执行表达式1
,结果为false
,则执行表达式2
示例:
var num = 10;
var result = 5 > 10 ? 'YES' : 'NO';
alert(result); // NO
- 表达式是有返回值的,所以声明一个
result
变量进行接收
/* 数字前面补0案例:
提示用户输入数字(0~59),如果数字小于10,则在前面补0,如果数字大于10,则不需要补0
*/
var time = prompt('请输入0~59的数字:');
var result = time < 10 ? '0' + time : time;
alert(result);
- 在数字前面补0,使用到字符串拼接
2.5 switch多分支语句
// 语法
switch (表达式) {
case value1: // 表达式等于value1时执行的代码
执行语句1;
break;
case value2: // 表达式等于value2时执行的代码
执行语句2;
break;
...
default: // 表达式不等于任何value执行的代码
执行语句;
}
switch
也是多分支语句,它用于不同的条件来执行不同的代码。当要针对变量设置一系列的特定值case(选项)时,就可以使用switch。switch也是多选1
- 若表达式的值与
case
选项值匹配,则执行该case里面的语句,然后break
;若都没有匹配上则执行default
里的代码
示例:
switch (8) {
case 1:
alert('这是1');
break;
case 2:
alert('这是2');
break;
case 3:
alert('这是3');
break;
default:
alert('啥也不是');
}
- 以上代码switch的表达式是
8
,case选项值中并没有8,所以执行的是default
中的代码
switch的注意事项:
var num = 2;
switch (num) {
case 1:
console.log(1);
break;
case 2:
console.log(2);
case 3:
console.log(3);
break;
default:
console.log(0);
}
-
开发中表达式经常写成变量
-
表达式的值与
case
选项值进行匹配时,需要全等关系
(数值和数据类型都相同)才能匹配上,如这里的num === 2
-
break
特殊情况下才可以省略,如果当前的case里面没有break,则不会退出switch,而是继续执行下一个case,直到看到break才退出switch
/* switch查询水果案例:
用户输入水果名称,如果有就弹出警示框显示水果的价格,如果没有该水果就弹出没有此水果
*/
var fruit = prompt('请输入您要查询的水果:');
switch (fruit) {
case '苹果':
alert('苹果3.5元/斤');
break;
case '橘子':
alert('橘子4元/斤');
break;
case '雪梨':
alert('雪梨3元/斤');
break;
default:
alert('没有您要找的水果');
}
- 根据用户输入的水果名称匹配case中相应的选项值
switch
和if else if
的区别:
- 一般情况下, 他们两个语句可以互相替换;
- switch…case通常处理case为比较确定值的情况, 而if…else if语句更灵活, 常用于范围判断(大于、等于某个范围);
- switch语句进行条件判断后, 直接匹配执行到程序的条件语句, 效率更高, 而if…else if语句有多少种条件, 就要判断多少次;
- 当分支比较少时,if…else if语句的执行效率要比switch…case语句高;
- 当分支比较多时, switch语句的执行效率比较高, 而且结构更清晰;
3.循环结构
在实际问题中,有许多具有规律性的重复操作,使用循环结构可以避免重复编写相同的代码,因此在程序中要完成这类操作就要使用到循环语句。
在Javascript中,循环结构主要有: for循环
、while循环
、do while循环
。
3.1 for循环
// 语法
for(初始化变量;条件表达式;操作表达式) {
// 循环体
...
} -->
初始化变量
: 用var
声明的一个普通变量,通常作为计数器
使用条件表达式:
决定每一次循环是否继续执行,循环的终止条件
操作表达式
: 每次循环最后执行的代码,经常对初始化变量
进行更新(递增或递减)
示例:
for (var i = 1; i <= 100; i++) {
console.log('hello world!');
}
- 先执行初始化变量(
var i=1
),初始化变量在for循环中也就只执行一次 - 执行条件表达式(
i < =100
),若条件满足,则执行循环体,不满足则退出for
循环 - 最后执行
i++
执行完后第一轮结束 - 第二轮开始继续执行(
i <= 100
) …
for循环中嵌套if语句示例:
for (var i = 1; i <= 100; i++) {
if (i == 1) {
console.log('pan今年1岁,长得真可爱!');
} else if (i == 100) {
console.log('pan活到了100岁!')
} else {
console.log('pan今年' + i + '岁了'); // 关键就是使用了计数器变量i
}
}
- 以上示例中得到的结果都不相同。因为我们有计算器变量
i
的存在,每次循环i
的值都在变化
// for循环案例:
// 案例1. 求 1~100之间所有数的平均值(平均值 = 总数 / 个数) ,
var sum = 0 // 变量sum存总数和
var avg = 0 // 变量avg存平均值
for (var i = 1; i <= 100; i++) {
sum = sum + i;
}
avg = sum / 100;
console.log(avg);
// 案例2. 求1~100之间所有偶数的和与奇数的和(偶数:能被2整除的数,奇数:除了能被2整除的数)
var even = 0; // 变量even存储偶数的和
var odd = 0; // 变量odd存储奇数的和
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);
// 案例3. 求1~100之间所有能被3整除的数字的和(能被3整除的数: i%3==0 )
var result = 0; // 变量result存储能被3整除的数字的和
for (var i = 1; i <= 100; i++) {
if (i % 3 == 0) {
// result = result + i;
result += i;
}
}
console.log('1~100之间所有能被3整除的数字的和为:' + result);
// 案例4. 求班级中的总成绩和平均分
var sum = 0; // sum变量保存成绩之和
var avg = 0; // avg变量保存平均分
var num = prompt('班级人数为:');
for (var i = 1; i <= num; i++) { // 根据学生总人数来确定弹出输入框次数
var score = prompt('第' + i + '名学生的成绩为:');
sum += parseInt(score); // 计算总成绩
}
avg = sum / num; // 求平均分
alert('班级总成绩为:' + sum);
alert('班级平均分为:' + avg);
3.2 双重for循环
// 语法
for (外层初始化变量;外层条件表达式;外层操作表达式) {
// 外层执行语句
for (内层初始化变量;内层条件表达式;内层操作表达式){
// 内层执行语句
}
}
-
双重for循环我们可以把内层循环看做外层循环的语句外层循环一次,内层就循环一遍
-
内层for执行完后一遍后才到外层的第二轮
示例:
for (var i = 1; i <= 3; i++) {
console.log('执行外层循环的第' + i + '次');
for (var j = 1; j <= 3; j++) {
console.log('执行内层循环的第' + j + '次');
}
}
- 以上示例执行一次外层for时,内层for执行了三次,内层for执行完三次后,才开始进入外层for的第二次。
// 双重for循环的案例
// 案例1. 打印五行五列的星星
var str = ''
for (var i = 1; i <= 5; i++) { // 外层循环负责行数
for (j = 1; j <= 5; j++) { // 内层循环负责列数
str = str + '*';
}
str = str + '\n'; // 内层走一遍(一行上打印了五颗星)后换行
}
console.log(str);
// 案例2. 打印n行n列的星星
var rows = prompt('请输入要打印的行数:');
var cols = prompt('请输入要打印的列数:');
str = '';
for (var i = 1; i <= rows; i++) { // 根据用户输入的行数来作为条件表达式
for (var j = 1; j <= cols; j++) { // 根据用户输入的列数来作为条件表达式
str = str + '*';
}
str = str + '\n';
}
console.log(str);
// 案例3. 打印倒三角星星
var str = '';
for (var i = 1; i <= 10; i++) {
for (var j = i; j <= 10; j++) {
str = str + '*';
}
str = str + '\n';
}
console.log(str);
// 案例4. 打印正三角星星
var str = '';
for (var i = 1; i <= 10; i++) {
for (var j = 1; j <= i; j++) { // 条件表达式改成j <=i 即可
str = str + '*';
}
str = str + '\n';
}
console.log(str);
// 案例5. 打印九九乘法表
var str = '';
for (var i = 1; i <= 9; i++) {
for (var j = 1; j <= i; j++) {
str += j + 'x' + i + '=' + j * i + '\t';
}
str = str + '\n';
}
console.log(str);
3.3 while循环
// 语法
while(条件表达式) {
// 循环体
}
- 当条件表达式为
true
时,则执行循环体里代码,为false
时,跳出while循环
完整的while示例:
var num = 1; // 初始化变量(计数器)
while (num <= 100) { // 条件表达式
console.log('hello world!');
num++; // 操作表达式
}
- 以上完整的while循环中也有
初始化变量
(num
)和操作表达式(num++
) - while循环初始化变量声明在最前面,操作表达式写在循环体的最后面
- 操作表达式用于完成
初始化变量的更新
,如果没有操作表达式,while会进入死循环
// while循环案例:
// 案例1. 打印人的一生,1~100岁;
var i = 1;
while (i <= 100) {
console.log('pan今年' + i + '岁了');
i++;
}
// 案例2. 计算1~100所有的整数之和
var num = 1;
var sum = 0; // 变量sum用来保存整数之和
while (num <= 100) {
sum = sum + num;
num++;
}
console.log(sum);
3.4 do while循环
// 语法
do {
// 循环体;
} while (条件表达式)
- 先执行一次循环体代码,再判断条件,若条件为
true
,则继续执行循环体,若为false
,则退出循环
完整的do while示例:
var i = 1; // 初始化变量(计数器)
do {
console.log('hello world');
i++; // 操作表达式
} while (i <= 100) // 条件表达式
- do while是
先执行
,后判断
- 和while的区别就是 do while
至少执行一次
循环体代码
// do while循环案例:
// 1.打印人的一生,从1岁到100岁
var i = 1;
do {
console.log('pan今年' + i + '岁了');
i++;
} while (i <= 100)
// 2.计算1~100之间所有整数的和
var j = 1;
var sum = 0;
do {
sum += j;
j++;
} while (j <= 100)
console.log(sum);
在for循环,while循环和do while循环三者中,我们更常用的的是for循环。而当出现一些复杂的条件判断时,我们可以利用while和do while来做。
示例:
// 弹出一个警示框,提示你爱我吗?如果输入我爱你则结束,否则,一直询问。
// 1.使用while循环
var answer = prompt('你爱我吗?')
while (answer !== '我爱你') { // 判断条件
answer = prompt('你爱我吗?');
}
alert('我也爱你')
// 2. 使用do while循环
do {
answer = prompt('你爱我吗?');
} while(answer !== '我爱你') // 判断条件
alert('我也爱你')
- 以上例子判断条件比较复杂,我们可以使用while或do while来做
continue,break关键字的使用
在JavaScript中,continue
是一个控制语句,它的作用是跳过当前循环中的某些语句,直接进入下一次循环。break
关键字用于跳出整个循环语句,它可以使程序在满足某个条件时立即退出循环,执行循环后的语句。
continue示例:
// 有五个包子,吃完第一个继续吃第二个,吃到第三个的时候发现有虫,扔掉不吃了,继续吃后面还剩下的包子
for (var i = 1; i <= 5; i++) {
if (i == 3) {
console.log('有虫!不吃了');
continue;
}
console.log('正在吃第' + i + '个包子');
}
- continue退出本次循环,然后直接跳回到
i++
操作表达式上,继续执行下一次循环
break示例:
// 1.有五个包子,吃完第一个继续吃第二个,吃到第三个的时候发现有虫,剩下的都没有勇气吃了
for (var i = 1; i <= 5; i++) {
if (i == 3) {
console.log('有虫!吃个Der!');
break;
}
console.log('我正在吃第' + i + '个包子');
}
- break会退出整个循环语句
6.数组
变量只能存储一个数值,如果我们想存储多个数据,如(存储班级中所有的学生名字),这要怎么存储呢?我们可以通过使用数组(Arrays
)来进行存储。数组可以把一组相关的数据一起进行存放,并提供方便的访问(获取)方式。
数组是一组数据的集合
,其中的每个数据被称为元素
,在数组中可以存放任意类型
的数据。简单来说就是数组是一种将一组数据存储在单个变量名下的优雅方式。
1.创建数组的方式
JavaScript中创建数组的方式有两种: new Array()
创建、使用字面量
创建。
1.使用new Array()
方式创建数组
var 变量名 = new Array()
var arr = new Array(); // [] 创建一个空数组
var arr2 = new Array(5); // [empty×5] 创建长度为5的空数组
var arr3 = new Array(2,3) // [2,3]
- 参数为空时,创建了的是
空数组
。 - 参数是一个时表示创建了一个长度为5的空数组(empty×5)
- 参数为2个以上时,也就是
数组的初始化
,创建了相应的数组
2.使用字面量
方式创建数组
var 变量名 = []
var arr2 = []; // [] 创建一个空的数组
var arr3 = [1, 2, 3, 'pan', true]; // [1,2,3,'pan',true]
- 创建数组中我们较为常用的是字面量的方式创建数组
- 创建数组并带有元素时也称为
数组的初始化
2.获取数组元素
通过索引获取数组元素
数组名[索引名]
var arr = ['刘备', '关羽', '张飞'];
console.log(arr[0]); // 刘备
console.log(arr[1]); // 关羽
console.log(arr[2]); // 张飞
console.log(arr[3]); // undefined
- 数组是有索引下标的,下标从0开始
- 获取数组元素可以通过
数组名[索引名]
的方式 - 数组的索引为数组长度-1
3.遍历数组
遍历数组,就是把数组元素从头到尾的访问一次。
// 1.使用for循环遍历
var arr = ['刘备', '关羽', '张飞'];
for (var i = 0; i < 3; i++) {
console.log(arr[i]);
}
-
数组下标(索引),从0开始,所以计数器变量
i
必须从0开始 -
输出了
arr[i]
,i
计数器变量当作了数组的索引号来使用
4.获取数组的长度
在JavaScript中,可以通过数组对象的length
属性获取数组的长度。
数组名.length
var arr = [1,2,3,4,5];
console.log(arr.length) // 5
5.数组转换为字符串
// 使用 + 号拼接,隐式转换为字符串
var arr = ['red', 'green', 'blue'];
var str = '';
var split = '^'
for (var i = 0; i < arr.length; i++) {
str += arr[i] + split;
}
console.log(str);
- 以上例子中我们使用+号拼接的方式将数组转换为字符串,并且定义了split变量当作分隔符
6.新增数组元素
数组名[索引号] = 值
var arr2 = [1, 2, 3];
arr2[3] = 4; // 若原数组没有该索引号,则默认是追加数组元素
arr2[0] = 99; // 若原数组有该索引号,就直接把原数组的元素替换掉了
console.log(arr2); // [99,2,3,4]
- 使用
数组名[索引号] = 值
的方式,可以在原数组后面追加数组元素
7.函数
函数就是封装了一段可以被重复执行调用的代码块 目的: 就是让大量的代码能够重复的使用。
函数的封装: 函数的封装就是把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口。
1.函数的使用
在Javascript中函数在使用时分为两步:1.声明函数
2.调用函数
// 语法
function 函数名() {
// 函数体
}
示例:
// 1.声明函数
function sayHi() {
console.log('hello world!')
}
// 2.调用函数()
sayHi();
- 我们声明函数时,函数名使用动词
- 一个函数需要调用后才能被执行
/*
案例:
函数封装求和代码:求1~100的累加和
*/
// 1.声明函数
function getSum() {
var sum = 0;
for (var i = 0; i <= 100; i++) {
sum += i;
}
console.log(sum);
}
// 2.调用函数
getSum();
getSum();
2.函数的声明方式
函数的声明方式有两种: 1.利用函数关键字
2.利用函数表达式
1.利用函数关键字声明函数
function 函数名() {}
function fn1() {
console.log('hello world');
};
fn1();
- 利用关键字
function
声明的函数也称为自定义函数
2.利用函数表达式声明函数
var 变量名 = function() {}
var fun = function () {
console.log('hello world');
};
fun();
-
利用
函数表达式
声明的函数也叫匿名函数
-
fun
不是函数名,而是变量名
,所以这个funtion
是没有函数名的
2.函数的参数
JavaScript中函数的参数分为形参
和实参
两种。
形参
:在声明函数时设置的参数,用于接收实参传递过来的数据。形参可以没有,也可以有多个。
实参
: 在调用函数时设置的参数,用于将数据传递给函数里的形参。实参可以是变量,值,数组,对象等。
// 语法
function 函数名(形参1,形参2..) {
// 函数体
}
函数名(实参1,实参2);
示例:
// 利用函数求任意两个数的和
function getSum(num1, num2) {
console.log(num1 + num2);
}
var result = getSum(1, 2);
console.log(result) // 3
形参和实参的执行过程:
调用函数时, 会根据函数名返回去找到函数所在的位置,把实际参数传递给形式参数,形式参数接收到实际参数后,继续执行函数体里的代码。
函数形参实参个数匹配:
function getSum(num1, num2) {
console.log(num1 + num2)
}
// 1. 如果实参和形参个数一致 则正常输出结果
getSum(10, 20) // 30
// 2. 如果实参多于形参,也会传递到相应的形参个数,后面多出来的实参不参与
getSum(10, 10, 30); // 20
// 3. 如果实参少于形参,多余的形参会定义成undefined
getSum(10); // NaN
- 所以我们尽量让形参个数和实参个数匹配
3.函数的返回值
在函数中是有返回值的,我们需要得到返回的结果,函数的返回值可以通过return
语句返回。
// 语法
function 函数名() {
return //需要返回的结果
}
示例:
function getSum(num1, num2) {
return num1 + num2;
}
var result = getSum(10, 20) // result变量接收return的返回值
console.log(result); // 30
-
函数只是实现某种功能,最终的结果需要返回给函数的调用者,通过return 实现
-
只要函数遇到return,就会把return后面的结果返回给函数的调用者。
4.return的注意事项
1.return会终止函数的执行
function getSum(num1, num2) {
return num1 + num2;
alert('我是return后面的代码,我不会执行啦!');
}
console.log(getSum(1, 2)); // 3
- 函数中遇到return后就会直接返回return后面的值。
- return后面的代码alert不会被执行。
- return不仅可以退出循环,还能返回return语句中的值,同时还可以终止结束当前函数体代码。
2.return只能返回一个值
function getValue(num1, num2) {
return num1, num2;
}
console.log(getValue(1, 2)); // 2
- 当return后面有多个值是只会返回一个值,返回的是最后的一个值
如果要是我们想获得多个值,可以用return返回数组:
// 求任意两个数的加减乘除结果
function getResult(num1, num2) {
return [num1 + num2, num1 - num2, num1 / num2, num1 * num2];
}
var result = getResult(20, 10); // 返回得到的是一个数组
console.log(result); // [30,10,2,200]
如果我们想得到的结果不是数组,而是每个数据,可以将得到的结果进行遍历:
for (var i = 0; i < result.length; i++) {
console.log(result[i]);
}
3.函数体没有return,则返回的是undefined
function fun2() {
}
console.log(fun2()); // undefined
5.arguments的使用
JavaScript中的argument
是一个特殊的对象
,它包含了函数在调用时传入的所有参数。argument
对象是一个伪数组
对象,它有length
属性,也可以通过索引
访问每个参数的值。
1.arguments
是一个伪数组
function fun() {
console.log(arguments); // Arguments(0)
console.log(arguments.length) // 0
console.log(arguments[0]) // undefined
}
fun();
arguments
是伪数组,具有数组的length
属性、按照索引
的方式进行存储
2.arguments
能获取到传递过来的所有实参
function fun() {
console.log(arguments); // [1,2]
console.log(arguments.length) // 2
console.log(arguments[0]) // 1
}
fun(1,2);
argument
存储了所有传递过来的实参arguments
和数组的区别就是:它没有真正数组的一些方法,如push()
、pop()
等
当我们不确定用户传递过来的实参个数时,也不好确定形参个数,我们可以不声明形参,使用arguments
来获取到所有的实参:
// 求任意个数中的最大值
function getMax() {
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
console.log(getMax(1, 2, 3));
console.log(getMax(21, 33, 12, 45, 50));
只有函数才有arguments
对象,它是函数独有的内置对象。
6.函数之间的调用
每个函数都是独立的代码块,用于完成特殊的任务(功能),所以常会出现互相调用的情况,函数的调用可以通过函数名
加上括号
和参数来实现。
1.函数的调用
函数名()
function fn1() {
console.log(10);
fn2(); // 在函数fn1中调用了函数fn2
}
function fn2() {
console.log(20);
}
console.log(fn1());
2.函数调用的执行顺序
function fn1() {
console.log(111);
fn2();
console.log(666);
}
function fn2() {
console.log(222);
console.log(333);
}
var result = fn1(); // 调用fn1,回头找到fn1函数,执行fn1里的代码
console.log(result);
- 代码从上到下执行,先代用fn1(),然后回头找到fn1()函数,执行fn1()里的代码
- fn1()里面调用了fn2(),找到fn2()函数,执行fn2()的代码
- 函数执行完后,会返回到被调用处
8.作用域
javascript中的作用域: 就是代码名字(变量)在某个范围内起作用和效果目的就是为了提高程序的可靠性和减少命名冲突。
全局作用域
: 就是在整个<script>
标签中,或者是一个单独的js文件
中
局部作用域
: 也称为函数作用域,只在函数内部里有效果
1.全局变量和局部变量
全局变量
: 在全局作用域下的变量,在全局范围内都可以访问到
局部变量
: 在局部作用域(函数内)的变量,只能在函数内部能够访问到
1.全局变量
var num = 10;
console.log(num); // 10
funtion fn1() {
console.log(num)
}
fn1(); // 10
- 全局作用域下的变量(
num
)都可以被访问到
在函数内部没有声明而直接赋值的变量也属于全局变量:
function fn() {
num = 10;
}
fn();
num
变量在函数fn()
内,但是没有用var
进行声明,属于全局变量
2.局部变量
function fun() {
var num = 20;
console.log(num)
}
console.log(num); // 报错: num is not defined
console.log(fun()); // 20
- 局部作用域的变量(
num
)只在函数内部中才起作用,在函数外部是访问不到的
函数的形参也可以看做是局部变量:
function fn(agu) {
console.log(agu);
}
console.log(agu); // 报错: agu is not defined
fn(2); // 2
fn()
函数里的形参agu
可以看做是局部变量,在该函数外部也是访问不到的
小结:
全局作用域下的变量和局部作用域下的变量互不影响。
全局变量只有关闭了浏览器之后才会销毁,比较占内存资源。
局部变量是程序执行完毕就会销毁,比较节约内存。
2.作用域链
JavaScript中的作用域链是指在函数执行时,查找变量的顺序。当函数内部需要使用某个变量时,首先会在自身的作用域中查找,如果没有找到则会向上一级作用域查找,直到找到为止。如果最终仍然没有找到,则会返回undefined
。这个查找的过程就形成了作用域链。作用域链的顶端是全局作用域,最底层是当前函数的作用域。
作用域链
: 内部函数访问到外部函数的变量,采用到的就是链式查找
的方式。
示例:
var num = 10;
function fun() { // 外部函数
var num = 20;
function fn1() { // 内部函数
console.log(num);
}
fn1();
}
var result = fun();
console.log(result); // 20
- 以上得到的结果输出
num
的结果是20
,fn1()
函数先在当前作用域查找num
变量,没有则继续往上一层(fun()中
)查找,发现fun()
中有num
,就直接拿过来使用。
3.javascript中的预解析
- js引擎运行js分为两步: 1.预解析 2.代码执行
预解析
: js引擎会把js中所有的var和funtion(声明)提升到当前作用域的最前面代码执行
: 预解析完后,代码从上到下执行变量预解析
(变量提升
): 就是把所有的变量声明提示到当前作用域的最前面,不提升赋值操作函数预解析
(函数提升
): 就是把所有的函数声明提升到当前作用域的最前面,不提升调用操作
1.变量预解析
console.log(num); // undefined
var num = 10;
/*
var num; // 把变量声明提升到当前作用域最前面
console.log(num); // 所以是undefined
num = 10;
*/
- 以上代码中
num
的输出结果之所以为undefined
,就是根据js在代码执行前,先做了预解析 - 变量的预解析就是把变量声明提升到当前作用域最前面,然后代码还是按照原来从上到下的执行
2.函数预解析
函数关键字(自定义函数)
f1();
function f1() {
console.log(11); // 11
}
/*预解析过程:
function f1() { // 把函数声明提升到当前作用域的最前面
console.log(11)
}
f1(); // 所以是11
*/
- 以上自定义函数在js代码执行前,先通过了预解析,得到了正常的结果
表达式函数(匿名函数)
fun();
var fun = function () {
console.log(22); // fun is not a function
};
// 预解析:
var fun;
fun(); // 所以是fun is not a function
fun = function () {
console.log(22);
}
- 匿名函数中
fun
是变量而非函数名,把变量声明提升到当前作用域最前面,通过预解析后可以看到代码执行后得到的结果为fun is not a function
9.JavaScript中的对象
对象就是一个具体的事物,实实在在存在的事物。 在javascript中, 对象是一组无序的相关属性和方法的集合, 所有的事物都是对象, 例如字符串
、数值
、数组
、函数
等。
对象(object
)是复杂的数据类型,对象是由属性
和方法
组成的。
属性
: 事物的特征,在对象中用属性来表示(常用名词)方法
: 事物的行为,在对象中用方法来表示(常用动词)
为什么需要对象?
- 保存一个数值时,可以使用变量,保存一组值时,可以使用数组,那么如果保存一个人的完整信息呢?
- 例如将一个张三的信息用数组来表示:
arr = ['张三','男',18,170,52]
; 后面的数值给人是模糊的,表达不出来。 - 而使用对象,表达结构更清晰。例如张三的个人信息在对象中来表达结构,如:
person.name = '张三';
person.sex = '男';
person.age = 18;
1.对象的创建方式
1.1 字面量创建对象
var 对象名 = {}
// var obj = {} 表示创建了一个空对象
// 1.创建对象
var obj = {
uname: '张三',
sex: '男',
age: 18,
sayhello: function () {
console.log('helloworld');
}
}
// 2.调用对象
console.log(obj.uname); // 张三
console.log(obj['sex']); // 男
console.log(obj.sayhello()); // helloworld
- 对象中属性和方法都用键值对(
键:值
)的方式来表示,每个属性或方法都以键:值
号进行分隔 - 使用
对象名.方法名 = function(){}
这种方式给对象添加方法 - 方法(
sayhello
)后面跟的function()
是一个匿名函数 - 使用对象时需要:1.创建对象 2.调用对象
- 调用对象的属性有两种方式: 1.
对象名.属性名
2.对象名['属性名']
- 调用对象的方法:
对象名.方法名()
/* 使用字面量方式创建对象案例 */
//1.创建对象
var dog = {
dname: '二狗子',
type: '哈士奇',
age: 5,
color: '黑白色',
bark: function () {
console.log('汪汪汪~~~');
},
showFilm: function () {
console.log('演电影~~~')
}
}
// 2.调用对象
// (1)使用属性
console.log(dog.dname);
console.log(dog.type);
console.log(dog['age']);
console.log(dog['color']);
// (2)使用方法
dog.bark();
dog.showFilm();
变量和属性的区别:
var num = 10; // 变量num
var obj = {
age: 18 // 属性age
}
console.log(num); // 变量num的使用
console.log(obj.age); // 属性age的使用
-
相同点: 都是用来
存储数据
的。 -
不同点: 变量
单独声明
并赋值,使用的时候直接写变量名
。属性写在对象里面的,不需要声明
,使用的时候对象名.属性名
函数和方法的区别:
function fun() { // 函数fun
console.log(111);
}
fun(); // 函数fun的调用
var obj = {
action: function () { // 方法action
console.log(222);
}
}
obj.action(); // action的调用
-
相同点: 都是
实现
某种功能
的。 -
不同点: 函数都是
单独声明
并且调用的, 使用时直接调用函数名()
。方法是写在对象里的, 调用时对象名.方法()
1.2 new Object创建对象
var 对象名 = new Object()
var obj = new Object(); // 创建了一个空对象
// 1.创建对象
var obj = new Object();
obj.uname = '张三';
obj.sex = '男';
obj.age = 18;
obj.sayHello = function () {
console.log('HelloWorld');
}
// 2.调用对象
console.log(obj.uname); // 张三
console.log(obj['sex']); // 男
console.log(obj.sayHello); // HelloWorld
-
使用
对象名.属性名 = 属性值
这种方式给对象添加属性 -
使用
对象名.方法名 = function(){}
这种方式给对象添加方法 -
每个属性或者方法之间都是使用
;
号进行分隔
/* 使用new Object创建对象案例 */
// 1.创建对象
var person = new Object();
person.uname = '鸣人';
person.sex = '男';
person.age = 18;
person.skill = function () {
console.log('影分身术');
}
// 2.使用对象
console.log(person.uname);
console.log(person.sex);
console.log(person['age']);
person.skill();
1.3 构造函数创建对象
- 在JavaScript中,可以使用构造函数来创建对象。构造函数就像一个模板,定义了对象的属性和方法。
- 当使用
new
关键字创建一个新对象时,就会调用该构造函数,并返回一个新的对象实例
。通过构造函数,可以创建多个相似的对象,每个对象的属性和方法都是独立的。 - 使用
字面量
和new Object()
的方式创建对象一次只能创建一个对象,而使用构造函数创建对象可以创建多个对象实例。
构造函数
: 就是用来把我们对象里面一些公共的属性和方法抽取出来封装到该函数里面。
// 语法
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);
}
}
// 1.new 构造函数()创建对象
var zjl = new Star('周杰伦',40,'男')
// 2.使用对象
console.log(zjl.name); // 周杰伦
console.log(zjl['age']); // 40
console.log(zjl.sing('一路向北')); // 一路向北
- 使用构造函数创建对象,使用new 构造函数名(
new Star()
)的方式就能得到一个对象(zjl
),括号里面写的是实参,实参传递给构造函数里的形参 - 构造函数里面的属性和方法必须使用
this
,表示当前对象
- 构造函数不需要
return
就可以返回结果 - 利用构造函数
new
出来的对象也称为对象的实例化,这里得到了一个zjl
实例
构造函数和对象的联系:抽象了对象的公共部分,封装到了函数里面,它泛指一大类。对象特指一个具体事物,而构造函数类似一个模板,有了模板就可以创建多个对象实例。
/* 用构造函数创建英雄联盟里的英雄对象案例 */
function Zero(uname, type, blood) {
this.name = uname;
this.type = type;
this.blood = blood;
this.attrack = function (attrack) {
console.log(attrack);
}
}
// 对象1
var lianpo = new Zero('熔岩巨兽', '坦克', 600);
console.log(lianpo.name);
console.log(lianpo.type);
console.log(lianpo['blood']);
lianpo.attrack('近战攻击');
// 对象2
var houyi = new Zero('伊泽瑞尔', '射手', 200);
console.log(houyi.name);
console.log(houyi.type);
console.log(houyi['blood']);
houyi.attrack('远程攻击');
new关键字的执行过程
在JavaScript中,使用new
关键字创建一个对象时,会执行以下步骤:
1.在内存中创建一个新的空对象
2.让this
指向这个新对象
3.执行构造函数里的代码,给这个新对象添加属性和方法
4.返回这个新对象(所以构造函数不需要return)
2.对象的遍历
for 变量 in 对象
var obj = {
name: '张三',
sex: '男',
age: 18,
skill: function () {
}
}
for (var k in obj) {
console.log(k); // name sex age skill
console.log(obj[k]); // '张三' '男' 18
}
- 使用
for..in
的方式遍历对象,可以获取到对象的属性
/方法
- 直接使用
k
的方式得到的是对象中的属性名
- 使用
obj[k]
的方式得到的是对象中的属性值 k
就是一个普通的变量,我们使用for..in
时,变量喜欢用k
或者key
来表示
10.内置对象
JavaScript中的内置对象是指在JS引擎中已经预定义好的一些对象,包括全局对象
、基本数据类型的包装对象
和一些常用的工具类对象
,如数学对象Math
、数组对象Array
等。
- javascirpt中的对象分为3种:
自定义对象
、内置对象
、浏览器对象
。 - 前面两种对象是js基础内容, 属于ECMAScript; 第三个浏览器对象属于我们js中独有的。
- 内置对象就是指js语言中自带的一些对象, 这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能。
- 内置对象最大的优点就是帮助我们快速开发。
- javascirpt中提供了多个内置对象如:
Math
、Date
、Array
、String
等
1.Math内置对象
Math数学对象,不是一个构造函数,所以我们不需要new来调用,直接使用Math.属性
/Math.方法
的方式获取Math对象中的属性/方法。
1.Math获取圆周率属性
Math.PI
console.log(Math.PI); // 3.141592653589793
2.Math获取最大/最小值
Math.max()
/Math.min()
console.log(Math.max(1, 50, 20)); // 50
console.log(Math.min(-10, -1, -5)); // -10
console.log(Math.max(5, 6, - 1, 'a')); // NaN
console.log(Math.max()); // -Infinity
console.log(Math.min()) // Infinity
Math.max()
可以获取到最大值,Math.min()
可以获取到最小值- 如果任一参数不能转换为数值,如:
'a'
,则返回NaN
max()
参数为空时得到的结果是-Infinity
min()
参数为空时得到的结果是Infinity
我们也可以封装自己的数学对象,如:
// 利用对象封装自己的数学对象,里面有PI属性,max方法,min方法
var myMath = {
PI: 3.1415926, // PI属性
max: function () { // max方法
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
},
min: function () { // min方法
var min = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] < min) {
min = arguments[i];
}
}
return min;
}
}
console.log(myMath.PI);
console.log(myMath.max(5, 9, 20, 5));
console.log(myMath.min(10, 20, 30));
2.Math取绝对值方法
Math.abs()
// 1.Math绝对值方法 Math.abs()
console.log(Math.abs(1)); // 1
console.log(Math.abs(-1)); // 1
console.log(Math.abs('-1')); // 1 隐式转换
console.log(Math.abs('a')); // NaN
console.log(Math.abs()); // NaN
Math.abs()
可以获取到绝对值,当任一参数不能转换为数值或为空时,得到NaN
3.Math取整方法
Math取整方法有三种: 向下取整Math.floor()
、向上取整Math.ceil()
、四舍五入Math.round()
// 1.Math.floor()
console.log(Math.floor(1.1)); // 1
console.log(Math.floor(1.5)); // 1
console.log(Math.floor(1.9)); // 1
console.log(Math.floor(-1.1)); // -2
console.log(Math.floor(-1.9)); // -2
// 2.Math.ceil()
console.log(Math.ceil(1.1)); // 2
console.log(Math.ceil(1.9)); // 2
console.log(Math.ceil(-1.1)); // -1
console.log(Math.ceil(-1.9)); // -1
// 3.Math.round()
console.log(Math.round(1.1)); // 1
console.log(Math.round(1.5)); // 2
console.log(Math.round(-1.5)); // -1 .5比较特殊 它是往大的取
console.log(Math.round(-1.6)); // -2
4.Math取随机数的方法
Math.random()
console.log(Math.random());
Math.random()
这个方法里面不跟参数Math.random()
在[0,1)
这个区间内取随机的小数
我们想要得到两个数之间的随机整数并且包含这两个整数:
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var rand = getRandom(1, 10); // [1,10]中取到随机数
console.log(rand);
- 在我们定义的
getRandom()
中返回了Math.floor(Math.random() * (max - min + 1)) + min
公式 - 这个公式可以得到两个数之间的随机整数并且包含这两个整数
/* 使用Math.random()做一个随机点名案例 */
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var arrName = ['刘备', '关羽', '张飞', '赵云', '马超', '黄忠', 'pancc'];
var getRandName = arrName[getRandom(0, arrName.length - 1)];
console.log(getRandName);
2.Date日期对象
JavaScript中的日期对象Date()
是一种用于处理日期和时间的内置对象。它可以表示日期和时间,以毫秒为单位,从1970年1月1日起算。
日期对象Date()
是一个构造函数,要使用必须要new
来实例化日期对象
。
1.创建日期对象
new Date()
// 1.new Date() 空参
var date = new Date();
console.log(date); // Tue Mar 28 2023 18:08:40 GMT+0800 (中国标准时间)
// 2.new Date(数字)
var date1 = new Date(2018, 11, 13); // Thu Dec 13 2018 00:00:00
console.log(date1);
// 3.new Date(字符串)
var date2 = new Date('2018-11-13 8:8:8'); // Tue Nov 13 2018 08:08:08 GMT+0800
console.log(date2);
-
使用
new Date()
实例化日期对象,参数为空时返回当前系统的时间
-
参数是数字的时候,返回的月份要比我们传递的日期参数的月份大一个月
-
参数是字符串的时候,返回得到的和我们传递的日期参数一样
2.日期格式化
// 格式化日期 年 月 日
var date = new Date();
console.log(date.getFullYear()); // 2023
console.log(date.getMonth() + 1); // 3
console.log(date.getDate()); // 22
console.log(date.getDay()); // 3
getFullYear()
:返回当前日期的年getMonth()
:返回当前日期的月(月份默认是0-11),所以比我们实际的少1,所以我们+1即可getDate()
:返回当前日期的日getDay()
:返回当前日期的周(周默认是0~6,星期天是0)
/* 使用日期格式化,写一个 2023年3月22日 星期三 的案例 */
var year = date.getFullYear();
var month = date.getMonth() + 1;
var dates = date.getDate();
var day = date.getDay();
var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
console.log(year + '年' + month + '月' + dates + '日 ' + arr[day]); // 今天是2023年2月22日星期三
3.时分秒格式化
var date = new Date();
console.log(date.getHours()); // 时
console.log(date.getMinutes()); // 分
console.log(date.getSeconds()); // 秒
getHours()
:返回当前时间的时
getMinutes()
: 返回当前时间的分
getSeconds()
: 返回当前时间的秒
/* 使用时分秒格式化,得到一个时间格式为 08:08:08 */
// 封装一个函数返回当前的时分秒,格式:08:08:08
function getTimer() {
var date = new Date();
var h = date.getHours();
h = h < 10 ? '0' + h : h; // 小于10则在前面加0
var m = date.getMinutes();
m = m < 10 ? '0' + m : m;
var s = date.getSeconds();
s = s < 10 ? '0' + s : s;
return h + ':' + m + ':' + s;
}
var time = getTimer();
console.log(time);
4.获得Date的总毫秒数
// 1. 使用valueOf()、getTime()的方式
var date = new Date();
console.log(date.valueOf());
console.log(date.getTime());
// 2. 使用+new的方式(常用)
var date = +new Date(); // new前面加上+号
console.log(date);
// 3.H5新增的方式 Date.now()
console.log(Date.now()); // 不用new,直接Date.now()
- 获得
Date
的总的毫秒数(时间戳),也就是当前时间距离1970年1月1日的总毫秒数
3.Arrays内置对象
1.检测是否为数组的方法
Array.isArray(参数)
var arr2 = [];
var arr3 = {};
console.log(Array.isArray(arr2)); // true
console.log(Array.isArray(arr3)); // false
- 使用
Array.isArray(参数)
可以判断是否为数组,是则返回true
,否则返回false
除了使用Array.isArray(参数)
方法判断是否为数组外,我们也可以使用关键字instance of
:
var arr2 = [];
var arr3 = {};
console.log(arr2.instance of Array); // true
console.log(arr3.instance of Array); // false
2.添加数组元素的方法
(1)push(参数)
var arr = [1, 2, 3];
console.log(arr.push(4, 5)); // 5
console.log(arr); // [1,2,3,4,5]
push()
在原数组末尾添加一个或多个元素push()
执行完返回的是新数组长度,会改变原数组
(2) unshift(参数)
var arr = [4, 5, 6];
console.log(arr.unshift(1)); // 4
console.log(arr); // [1,4,5,6]
-
unshift()
在原数组前面添加一个或多个元素 -
unshift()
执行完返回的是新数组长度,会改变原数组
3.删除数组元素的方法
(1)pop()
// 1.pop()
var arr = [1, 2, 3, 'abc'];
console.log(arr.pop()); // abc
console.log(arr); // [1,2,3]
// 2.shift()
pop()
删除数组的最后一个元素pop()
执行完返回的是被删除的数组元素,会改变原数组
(2) shift()
var arr = ['abc', 4, 5, 6];
console.log(arr.shift()); // abc
console.log(arr); // [4,5,6]
-
shift()
删除数组的第一个元素 -
shift()
执行完返回的是被删除的数组元素,会改变原数组
4.数组的排序
(1) 翻转数组
reverse()
var arr = ['a', 'b', 'c'];
arr.reverse();
console.log(arr); // ['c','b','a']
- 使用
reverse()
方法可以将数组元素进行翻转
(2) 数组的升序
sort(function(参数a,参数b)) { return }
var arr = [3, 7, 1, 11, 13, 9, 5];
arr.sort(function (a, b) {
return a - b;
});
console.log(arr); // [1,3,5,7,9,11,13]
- 使用
soft()
方法,返回a - b
时,得到的数组是升序
排列
(3)数组的降序
sort(function(参数a,参数b)) { return }
var arr = [3, 7, 1, 11, 13, 9, 5];
arr.sort(function (a, b) {
return b - a;
});
console.log(arr); // [13,11,9,7,5,3,1]
- 使用
soft()
方法,返回b-a
时,得到的数组是降序
排列
5.获取数组的索引方法
(1) indexOf(数组元素)
var arr = ['red', 'green', 'blue', 'blank', 'blue'];
console.log(arr.indexOf('blue')); // 2
console.log(arr.indexOf('orange')); // -1
-
indexOf(数组元素)
从前往后查找,返回该数组元素的索引号 -
使用
indexOf(数组元素)
时,若数组中有一样的元素,则返回的是第一个数组元素,若数组中无此元素,则返回 -1
(2) lastIndexOf(数组元素)
var arr = ['red', 'green', 'blue', 'blank', 'blue'];
console.log(arr.lastIndexOf('blue')); // 4
console.log(arr.indexOf('orange')) // -1
-
lastIndexOf(数组元素)
从后往前查找,返回该数组元素的索引号 -
使用
indexOf(数组元素)
时,若数组中有一样的元素,则返回的是第一个数组元素,若数组中无此元素,则返回 -1
6.数组去重
目标: 把旧数组中不重复的元素选出来放到新数组中,如果有重复的元素也只保留一个,放到新数组中去重
- 核心算法: 我们遍历旧数组。然后拿着旧数组元素去查新数组,如果该元素在新数组中没有出现过,新数组就添加该元素,否则不添加
- 我们怎么知道该元素有没有存在? 利用
新数组.indexOf(数组元素)
,如果返回-1,则说明新数组里面没有该元素,然后依次添加到新数组中,就可以得到不重复的新数组元素。
// 定义一个数组去重的函数
function unique(arr) {
var newArr = []; // 创建一个空的新数组
for (var i = 0; i < arr.length; i++) { // 遍历旧数组
if (newArr.indexOf(arr[i]) === -1) { // 新数组使用indexOf()方法判断自己是否有这个元素,=== -1则是没有
newArr.push(arr[i]); // 添加数组元素到新数组中
}
}
return newArr;
}
var result = unique(['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b', 'd']);
console.log(result);
7.数组转换为字符串
(1)toString()
var arr = [1, 2, 3];
console.log(arr.toString()); // 1,2,3
toString()
直接将数组转换为字符串
(2)join(分隔符)
var arr1 = [4, 5, 6];
console.log(arr1.join()); // 4,5,6
console.log(arr1.join('-')); // 4-5-6
join(分隔符)
将数组转换为字符串的同时添加分隔符,若join()
中的参数为空,则默认以,
号分隔
8.合并和截取数组的方法
(1) 合并数组
concat()
var arr1 = ['a', 'b', 'c'];
var arr2 = ['d', 'e', 'f'];
var arr3 = ['g', 'h', 'i'];
console.log(arr1.concat(arr2)); // [a,b,c,d,e,f];
console.log(arr1.concat(arr2, arr3)); // [a,b,c,d,e,f,g,h,i] 个
console.log(arr1); // [a,b,c]
concat()
合并两个或者多个数组,返回一个新数组,并不会改变原数组
(2)截取数组
slice(begin,end)
var arr = ['red', 'green', 'blue', 'pink', 'blank'];
console.log(arr.slice(1, 4)); // ['green', 'blue', 'pink']
console.log(arr); // ['red', 'green', 'blue', 'pink', 'blank']
slice()
截取数组,begin
参数表示从第几个开始,end
表示取多少个slice()
截取到的数组是左闭右开
的区间,即包含begin
,不包含end
slice()
返回被截取项目的新数组,并不会改变原数组
(3) 截取数组(将截取到的数组删除)
splice(start, deleteCount)
var arr5 = [1, 2, 3, 4, 5];
console.log(arr5.splice(1, 4)); // [2,3,4,5]
console.log(arr5); // 1
splice()
截取数据,start
表示从第几个开始,deleCount
表示要截取(删除)的个数spilce()
截取到的数组是闭区间,即包含start
也包含deleCount
slice()
返回被截取(删除)项目的新数组,会改变原数组
4.String内置对象
1.基本包装类型
JavaScript中的包装类型有三种:Number
、String
和Boolean
,可以包装成复杂数据类型。
简单数据类型包装成了复杂数据类型就可以有属性和方法,使用包装类型目的就是为了方便将操作简单数据类型。
如String有包装类型,所以它可以有length:
// string 简单数据类型
var str = 'abcd';
console.log(str.length); // 4
2.字符串的不可变性
在 JavaScript 中,字符串是不可变
的,这意味着一旦一个字符串被创建,它就不能被修改。当对字符串进行任何修改时,实际上是创建了一个新的字符串对象,而不是在原来的字符串上进行修改。
var str = 'abc';
console.log(str); //abc
str = '123';
// 当
// 重新给字符串赋值,
console.log(str); // 123
- 重新给
str
赋值的时候,其实’abc’不会被修改,'abc’还是会保存在内存中,而内存会重新开辟一个新的空间,str
重新指向了这个空间,这个特点就是字符串的不可变性 - 表面上看
str
的内容是改变了,但实际上是地址变了,在内存中又开辟了新的空间,变量指向当前的地址 - 我们要尽量的避免使用大量的字符串进行拼接,因为字符串进行拼接(重新赋值)一次,内存中就多开辟了一个空间。
3.查找字符串位置的方法
(1)indexOf(要查找的字符,起始位置)
var str = '改革春风吹满地,春天来啦';
console.log(str.indexOf('春')); // 2
console.log(str.indexOf('春', 3)) // 8
indexOf()
第一个参数表示要查找的字符,第二个参数表示起始位置indexOf()
是从前面开始查找,只会查找到第一次出现的字符- 如果查不到则返回-1
(2)lastIndexOf(要查找的字符,起始位置)
var str = '改革春风吹满地,春天来啦';
console.log(str.lastIndexOf('春')); // 8
lastIndexOf
和indexOf()
的用法相同,区别lastIndexOf()
是从后面开始查找
4.根据索引返回字符串
(1) charAt(index)
var str = 'pan';
console.log(str.charAt(0)); // p
charAt(index)
根据索引号,返回指定位置的字符
(2) charCodeAt(index)
var str = 'abcd'
console.log(str.charCodeAt(0)); // 97
charCodeAt(index)
根据索引号,返回指定位置字符的ASCII码charCodeAt(0)
查找到的是'a'
字符,a的ASCII编码是97
(3) str[index]
var str = 'abcd'
console.log(str[0]); // a
str[index]
是h5新增的方式,根据索引号,返回指定位置的字符
5.字符串合并与截取
(1) 字符串合并
concat(str1,str2…)
var str1 = 'pan';
console.log(str1.concat(' is very good')); // pan is very good
- 使用
concat()
可以将多个字符串进行合并,相当于字符串的+
号拼接
(2)字符串截取
substr(start,length)
var str2 = '改革春风吹满地';
console.log(str2.substr(2, 3)); // 春风
substr()
截取字符串,start
表示从第几个开始,length
表示取几个字符substr()
截取字符串是得到闭区间,包含start
也包含length
slice(start,end)
var str2 = '改革春风吹满地';
console.log(str2.slice(2, 3)); // 春
slice()
截取字符串,start表示从第几个开始,end
表示到第几个结束slice()
截取字符串是得到左闭右开区间,包含start
但是不包含end
substring(start,end)
var str2 = '改革春风吹满地';
console.log(str2.substring(2, 3)); // 春
substring
和slice()
用法基本相同,区别是它不接受负值
6.字符串的替换
replace(要替换的字符,替换后的字符)
var str1 = 'pan';
console.log(str1.replace('p', 'P')); // Pan
replace()
可以将字符串进行替换,只会将第一个出现的字符进行替换
7.字符串转换为数组
split(‘分割符’)
var str3 = 'a,b,c,d,e';
console.log(str3.split(',')); // [a,b,c,d,e] 以,号进行分割
var str4 = 'a&b&c&d&e';
console.log(str4.split('&')); // [a,b,c,d,e ] 以&进行分割
split()
可以将字符串转换为数组,参数的分割符表示要以什么符号进行分割
8.字符串转换为大小写
// 1.toUpperCase() 字符串转换为大写
var str = 'pancc';
console.log(str.toUpperCase()); // PANCC
// 2.toLowerCase() 字符串转换为小写
var str2 = 'PaNcc';
console.log(str.toLowerCase()); // pancc
简单数据类型和复杂数据类型的内存分配:
简单数据类型
: 在内存中是存放在栈
中,里面直接开辟了一个空间然后存放的是值
。
复杂数据类型
: 首先在栈
里面存放的是地址值(16进制表示)
,然后这个地址指向了堆
里面的数据
。
unt`
slice()
返回被截取(删除)项目的新数组,会改变原数组
4.String内置对象
1.基本包装类型
JavaScript中的包装类型有三种:Number
、String
和Boolean
,可以包装成复杂数据类型。
简单数据类型包装成了复杂数据类型就可以有属性和方法,使用包装类型目的就是为了方便将操作简单数据类型。
如String有包装类型,所以它可以有length:
// string 简单数据类型
var str = 'abcd';
console.log(str.length); // 4
2.字符串的不可变性
在 JavaScript 中,字符串是不可变
的,这意味着一旦一个字符串被创建,它就不能被修改。当对字符串进行任何修改时,实际上是创建了一个新的字符串对象,而不是在原来的字符串上进行修改。
var str = 'abc';
console.log(str); //abc
str = '123';
// 当
// 重新给字符串赋值,
console.log(str); // 123
- 重新给
str
赋值的时候,其实’abc’不会被修改,'abc’还是会保存在内存中,而内存会重新开辟一个新的空间,str
重新指向了这个空间,这个特点就是字符串的不可变性 - 表面上看
str
的内容是改变了,但实际上是地址变了,在内存中又开辟了新的空间,变量指向当前的地址 - 我们要尽量的避免使用大量的字符串进行拼接,因为字符串进行拼接(重新赋值)一次,内存中就多开辟了一个空间。
3.查找字符串位置的方法
(1)indexOf(要查找的字符,起始位置)
var str = '改革春风吹满地,春天来啦';
console.log(str.indexOf('春')); // 2
console.log(str.indexOf('春', 3)) // 8
indexOf()
第一个参数表示要查找的字符,第二个参数表示起始位置indexOf()
是从前面开始查找,只会查找到第一次出现的字符- 如果查不到则返回-1
(2)lastIndexOf(要查找的字符,起始位置)
var str = '改革春风吹满地,春天来啦';
console.log(str.lastIndexOf('春')); // 8
lastIndexOf
和indexOf()
的用法相同,区别lastIndexOf()
是从后面开始查找
4.根据索引返回字符串
(1) charAt(index)
var str = 'pan';
console.log(str.charAt(0)); // p
charAt(index)
根据索引号,返回指定位置的字符
(2) charCodeAt(index)
var str = 'abcd'
console.log(str.charCodeAt(0)); // 97
charCodeAt(index)
根据索引号,返回指定位置字符的ASCII码charCodeAt(0)
查找到的是'a'
字符,a的ASCII编码是97
(3) str[index]
var str = 'abcd'
console.log(str[0]); // a
str[index]
是h5新增的方式,根据索引号,返回指定位置的字符
5.字符串合并与截取
(1) 字符串合并
concat(str1,str2…)
var str1 = 'pan';
console.log(str1.concat(' is very good')); // pan is very good
- 使用
concat()
可以将多个字符串进行合并,相当于字符串的+
号拼接
(2)字符串截取
substr(start,length)
var str2 = '改革春风吹满地';
console.log(str2.substr(2, 3)); // 春风
substr()
截取字符串,start
表示从第几个开始,length
表示取几个字符substr()
截取字符串是得到闭区间,包含start
也包含length
slice(start,end)
var str2 = '改革春风吹满地';
console.log(str2.slice(2, 3)); // 春
slice()
截取字符串,start表示从第几个开始,end
表示到第几个结束slice()
截取字符串是得到左闭右开区间,包含start
但是不包含end
substring(start,end)
var str2 = '改革春风吹满地';
console.log(str2.substring(2, 3)); // 春
substring
和slice()
用法基本相同,区别是它不接受负值
6.字符串的替换
replace(要替换的字符,替换后的字符)
var str1 = 'pan';
console.log(str1.replace('p', 'P')); // Pan
replace()
可以将字符串进行替换,只会将第一个出现的字符进行替换
7.字符串转换为数组
split(‘分割符’)
var str3 = 'a,b,c,d,e';
console.log(str3.split(',')); // [a,b,c,d,e] 以,号进行分割
var str4 = 'a&b&c&d&e';
console.log(str4.split('&')); // [a,b,c,d,e ] 以&进行分割
split()
可以将字符串转换为数组,参数的分割符表示要以什么符号进行分割
8.字符串转换为大小写
// 1.toUpperCase() 字符串转换为大写
var str = 'pancc';
console.log(str.toUpperCase()); // PANCC
// 2.toLowerCase() 字符串转换为小写
var str2 = 'PaNcc';
console.log(str.toLowerCase()); // pancc
简单数据类型和复杂数据类型的内存分配:
简单数据类型
: 在内存中是存放在栈
中,里面直接开辟了一个空间然后存放的是值
。
复杂数据类型
: 首先在栈
里面存放的是地址值(16进制表示)
,然后这个地址指向了堆
里面的数据
。