目录
JavaScript
Javascript简称JS,是脚本语言,JS语言开发的文件以.js为后缀,通过在HTML文件中引入该js文件来控制html代码的交互功能以及前台数据处理的业务逻辑(js语言代码也可以直接写在html文件中),采用的ECMAScript语法,属于编程语言。
ECMAScript目前普遍使用的存在ES5与ES6两个版本
JS的引入方式
- 行间式:JS代码书写在标签的事件全局属性中
- 内联式:写在scrip标签中,一般放在body标签的最下面,因为代码自上而下运行,放在body标签的最下方,会保证页面所有标签都加载完毕,html再去加载js文件,那么js脚步文件就会更好的控制页面标签的人机交互了
- 外联式:写在外部js文件中,在html页面中用script标签引入js文件,建议放在body最下方
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>引入</title>
<style>
#box {
200px;
height: 200px;
background-color: orange;
}
/*#box:active {*/
/*background-color: red;*/
/*}*/
</style>
</head>
<body>
<!-- 行间式 -->
<!--<div id="box" onclick="this.style.backgroundColor = 'red'"></div>-->
<div id="box"></div>
</body>
<!-- 内联式 -->
<!--<script>-->
<!--box.style.backgroundColor = 'pink'-->
<!--</script>-->
<script src="js/外联.js">
// 链接了外部js的script标签,就相当于单标签,内部代码块会自动屏蔽
box.style.borderRadius = '50%'
</script>
</html>
# js/外联.js
box.style.background = 'blue'
JS的基础语法
变量
JS变量不同于python变量,但是变量结构相差不大,也有变量名,赋值符号,变量值,但是需要特定的关键字来定义,现在JS有两种语法共同存在,ES5/ES6这两个版本,但浏览器会自动识别版本,无需担心语法问题
四种定义变量的关键字
- 不写:全局变量
- var:局部变量
- let:块级变量
- const:常量
n1 = 10; // 全局变量
// console.log(n1); //打印
var n2 = 20; // 局部变量
// alert(n2);
let n3 = 30; // 块级变量
// document.write(n3);
const N4 = 40; // 常量
// console.log(N4);
// N4 = 50; // 报错,常量值不能修改
变量名命名规范
- 由字母,数字,_,$组成,不能以数字开头(可以包含中文字符)
- 区分大小写
- 不能出现关键字及保留字
abstract | arguments | boolean | break | byte |
case | catch | char | class* | const |
continue | debugger | default | delete | do |
double | else | enum* | eval | export* |
extends* | false | final | finally | float |
for | function | goto | if | implements |
import* | in | instanceof | int | interface |
let | long | native | new | null |
package | private | protected | public | return |
short | static | super* | switch | synchronized |
this | throw | throws | transient | true |
try | typeof | var | void | volatile |
while | with | yield |
四种变量的分析
function fn() {
n1 = 10; // 只有全局变量外界才能访问
var n2 = 20;
let n3 = 30;
const n4 = 40;
}
fn();
console.log(n1);
if (true) { // 块级作用域
n1 = 10;
var n2 = 20;
let n3 = 30; // let与const声明的变量有块级作用域
const n4 = 40; // 常量
}
console.log(n1);
console.log(n2);
{
let aaa = 10
}
基本数据类型
值类型
// 数字类型:number
var num = 10;
const PI = 3.14;
console.log(typeof(num), num); // 结果:number 10
// 字符串类型:string
var s1 = "双引号可以表示字符串";
var s2 = '单引号可以表示字符串';
var s3 = `多行字符串:
再来一行`;
console.log(typeof(s1), s1); // 结果:string 双引号可以表示字符串
// 布尔类型:boolean
var b1 = true;
var b2 = false;
console.log(typeof(b1), b1); // 结果:string 双引号可以表示字符串
// 未定义类型:undefined
var u1;
var u2 = undefined;
console.log(typeof(u1), u1); // 结果:undefined undefined
引用类型
// 函数类型:function
function fn1() {}
var fn2 = function() {};
console.log(typeof(fn1), fn1); // 结果:function ƒ fn1() {}
// 对象类型:object
var obj1 = {}
console.log(typeof(obj1), obj1); // 结果:function {}
其它
// 空类型 var jerry = null; console.log(typeof jerry, jerry); // Array对象类型: var arr1 = [1, 2, 3, 4, 5] console.log(typeof(arr1), arr1); // 结果:object (5) [1, 2, 3, 4, 5] // 时间 var date = new Date(); console.log(typeof date, date); // 功能性 随机数: Math.random() - (0, 1) console.log(Math.random()); // 需求:在正整数区间[m, n]随机一个数 // (0, 1) * 10 => (0, 10) 取值parseInt() => [0, 9] + 5 => [5, 14] // parseInt(Math.random() * 11) + 5 => [5, 15] // [m, n] => +的值就是m,*的值 n - m + 1 // ① parseInt(Math.random() * (n - m + 1)) + m => [m, n] var r_num = parseInt(Math.random() * (14 - 7 + 1)) + 7; console.log(r_num); // ② (0, 1) * 超大的数 取整 // 一个正整数 % num => [0, num-1] + m => [m, num-1+m] => n = num+m-1 => num = n-m+1 // 一个正整数 % (n-m+1) + m => [m, n] var random_num = parseInt( Math.random() * 10000000000 % (14 - 7 + 1) ) + 7; console.log(random_num)
数据类型的使用
- 字符串
// string => str
// 1)声明
// 单引号 | 双引号 | 反引号
// 2)字符串拼接
res = 'you are' + ' ' + 'good man!';
console.log(res);
// 3)字符串的切片
s = 'you are good man!';
n_s = s.slice(8, 12);
console.log(n_s); // good
// 4)字符串替换
s = 'you are good man!';
n_s = s.replace('man', 'woman');
console.log(n_s);
// 5)字符串拆分
s = 'you are good man!';
res = s.split(' ');
console.log(res);
// 6)字符串迭代
s = 'abcdef';
for (num of s) {
console.log(num)
}
- 数组
// array => list
// 1)声明
arr = [1, 4, 2, 3, 5];
console.log(arr);
// 2)反转
arr.reverse();
console.log(arr);
// 3)组合
str = arr.join('@');
console.log(str);
// 4)切片
new_arr = arr.slice(1, 4);
console.log(new_arr);
// 5)排序
arr.sort();
console.log(arr);
// 6)增删改查
// 查:只有正向索引
console.log(arr[2]);
// 增
arr.push(888); // 尾增
console.log(arr);
arr.unshift(666); // 首增
console.log(arr);
// 删
res = arr.pop(); // 尾删
console.log(arr, res);
res = arr.shift(); // 首删
console.log(arr, res);
// 增删改 综合方法:splice
// 三个参数:开始操作的索引 操作的位数 操作的结果(可变长)
arr = [1, 2, 3, 4, 5];
// 数组长度:arr.length
arr.splice(arr.length, 0, 666, 888);
console.log(arr);
- 字典(对象)
// object => dict
// 1)定义
height = 180;
dic = {
'name': 'Owen', // 本质是对象
age: 18, // 所有的key(属性名)都是字符串类型,所以可以省略引号
height, // 当value为变量,且变量名与key同名,可以省略value
};
console.log(dic);
// 2)访问
console.log(dic.name);
console.log(dic['age']);
// 3)增删改
// 增
dic.sex = '男';
console.log(dic);
// 删
delete dic.sex;
console.log(dic);
// 改
dic.name = 'Nick';
console.log(dic);
基本运算符
算数运算符
假设:n = 5
运算符 | 描述 | 例子 | x结果 | n结果 |
---|---|---|---|---|
+ | 加法 | x=n+2 | 7 | 5 |
- | 减法 | x=n-2 | 3 | 5 |
* | 乘法 | x=n*2 | 10 | 5 |
/ | 除法 | x=n/2 | 2.5 | 5 |
% | 取模(余数) | x=n/2 | 1 | 5 |
++ | 自增 | x=++n | 6 | 6 |
x=n++ | 5 | 6 | ||
-- | 自减 | x=--n | 4 | 4 |
x=n-- | 5 | 4 |
赋值运算符
假设:x=5,y=5
运算符 | 例子 | 等同于 | 运算结果 |
---|---|---|---|
= | x=y | 5 | |
+= | x+=y | x=x+y | 10 |
-= | x-=y | x=x-y | 0 |
*= | x*=y | x=x*y | 25 |
/= | x/=y | x=x/y | 1 |
%= | x%=y | x=x%y | 0 |
比较运算符
假设:x = 5
运算符 | 描述 | 比较 | 结果 |
---|---|---|---|
== | 等于 | x=="5" | true |
=== | 绝对等于 | x==="5" | false |
!= | 不等于 | x!="5" | fales |
!== | 不绝对等于 | x!=="5" | true |
> | 大于 | x>5 | false |
< | 小于 | x<5 | false |
>= | 大于等于 | x>=5 | true |
<= | 小于等于 | x<=5 | true |
逻辑运算符
假设:n = 5
运算符 | 描述 | 例子 | 结果 |
---|---|---|---|
&& | 与 | x=n>10&&++n | x=false,n=5(短路) |
|| | 或 | x=n<10||n-- | x=true,n=5(短路) |
! | 非 | x=!n | x=false,x=5 |
三目运算符
语句:结果 = 条件表达式 ? 结果1 : 结果2;
假如条件表达式成立,则把结果1赋值给结果,否则就把结果2赋值给结果
案例
// 1)算术运算符
console.log(5 / 2); // 2.5
console.log(parseInt(5 / 2));
console.log(parseFloat(5 / 2));
// parseInt | parseFloat 可以完成 string => number
res = parseInt('3.14.15abc');
console.log(res); // 从头往后找整数部分
res = parseFloat('3.14.15abc');
console.log(res); // 从头往后找小数部分(最多只识别一个小数点)
res = parseInt('a3.14.15abc'); // NaN
console.log(typeof res, res);
// 2) 弱语言类型的js
res = 10 + '5';
console.log(res); // 字符串:105
res = 10 - '5';
console.log(res); // 数字:5
// 数字 => 字符串
res = '' + 5;
console.log(typeof res, res);
// 字符串 => 数字
res = +'5';
console.log(typeof res, res);
// 3) 自增自减
num = 10;
num += 1;
console.log(num);
num++;
console.log(num);
num--;
console.log(num);
// 了解:符号 在前优先级高于一切运算符,在后优先级比赋值符还低
// ++在前先自增再运算;++在后先运算再自增
num = 10;
res = num++;
console.log(num, res);
num = 10;
res = ++num;
console.log(num, res);
// 4) 比较运算符的比较
console.log(5 == '5'); // true,只做值比较
console.log(5 === '5'); // false,做值与类型比较
console.log(5 != '5'); // false,只做值比较
console.log(5 !== '5'); // true,做值与类型比较
// 5)逻辑运算符
console.log(true && true);
console.log(false || false);
console.log(!true);
// 短路现象
// &&: 有假则假,前为假,后不用判断
num = 10;
console.log(false && ++num); // num++ | ++num 都被短路不会被执行
console.log(num);
console.log(true || ++num); // num++ | ++num 都被短路不会被执行
console.log(num);
// 6)三元运算符(三目运算符)
res = 5 == '5' ? '值相等':'值不等';
console.log(res);
流程控制
分支结构
- if分支结构
/*
* if (条件) {
* 代码块1
* }
* else if (条件) {
* 代码块2
* }
* else {
* 代码块3
* }
*/
var num = parseInt(Math.random() * 16);
console.log(num);
if (num > 10) {
console.log("产生的数超过10")
} else if (5 <= num && num <= 10) {
console.log("产生的数间于5~10")
} else {
console.log("产生的数不超过5")
}
- switch分支结构
/*
* switch(值) {
* case 条件1:
* 代码块1;
* break; // 没有break会自动执行下一个case里面的代码块,直到遇到break或程序结束
* case 条件2:
* 代码块2;
* break;
* ...
* default: // 没有走任何case,会进入default分支
* 代码块3;
*/
month = parseInt(Math.random() * (12 - 1 + 1)) + 1;
console.log(month);
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
console.log('%s月31天', month);
break; // 用来结束case,跳出switch分支结构,多个分支可以共享一个break
case 2:
console.log('2月28天');
break;
case 4:
case 6:
case 9:
case 11:
console.log('%s月30天', month);
break;
default:
console.log('月份参数有误');
}
循环结构
- for循环
for (循环变量①; 条件表达式②; 循环变量增量③) {
代码块④;
}
// for循环执行的顺序:① ②④③ ... ②④③ ②,入口为①,出口为②,②④③就是循环过程
// 案例:
for (var i = 0; i < 5; i++) {
console.log(i);
}
// 结果:
0
1
2
3
4
// for…in迭代器
var arr = [1, 2, 3, 4, 5]
for (num in arr) {
console.log(num);
}
// 结果:
0
1
2
3
4
- while循环
while (条件表达式) {
代码块;
}
// 条件满足执行代码块,条件不满足跳出循环
// 案例:
var i = 0;
while (i < 5) {
console.log(i);
i++;
}
// 结果:
0
1
2
3
4
- do...while 循环:先执行一次循环体,再判断条件
var num = 90;
do {
console.log(num);
num++;
} while (num <= 10);
//结果:
90
"""
1) for:解决知道循环次数的循环
2) while:
解决一切for与do...while能解决的问题(结合函数的思想)
解决不知道循环次数的循环(循环用break结合)
3) do...while:完成循环体必须要提前执行一次的循环
"""
函数
函数的组成
-
函数名 :函数名存放的就是函数的地址
通过 函数名() 调用函数的 -
参数列表:将外界资源传给内部的桥梁
你传你的,我收我的,用...接收可变长 -
函数体 : 解决需求的代码块
功能代码块 -
返回值 : 将内部数据反馈给外部
只能返回一个值,不写或空return返回undefined
定义函数的三种方式
"""
第一种:
关键字 函数名(参数列表) {
函数体;
返回值
}
第二种:
var 函数名 = 关键字(参数列表) {
函数体;
返回值
}
第三种:
var 函数名 = (参数列表) => {
函数体;
返回值
}
"""
有名函数
// 定义
function add(n1, n2) {
return n1 + n2
}
// 使用
res = add(10, 20);
console.log(res);
// 函数名的运用
my_add = add;
console.log(my_add(100, 200));
// 少传未接收到的形参赋值为undefined,多传的实参自动被丢弃
function fn(n1, n2) {
console.log('传输的n1:%s | n2:%s', n1, n2)
}
fn(10, 20);
fn();
fn(100);
fn(1000, 2000, 3000);
// 可变长参数
function func(...num) {
console.log(num)
}
func(1, 2, 5, 3, 4);
// 用变量接收 - 函数的第二种声明方式
var fun = function () {
console.log('函数的第二种声明方式')
};
fun();
// 函数的第三种声明方式
var fun2 = (n1, n2) => { // 有函数体标明{}
console.log('n1:%s | n2:%s', n1, n2);
return n1 + n2
};
console.log(fun2(222, 444));
var fun3 = (n1, n2) => n1 + n2; // 只有返回值可以省略{}
console.log(fun3(222, 444));
匿名函数
// 匿名函数
// 匿名函数的自调用 - 调用一次后就会被回收资源
(function () {
console.log('匿名函数')
})();
// 匿名函数自调用,可以产生局部作用域与外界隔离
(function () {
let number = 888
})()
// console.log(number) // 外界不可以直接访问