前情回顾:网页布局
JavaScript
简介
avaScript诞生于1995年,它的出现主要是用于处理网页中的前端验证。所谓的前端验证,就是指检查用户输入的内容是否符合一定的规则。比如:用户名的长度,密码的长度,邮箱的格式等。但是,有的同学可能会有疑问,这些验证,后端不也可以进行验证吗?确实,后端程序的确可以进行这些验证,但你要清楚,在1995年那个年代,网速是非常慢的,向后端发送一个请求,浏览器很久才能得到响应,那这无疑是一种非常不好的用户体验。
为了解决前端验证的问题,当时的浏览器巨头NetScape(网景)公司就开发出一种脚本语言,起初命名为LiveScript,后来由于SUN公司的介入更名为了JavaScript。
详细情况可以看up主轻松的小希的文章点击简介即可打开
常见情况
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- <script src="./index.js"></script> -->
</head>
<body>
<!-- 引入方式 -->
<script>
console.log('hello Javascrpit');
prompt();
/*
输入和输出
输出有三种方式:alert()
document.write('要输出的内容');
console.log('要输出的内容')
输入:prompt("")
*/
</script>
<!-- <script src="./index.js"></script> -->
</body>
</html>
根据代码学语言:从此段代码中可以看出,JavaScript的书写形式是包含在<script></script>
标签当中的。
引入方式有两种:
- 在
<head></head>标签
当中引入,方式<script src="./index.js"></script>
- 在
<body></body>标签
当中引入,方式在这里插入代码片<script> console.log('hello Javascrpit'); prompt(); </script>
javascript的组成
JavaScript的输出
其输出的输出方式有三种:页面、控制台、弹出窗口
- 页面
<script>
document.write("Hello,World!");
</script>
- 控制台
摁F12,可以在网页中调出控制台
<script>
console.log("输出一条日志");//最常用
console.info("输出一条信息");
console.warn("输出一条警告");
console.error("输出一条错误");
</script>
- 弹出窗口
<script>
alert("Hello,World!");
</script>
基础语法
变量
变量的声明有三个关键字 var、const、let
var message = "hi",
found = false,
age = 29;
var message;
console.log(message); //不初始化的情况下,变 量会保存一个特殊值 undefined
var 声明提升(变量提升)
声明提升 也就是把所有变量声明都拉到函数作用域的顶部。此外,反复多次使用 var 声明同一个变量也没有问题
function foo() {
var age = 16;
var age = 26;
var age = 36;
console.log(age);
}
foo();
let 声明
// if (true) {
// var message = ‘Matt’;
// console.log(message);
// let age = 18;
// console.log(age);
// }
// console.log(message);
// console.log(age);
块作用域 是函数作用域的子集,因此适用于 var 的作用域限制同样也适用于 let。
var与left的区别:
let 声明的范围是块作用域, 而 var 声明的范围是函数作用域。
let 声明的变量不会在作用域中被提升。
使用 let 在全局作用域中声明的变量不会成为 window 对象的属性(var 声明的变量则会)。
for循环中的let声明
for循环中var声明的迭代变量会渗透到循环体外部
for (var j = 0; j < 5; j++) {
}
console.log(j);
for (let i = 0; i < 5; i++) {
}
console.log(i)
const声明
注:const 的行为与 let 基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改 const 声明的变量会导致运行时错误。
数据类型
Js中的数据类型总共有七种:undefined、Boolean、null、Number、String、Symbol和Object。Symbol(符号)是 ECMAScript 6 新增的。
-
布尔类型 只有2个值:ture和false let isTure = false; console.log(isTure);
-
字符串类型String 被单引号或者双引号包裹的值 let name = “Js”; console.log(name);
-
typeof:判断数据类型(判断基本数据类型) console.log(typeof message);
console.log(typeof(isTure)); console.log(typeof 36); -
undefined Undefined 类型只有一个值,就是特殊值 undefined。当使用 var 或 let 声明了变量但没有初始 化时,就相当于给变量赋予了 undefined 值可以直接给一个变量赋值为 undefined,但是没有必要。对一个未声明的变量,只能执行一个有用的操作–typeof。undefined 是一个假值。因此,如果需要,可以用更简洁的方式检测它。不过要记住,也有很多 其他可能的值同样是假值。所以一定要明确自己想检测的就是undefined 这个字面值,而不仅仅是假值。
-
Null Null 类型同样只有一个值,即特殊值 null。逻辑上讲,null 值表示一个空"对象"指针
console.log(typeof null); //object即使 null 和 undefined 有关系,它们的用途也是完全不一样的。
null一般代表的是对象为‘空’,undefined一般代表着数值为‘空’null 是一个假值。 console.log(null ==
undefined); // true -
Number类型 Number 类型使用 IEEE 754 格式表示整数和浮点值(在某些语言中也叫双精度值)整数也可以用八进制(以 8 为基数)或十六进制(以 16 为基数)字面量表示。对于八进制字面量, 第一个数字必须是零(0),然后是相应的八进制数字(数值 0~7)。如果字面量中包含的数字超出了应 有的范围,就会忽略前缀的零,后面的数字序列会被当成十进制数, 八进制字面量在严格模式下是无效的,会导致 JavaScript 引擎抛出语法错误。ES6中八进制通过前缀0o来表示,也适用于严格模式。
let octalNum1 = 070; //八进制56
let octalNum2 = 079; //无效的八进制值,当成79处理
let octalNum3 = 08; //无效的八进制值,当成8处理
//创建十六进制字面量,必须让真正的数值前缀 0x(区分大小写),然后是十六进制数字(0~9 以 及 A~F)。十六进制数字中的字母大小写均可。
let hexNum1 = 0xA; //十六进制的10
let hexNum2 = 0x1f; //十六进制的31
// 浮点值
let floatNum1 = 1.1;
let floatNum2 = 0.1;
let floatNum3 = .1; // 有效,但不推荐
// 因为存储浮点值使用的内存空间是存储整数值的两倍,所以 ECMAScript 总是想方设法把值转换为 整数。在小数点后面没有数字的情况下,数值就会变成整数。类似地,如果数值本身就是整数,只是小数点后面跟着 0(如 1.0),那它也会被转换为整数。
let floatNum4 = 1.; // 小数点后面没有数字,当成整数 1 处理
let floatNum5 = 10.0; // 小数点后面是零,当成整数 10 处理
// 科学计数法
// 对于非常大或非常小的数值,浮点值可以用科学记数法来表示。科学记数法用于表示一个应该乘以 10 的给定次幂的数值。ECMAScript 中科学记数法的格式要求是一个数值(整数或浮点数)后跟一个大 写或小写的字母 e,再加上一个要乘的 10 的多少次幂。
let floatNum6 = 3.125e7;
let floatNum7 = 3e-7;
// 浮点值的精确度最高可达 17 位小数,但在算术计算中远不如整数精确。
// let a = 0.1;
// let b = 0.2;
// let sum = a + b;
// console.log(sum);
// let a = 0.15;
// let b = 0.25;
// let sum = a + b;
// console.log(sum);
// 解决浮点数运算错误的方法可以考虑将浮点数统一乘以一个固定的倍数,将其转化成整数进行计算,计算结果再除以固定倍数转换回原来的小数。
- NaN
NaN 是一个特殊值,意思是“不是数值”(Not a Number),用于表示本来要返回数值的操作失败了(而不是抛出错误)。
console.log(0/0); // NaN
console.log(-0/+0); // NaN
console.log(5/0); // Infinity
console.log(5/-0); // -Infinity
// NaN 有几个独特的属性。首先,任何涉及 NaN 的操作始终返回 NaN(如 NaN/10),在连续多步计算 时这可能是个问题。其次,NaN 不等于包括 NaN 在内的任何值。
console.log(NaN == NaN); // false
// isNaN()函数 判断值是不是NaN
console.log(isNaN(NaN)); // true
console.log(isNaN(10)); // false,10 是数值
console.log(isNaN("10")); // false,可以转换为数值10
console.log(isNaN("blue")); // true,不可以转换为数值
console.log(isNaN(true)); // false,可以转换为数值1
数值转换函数
可以通过三个函数将非数值转换为数值:Number()、parseInt()和parseFlot()
Number()函数基于如下规则进行转换。
布尔值,true转换成1,false转换成0。
数值直接返回。
null,返回0。
undefined,返回NaN。
字符串,应用一下规则。
如果字符串包含数值字符,包括数值字符前面带加、减号的情况,则转换为一个十进制数值。
如果字符串包含有效的浮点值格式如"1.1",则会转换为相应的浮点值。
如果字符串包含有效的十六进制格式如"0xf",则会转换为与该十六进制值对应的十进制整数值。
如果是空字符串(不包含字符),则返回 0。
如果字符串包含除上述情况之外的其他字符,则返回 NaN。
对象,调用 valueOf()方法,并按照上述规则转换返回的值。如果转换结果是 NaN,则调用 toString()方法,再按照转换字符串的规则转换。
let num1 = Number('Hello World!'); //NaN
let num2 = Number(""); //0
let num3 = Number("0000111"); //111
let num4 = Number(true); //1
parseInt()函数更专注于字符串是否包含数值模式。
字符串最前面的空格会被忽略,从第一个非空格字符开始转换。
如果第一个字符不是数值字符、加号或减号,parseInt()立即返回 NaN。这意味着空字符串也会返回 NaN(这一点跟 Number()不一样,它返回 0)。
如果第一个字符是数值字符、加号或减号,则继续依次检测每个字符,直到字符串末尾,或碰到非数值字符。
parseInt()函数也能识别不同的整数格式(十进制、八进制、十六进制)。
不同的数值格式很容易混淆,因此 parseInt()也接收第二个参数,用于指定底数(进制数)。
let num5 = parseInt("1234blue"); // 1234
let num6 = parseInt(""); // NaN
let num7 = parseInt("0xA"); // 10, 解释为十六进制整数
let num8 = parseInt(22.5); // 22
let num9 = parseInt("70"); // 70, 解释为十进制整数
let num10 = parseInt("0xf"); // 15, 解释为十六进制整数
let num11 = parseInt("0xAF", 16); // 175
// let num11 = parseInt("AF", 16);
let num12 = parseInt("AF"); // NaN
parseFloat()
parseFloat()函数的工作方式与parseInt()函数类似。
parseFloat()函数始终忽略字符串开头的零。
这个函数能识别前面讨论的所有浮点格式,以及十进制格式(开头的零始终被忽略)。
十六进制数值始终会返回0。因为 parseFloat()只解析十进制值,因此不能指定底数。
let num13 = parseFloat("1234blue"); // 1234,按整数解析
let num14 = parseFloat("0xA"); // 0
let num15 = parseFloat("22.5"); // 22.5
let num16 = parseFloat("22.34.5"); // 22.34
let num17 = parseFloat("0908.5"); // 908.5
let num18 = parseFloat("3.125e7"); // 31250000
- String类型
String(字符串)数据类型表示零或多个 16 位 Unicode 字符序列。字符串可以使用双引号(")、 单引号(')或反引号(`)表示
let firstName = 'John';
let lastName = "Jacob";
let secondName = `Jingleheimerschmidt`;
\n 换行
\t 制表
\b 退格
\r 回车
\f 换页
\ 反斜杠()
’ 单引号(‘),在字符串以单引号标示时使用,例如’He said, ‘hey.’’
" 双引号(“),在字符串以双引号标示时使用,例如"He said, “hey.””
` 反引号(),在字符串以反引号标示时使用,例如
He said, `hey.``
\xnn 以十六进制编码 nnnn 表示的 Unicode 字符(其中 n 是十六进制数字 0~F),例如\u03a3等于希腊字符"Σ"
转换字符串方式:
-
toString()方法。这个方法唯一的用途就是返回当前值的字符串等价物。
toString()方法可见于数值、布尔值、对象和字符串值。(没错,字符串值也有 toString()方法, 该方法只是简单地返回自身的一个副本。)null 和 undefined 值没有 toString()方法。
在对数值调用这个方法时,toString()可以接收一个底数参数,即以什么底数来输出数值的字符串表示 -
String()方法
如果值有 toString()方法,则调用该方法(不传参数)并返回结果。
如果值是 null,返回"null"。
如果值是 undefined,返回"undefined"。
// 1. toString()方法。这个方法唯一的用途就是返回当前值的字符串等价物。
let age = 11;
let ageAsString = age.toString();
let found = true;
let founAsString = found.toString();
// 在对数值调用这个方法时,toString()可以接收一个底数参数,即以什么底数来输出数值的字符串表示
let num = 10;
console.log(num.toString()); // "10"
console.log(num.toString(2)); // "1010"
console.log(num.toString(8)); // "12"
console.log(num.toString(10)); // "10"
console.log(num.toString(16)); // "a"
// 2. String()方法
let value1 = 10;
let value2 = true;
let value3 = null;
let value4;
console.log(String(value1)); // "10"
console.log(String(value2)); // "true"
console.log(String(value3)); // "null"
console.log(String(value4)); // "undefined"
// 字符串插值
// 字符串插值通过在 中使用一个 J a v a S c r i p t 表达式实现(包括函数,方法) l e t v a l u e = 5 ; l e t e x p o n e n t = ′ s e c o n d ′ ; l e t i n t e r p o l a t e d S t r i n g = v a l u e + ′ t o t h e ′ + e x p o n e n t + ′ p o w e r i s ′ + ( v a l u e ∗ v a l u e ) ; l e t i n t e r p o l a t e d T e m p l a t e L i t e r a l = ‘ {}中使用一个 JavaScript 表达式实现(包括函数,方法) let value = 5; let exponent = 'second'; let interpolatedString = value + ' to the ' + exponent + ' power is ' + (value * value); let interpolatedTemplateLiteral = ` 中使用一个JavaScript表达式实现(包括函数,方法)letvalue=5;letexponent=′second′;letinterpolatedString=value+′tothe′+exponent+′poweris′+(value∗value);letinterpolatedTemplateLiteral=‘{ value } to the ${ exponent } power is ${ value * value }`;
操作符
操作符的种类跟Java类似直接上例子
// 操作符包含有 数学操作符、位操作符、关系操作符、赋值操作符等。
// 1 算术运算符。 +、-、*、/、
let num1 = 100;
let num2 = 10;
// 加、减、乘、除
console.log(num1 + num2);
console.log(num1 - num2);
console.log(num1 * num2);
console.log(num1 / num2);
// 取余运算%
console.log(num1 % num2);
// 除了+ 以外的运算符都会把数据转成数值类型进行运算。
// 运算符进行了类型转换(隐式转换)
console.log(2 + '2');
console.log(2 - '2');
// 如果将一元加、减(+、-)应用到非数值,则会执行与使用 Number()转型函数一样的类型转换:布尔值 false 和 true 转换为 0 和 1,字符串根据特殊规则进行解析,对象会调用它们的 valueOf()和/或 toString() 方法以得到可以转换的值。
let x1 = '1';
let x2 = '1.1';
let x3 = 'Z';
let bb = false;
let ff = 1.1;
let obj = {
valueOf() {
return -1;
}
}
x1 = +x1;
x2 = +x2;
x3 = +x3;
bb = +bb;
ff = +ff;
obj = +obj;
// 自增、自减运算符 ++、-- (一元操作)
// 自增或自减运算符相当于当前值+1或者-1
let age = 18;
console.log(++age);
console.log(--age);
// 自增和自减有两种写法
// ++在前,先自增再运算,++在后,先运算再自增
console.log(age++);
console.log(age);
/*
自增、自减操作符可以作用于任何值,不限于整数--字符串、布尔值、浮点值,甚至对象都可以。
·对于字符串,如果是有效的数值形式,则转换为数值再应用改变。变量类型从字符串变成数值。
·对于字符串,如果不是有效的数值形式,则将变量的值设置为 NaN 。变量类型从字符串变成数值。
·对于布尔值,如果是 false,则转换为 0 再应用改变。变量类型从布尔值变成数值。
·对于布尔值,如果是 true,则转换为 1 再应用改变。变量类型从布尔值变成数值。
·对于浮点值,加 1 或减 1。
·如果是对象,则调用其valueOf()方法取得可以操作的值。对得到的值应用上述规则。如果是 NaN,则调用 toString()并再次应用其他规则。变量类型从对象变成数值。
*/
let s1 = "2";
let s2 = "z";
let b = false;
let f = 1.1;
let o = {
// 返回对象对应的字符串、数值或布尔值
valueOf() {
return -1;
}
};
s1++;
s2++;
b++;
f--;
o--;
// 赋值运算符 =
let point = 100;
// += x+=y => x=x+y
// -= x-=y => x=x-y
// *= x*=y => x=x*y
// /= x/=y => x=x/y
// %= x%=y => x=x%y
let x = 10;
let y = 10;
x += y;
console.log(x);
// 比较运算符(关系运算符)
// 比较运算符执行比较两个值的操作,包括(<)(>)(<=)(>=)(==)(!=)(===)(!==)
// 这几个操作符都返回的是布尔值。
/**
如果操作数都是数值,则执行数值比较。
如果操作数都是字符串,则逐个比较字符串中对应字符的编码。
如果有任一操作数是数值,则将另一个操作数转换为数值,执行数值比较。
如果有任一操作数是对象,则调用其 valueOf()方法,取得结果后再根据前面的规则执行比较。 如果没有 valueOf()操作符,则调用 toString()方法,取得结果后再根据前面的规则执行比较。
如果有任一操作数是布尔值,则将其转换为数值再执行比较。
*/
console.log(1 > 5);
console.log(2 >= 2);
// 相等和不相等操作符(==)(!=)
// 这两个操作符都会先进行类型转换(通常称为强制类型转换)再确定操作数是否相等。
// null 和 undefined 相等。
// null 和 undefined 不能转换为其他类型的值再进行比较。
// 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回 true。否则,两者不相等。
console.log(2 == "2");
console.log(undefined == null);
let oc = {
valueOf() {
return -1;
}
};
let od = {
valueOf() {
return -1;
}
};
console.log(oc == od);
// 全等与不全等 (===)(!==)
// 全等和不全等操作符与相等和不相等操作符类似,只不过它们在比较相等时不转换操作数。
// 判断的是两边的值和数据类型是否完全相同。
console.log(2 === "2");
console.log(undefined === null);
// NaN不等于任何值,包括它本身。 涉及到NaN的比较都是false
console.log(NaN == NaN);
console.log(NaN === NaN);
// 尽量不是比较浮点数,因为会有精度问题
console.log(0.1+0.2 === 0.3);
// 逻辑运算符(布尔运算符)
// 逻辑与(&&)、逻辑或(||)、逻辑非(!)
console.log(false && false);
console.log(true && false);
console.log(true && true);
console.log(false && true);
// 逻辑与操作符是一种短路操作符,意思就是如果第一个操作数决定了结果,那么永远不会对第二个操作数求值。对逻辑与操作符来说,如果第一个操作数是 false,那么无论第二个操作数是什么值,结 果也不可能等于 true。
let fond = true;
let result = (found && someUndeclaredVariable);
console.log(result);
console.log(false || false);
console.log(true || false);
console.log(true || true);
console.log(false || true);
console.log(!false);
console.log(!true);
console.log(!0);
console.log(!NaN);
console.log(!undefined)
console.log(!'');
console.log(!12345)
console.log(!{});
接下来就是分支和循环也是类似的
分支
// if...else... 语句
/*
if (条件) {
满足条件执行的代码
}
*/
if (true) {
console.log('我是真');
}
let s = 'ajosd';
if (s) {
console.log('我是真');
} else {
console.log('我是假');
}
let day = 2;
if (day === 1) {
console.log('今天是星期一');
} else if (day === 2) {
console.log('今天是星期二');
} else if (day === 3) {
console.log('今天是星期三');
} else if (day === 4) {
console.log('今天是星期四');
} else if (day === 5) {
console.log('今天是星期五');
} else if (day === 6) {
console.log('今天是星期六');
} else if (day === 7) {
console.log('今天是星期日');
} else {
console.log('哎呀超出我的能力范围了');
}
if (condition) {
if (condition) {
} else {
}
} else {
}
// 需求根据输入不同的成绩,反馈不同的评价
// 成绩90以上是优秀,成绩70~90是良好,成绩60~70是及格,成绩60分以下是不及格
// 三元运算符(三目运算符)
// (条件)? 表达式1 : 表达式2
let num = 10;
num % 2 === 0? console.log('偶数'): console.log('奇数');
const result = num % 2 === 0? '偶数': '奇数';
console.log(result);
// switch语句
// switch 语句是与 if 语句紧密相关的一种流控制语句,从其他语言借鉴而来。ECMAScript 中 switch 语句跟 C 语言中 switch 语句的语法非常相似
switch (key) {
case value:
break;
default:
break;
}
switch (day) {
case 1:
console.log('今天是星期一');
break;
case 2:
console.log('今天是星期二');
break;
case 3:
console.log('今天是星期三');
break;
case 4:
console.log('今天是星期四');
break;
case 5:
console.log('今天是星期五');
break;
case 6:
console.log('今天是星期六');
break;
case 7:
console.log('今天是星期日');
break;
default:
console.log('哎呀超出我的能力范围了')
}
循环
// 循环语句有三种
// 1 do...while
// 2 while循环语句
// 3 for循环语句
let i = 0; //起始值
do {
i++ //循环体
} while (i <= 10); //循环条件
i = 0; //起始值
while (i < 10) { //循环条件
i++; //循环体
}
// for (初始值; 循环条件; 变量变化量) {
// 循环体
// }
// 循环是可以嵌套的。
for (let i = 0; i < 10; i++) {
console.log(i);
}
// 打印一个99乘法表
// for-in 语句
// for-in 语句是一种严格的迭代语句,用于枚举对象中的非符号键属性
// 对象的属性是无序的,因此 for-in 语句不能保证返回对象属性的顺序。
// 如果 for-in 循环要迭代的变量是 null 或 undefined,则不执行循环体。
let object = {
name: 'zhangsan',
age: 18,
}
for (const key in object) {
console.log(key);
}
let array = [1, 2, 3, 4, 5];
for (const key in array) {
console.log(key);
}
// for-of 语句
// for-of 语句是一种严格的迭代语句,用于遍历可迭代对象的元素
for (let index = 0; index < array.length; index++) {
console.log(array[index]);
}
for (const value of array) {
console.log(value);
}
for (const s of "object") {
console.log(s);
}
// break和continue语句
// break和continue语句为执行循环代码提供了更严格的控制手段。其中,break语句用于立即退出循环,强制执行循环后的下一条语句。而 continue 语句也用于立即退出循环,但会再次从循环顶部开始执行。
let num = 0;
for (let i = 0; i < 10; i++) {
console.log(`i = ${ i }`);
for (let j = 0; j < 10; j++) {
if (i === 5 && j ===5) {
break;
}
num++;
console.log(`j = ${ j }`);
}
console.log('--------------------')
}
console.log(num);