JavaScript
概述
什么是javascript
脚本语言
语法与java类似
ECMAScript:javascript标准,最新为6,普遍适用5
引入
html 内部使用,一般定义在 html 末尾,其实放哪无所谓
<script>
var num = 1;
alert(num);
</script>
2
3
4
外部引用 .js 文件,一般放在 html 的最下方
<script src="javascript/hello.js"></script>
基础
与java基本保持一致,无数据类型
<!-- 语法和java基本保持一致 -->
<script>
//定义变量
var score = 71;
var name = "hello";
//条件控制
if(score > 60){
alert("successed");
} else {
alert("failed");
}
</script>
2
3
4
5
6
7
8
9
10
11
12
- 变量名规则基本与java保持一致
控制台操作
console.log(value);
//在控制台打印一个变量value
2
或直接输入执行 js 代码,类似于 python 的解释性编程
数据类型
数值,文本,图形,音频,视频......
number
js不区分小数和整数,数字全为number类型
123 //整数123
123.1 //浮点数123.1
1.123e3 //科学计数法
-99 //负数
NaN //not a number
Infinity //表示无限大
2
3
4
5
6
字符串
'abc' "abc" '\n'
布尔值
true false
逻辑运算
&& 与
|| 或
! 非
2
3
比较运算符
在 js 中绝大部分判断等于时使用 === 绝对等于
= 赋值
== 等于(类型不一样,值一样会判断为true,如1和'1')
=== 绝对等于(类型一样&&值一样)
2
3
属于 javascript 的缺陷
须知
NaN与所有数据都不相等,包括自己
可通过 isNaN() 函数判断是否为NaN
浮点数问题
// 值为false,不相等,浮点数会有精度损失,尽量避免使用浮点数进行运算 console.log((1/3) === (1-2/3));
1
2
null 和 undefined
null:空
undefined:用了不存在的变量
数组
一系列相同类型的对象,js中不分类型(全为var),可以直接打印出来
var arr = [1, 2, 3, 4, 5,"hello", null, true];
alert(arr);
alert(arr[0]);
2
3
数组越界:undefined
//超出数组长度会报 undefined
alert(arr[12]);
2
也可以使用这样的形式,但可读性很低,不建议使用
var arr = new Array(1, 2, 3, 4, "hello, world");
alert(arr);
2
对象
对象式大括号,数组为中括号
// 对象,每个属性之间用逗号隔开
var person = {
name: "northboat",
age: 2,
tags: ["javascript", "java", "c++", "golang"]
}
console.log(person.name + " " + person.age + " " + person.tags);
2
3
4
5
6
7
8
严格检查模式
在 js 中,下列代码也是可以的,但很不好(太随意了)
i = 1;
为了预防这种操作,在script的第一行启用严格检查模式,预防此类问题
'use strict';
注意在 js 中,用 var 定义的均为全局变量,当一个html引入多个js文件时很不安全,我们用 let 定义局部变量,只作用于当前js文件
- ES6支持
let a = 1;
数据类型与函数
数据类型
字符串
多行编写 ``
`多行编写\n我遍尼玛`
模板字符串 ${}
let name = xzt;
let hello = wdnmd;
let msg = `我${name},${hello}`;
2
3
样例
<!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>
// 严格检查模式
'use strict';
let a = "hahaha";
let d = "wdnmd";
// 内建函数
let l = a.length;
let b = a[0];
let c = a.charAt(0);
let f = a.substring(0, 4);
console.log(a + '\n');
console.log(l + '\n');
if(b === c){
console.log("他们一样噢~");
}
// 多行编写 模板字符串
let msg = `${a}\n${d}`;
console.log(msg);
console.log(f);
</script>
</head>
<body>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
数组
数组函数
let arr = [1,2,3,4,5,a,b]
- arr.length()
- arr.indexOf(9):越界将报undefined
- slice(0, 5):切割,同subString
- push(...):追加,可追加无限元素
- pop():弹出末尾元素
- unshift(...):头插
- shift():弹出头部元素
- sort()
- reverse()
- concat("hahaha"):拼接,返回拼接结果,不修改原数组
- join('-'):用 - 连接数组中元素,返回字符串
- fill('+'):用+填充数组
- find(1):查找元素
多维数组
let arr = [[a,2], ['hahaha',1],["wdnmd",'hello']];
对象
对象定义
let person = {
name: "xzt",
age: 3,
socre: 59.5,
tag: fw
}
2
3
4
5
6
使用不存在的属性:报错undefined
person.hahaha;
动态删减属性
delete person.tag;
动态添加属性
person.hahaha = "wdnmd";
一些函数
'age' in person //true
'toString' in person //true
person.hasOwnProperty('toString') //false
2
3
- 'toString' 是对象继承而来的方法,使用in为true
- hasOwnProperty()只检查对象自己的方法,为false
流程控制
if判断
let age = 3;
if(age < 3){
console.log("呜呜呜");
} else if(age >= 3 && age <= 19){
console.log("哈哈哈");
} else {
console.log("...");
}
2
3
4
5
6
7
8
while循环
while(age < 60){
age = age+1;
console.log(age);
}
2
3
4
for循环
for(let i = 0; i < 9; i++){
console.log(i + " wdnmd");
}
2
3
数组循环
- 在不知道数组大小时,使用for-in循环比较稳妥
- 更多时候我们使用函数遍历
//数组循环
let arr = [1,2,3,4,5,6,7,8,9];
// 函数
arr.forEach(function(value){
console.log(value);
})
// for-in:index为索引
for(let index in arr){
console.log(arr[index]);
}
2
3
4
5
6
7
8
9
10
注意在使用for-in时,如给数组新增属性,x会输出"hahaha",bug属于是
arr.name = "hahaha";
for(let x in arr){
console.log(x);
}
2
3
4
Map和Set
1、map
var map = new Map([["tom", 60], ["jack", 90], ["hahaha", 100]]);
// 通过key获得value
let score = map.get("tom");
map.set("admin", 123456);
map.delete("hahaha");
// 判断键是否存在
console.log(map.has("jack"));
2
3
4
5
6
7
2、set
var set = new Set([3,1,1,1,1,1,2]); //Set可以去重
set.add(3);
set.delete(1);
// 以数组形式输出Set
let arr = Array.from(set);
console.log(set.has(3));
2
3
4
5
6
Iterator
遍历器,ES6新特性
遍历数组
'use strict';
let arr = [99,2,3,4,5];
// 遍历数组
for(let x of arr){
console.log(x);
}
2
3
4
5
6
遍历map
// 遍历map
let map = new Map([["tom", 60], ["jack", 90], ["hahaha", 100]]);
for(let x of map){
console.log(x);
}
2
3
4
5
遍历set
// 遍历set
let set = new Set([1,2,3,4,5]);
for(let x of set){
console.log(x);
}
2
3
4
5
函数
定义
推荐方法
function abs(x){
if(x < 0){
return -x;
} else {
return x;
}
}
let x = abs(-2);
2
3
4
5
6
7
8
9
方法二:定义abs为函数
var abs = function(x){
if(x < 0){
return -x;
} else {
return x;
}
}
2
3
4
5
6
7
参数问题:
- 若abs(1,2,3,4,5,6),将返回第一个参数的结果
- 若abs(),即不传参,将返回undefined
不存在参数,手动抛出异常
- typeof x:x的类型
- throw:抛出异常
function abs1(x){
if(typeof x !== 'number'){
throw "Not a Number";
}
return abs(x);
}
2
3
4
5
6
参数过多
- arguments:关键字 —— 参数
- 可以通过argument拿到多余参数
- arguments有自己的内置属性
function abs2(x){
for(let i = 0; i < arguments.length; i++){
console.log(arguments[i]);
}
// 手动抛出参数过多异常
if(arguments >= 2){
throw "Too much arguments";
}
return abs1(x);
}
2
3
4
5
6
7
8
9
10
11
12
问题:arguments包含所有的参数(以数组的形式),有时候我们想操作多余参数,需要排除已有参数
rest:剩余
ES6引入的新特性,获取除了已定义的参数之外的所有参数
- 必须按照以下格式,rest参数为rest,省略号模仿的java
function fun(a, b,...rest){
console.log("a=>" + a);
console.log("b=>" + b);
console.log(rest);
}
2
3
4
5
作用域
类比C语言
变量未定义报错,当你试图用函数内定义的变量
- Uncaught ReferenceError: x is not defined
function ha(){
var x = 1;
x++;
}
x = x+2;
2
3
4
5
内部函数能访问外部函数成员,反之不行
function ha(){
var x = 1;
x++;
function ha2(){
console.log(x);
var y = 0;
}
//console.log(y);将报错
}
2
3
4
5
6
7
8
9
当内部函数变量与外部函数重名,使用内部的env中函数,递归从内向外查找env->fatherEnv
function ha(){
var x = 1;
x++;
function ha2(){
var x = 95;
console.log(x);
var y = 0;
}
console.log(x);
ha2();
//console.log(y);
}
ha();
2
3
4
5
6
7
8
9
10
11
12
13
此时输出
95
2
2
提升作用域
function hei(){
var y;
var x = "x" + y;
console.log(x);
y = "y";
}
hei();
2
3
4
5
6
7
结果:xundefined
说明:自动提高了y的声明,不会报错
- 我们习惯在头部声明好变量,便于代码维护,无论是否赋值
全局变量
var x = "xzt";
function f(){
console.log(x);
}
f();
2
3
4
5
window
var x = "xzt";
alert(window.x);
2
默认所有的全局变量,都会自动绑定在window对象下,包括内建函数如 alert
window.alert(window.x);
window => 浏览器本身,我们甚至可以通过window修改内建函数
alert("hahaha");
var old_alert = window.alert;
window.alert = function(){
};
//alert失效
alert(window.x);
2
3
4
5
6
7
javascript实际上只有一个全局作用域,任何变量(函数也视为变量),假设没有在函数作用域内找到,就会向外查找,最终在window中找,若仍未找到,则报错 ReferenceError 引用异常
规范
由于全局变量都绑定在window上,如果不同的js文件同名将会产生冲突
将自定义函数、变量全绑定在唯一一个对象(变量)中
var app = {};
app.name = "xzt";
app.fun = function(a, b){
return a+b
}
2
3
4
5
局部作用域let
这样的代码在for代码块外也能读到a
function aaa(){
for(var a = 0; a < 100; a++){
console.log(a);
}
console.log(a+1);
}
2
3
4
5
6
推荐以下写法
function aaa(){
for(let a = 0; a < 100; a++){
console.log(a);
}
//console.log(a+1);
}
2
3
4
5
6
常量const
在ES6之前,这样定义常量,全部大写命名的变量即为常量,建议不要修改这样的值(但实际上是能改的)
var PI = 3.14;
在ES6中引入常量关键字const
const PI = 3.14;
console.log(PI);
PI = 3.15;
2
3
将报错 invalid assignment to const 'PI'
方法
对象中的函数
var xzt = {
name: "xzt",
birth: 2001,
age: function(){
let cur = new Date().getFullYear();
return cur-this.birth;
}
}
console.log(xzt.age()); //20
2
3
4
5
6
7
8
9
10
this:指向自己 ——> 可以这样调用,但还是要加括号,只要调用函数,必有括号
function getAge(){
let cur = new Date().getFullYear();
return cur-this.birth;
}
var xzt = {
name: "xzt",
birth: 2001,
age: getAge
}
console.log(xzt.age()); //20
2
3
4
5
6
7
8
9
10
11
但不能直接 getAge(),因为此时 this 指向 window,window 无 birth 对象,将输出NaN
apply(this, arugements)
let x = getAge.apply(xzt, [])
console.log(x); //20
2
apply第一个参数为this指向对象,第二个参数为数组,即你要调用的函数参数,如此实现外部函数对某一特定对象的使用
对象
标准对象
typeof 1 => "number"
typeof "1" => "string"
typeof true => "boolean"
typeof [] => "object"
typeof Math.abs => "function"
内部对象
Date
基本使用
var now = new Date();
now.getFullYear();
now.getDate(); //日期(几号)
now.getDay() //星期几
now.getMonth(); //0~11月
now.getHours();
now.getMinutes();
now.getSeconds();
2
3
4
5
6
7
8
转化时区,也可以toDateString(地区)
//转化为当前地区时间
now.toLocaleDateString();
2
时间戳
//获得时间戳,全世界统一,从1970.1.1 0:00:00到现在的毫秒数
let curTime = now.getTime();
for(let i = 0; i < 100000000; i++){
i *= i;
}
let time = now.getTime();
console.log(time-curTime);
2
3
4
5
6
7
JSON
轻量级的数据交换格式 —— 键值对数据
早期,所有数据传输习惯使用xml文件
现在还有BSON,主要被用在MongoDB中,二进制的JSON
- 简洁和清晰的层次结构
- 易于人阅读编写,有效提升网络传输效率
任何js支持的类型都可以用JSON来表示:number, string, object, function
格式
- 对象都用{}
- 数组都用[]
- 所有的键值对,都是用 key-value
JS字符串和JSON的转化
var person = {
name: "xzt",
age: 3,
gender: "男"
}
// 将对象转化为JSON
var jsonPerson = JSON.stringify(person);
// 字符串转化为对象
var obj = JSON.parse('{"hahaha": 1, "age": 3, "eihei": "wdnmd"}');
2
3
4
5
6
7
8
9
10
11
JSON和JS对象的区别
var obj = {a: "hello", b: 123};
var json = "{"a":"hello", "b": "123"}"
2
Ajax
- 原生的js写法:xhr 异步请求
- jQury 封装好的方法 $("#name").ajax("")
- axios 请求
面向对象
继承
proto继承
var person = {
name: "xzt",
age: 3,
gender: "男",
run: function(){
console.log(this.name + " is running");
}
}
var bird = {
fly: function(){
console.log(this.name + " is flying");
}
}
// 将对象转化为JSON
var jsonPerson = JSON.stringify(person);
// 字符串转化为对象
// var obj = JSON.parse({"hahaha": 1, "age": 3, "eihei": 99});
var xiaoming = {
name: "xiaoming"
}
// 另类的继承,proto指模板,即xiaoming的模板为person
xiaoming.__proto__ = person;
xiaoming.run();
xiaoming.__proto__ = bird;
xiaoming.fly();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class继承
class关键字在ES6中引入
<!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>
class Student{
constructor(name){
this.name = name;
}
hello(){
alert("wdnmd");
}
}
class XiaoStudent extends Student{
constructor(name, grade){
// super实现父类同名方法
super(name);
this.grade = grade;
}
myHello(){
alert("我是一个小学生")
}
}
var xiaoming = new Student("xiaoming");
var xiaohong = new XiaoStudent("xiaohong", 86);
</script>
</head>
<body>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
原型链:proto
在javascript中,每一个函数都有一个prototype属性,指向函数的原型对象
Object.prototype为null,停止查找,但实际上构成一个死循环,有点像jdk
BOM和DOM
BOM:浏览器对象模型
B:Browser
BOM
window
// window
let windowInnerWidth = window.innerWidth;
let windowInnerHeight = window.innerHeight;
let windowOuterWidth = window.OuterWidth;
let windowOuterHeight = window.outerHeight;
2
3
4
5
navigator
储存了浏览器信息,可被修改,不推荐使用
// navigator:浏览器信息 ——> 可被修改
let appName = navigator.appName;
let version = navigator.version;
let userAgent = navigator.userAgent;
let platform = navigator.platform;
2
3
4
5
screen
屏幕
// screen:屏幕大小 ——> 电脑分辨率
let screenWidth = screen.width;
let screenHeight = screen.height;
2
3
location
网页地址
// location
let host = location.host;
let href = location.href;
let protocal = location.protocal;
// 重新加载函数
location.reload();
// 重定向函数
location.assign("http://www.baidu.com");
2
3
4
5
6
7
8
history
主要控制网页前进\后退
// history:网页历史
history.back(); //后退
history.forward(); //前进
2
3
document
html网页文档
// ducoment ——> 当前HTML页面文档树
document.getElementsByClassName("hahaha");
document.getElementById("app");
document.getElementsByTagName("span");
document.cookie;
2
3
4
5
DOM
文本对象模型
D:Document
获取结点
// 获取结点
var ul = document.getElementById("oh");
var a = document.getElementsByClassName("hahaha");
var p = document.getElementById("ah")
2
3
4
删除结点
// 删除结点
var father = ul.parentElement;
father.removeChild(ul);
father.removeChild(father.children[0]);
2
3
4
更新结点
注意此处要用id获取唯一结点
// 修改结点内容,注意必须要用id获得的结点才能生效
p.innerText = "hahaha";
p.innerHTML = "<h1>wdnmd</h1>"
2
3
添加结点
// 添加结点
father.append(ul);
2
创建并添加结点
// 创建结点,参数为标签名
var btn = document.createElement("button");
// 创建文本结点
var text = document.createTextNode("wdnmd");
btn.append(text);
father.append(btn);
2
3
4
5
6
表单提交和加密
表单提交
onsubmit:在提交时可以设置js动作,一个函数
<form action="https://www.baidu.com" method="post" onsubmit="return aaa()"></form>
onclick:与onsubmit同理,在点击提交时,设置一个js动作
<button type="submit" onclick="aaa()">提交</button>
利用md5和hidden框进行加密
引入md5库,或下载下来用相对路径引用
<!-- 引入md5 ——> 加密 -->
<script src="https://cdn.bootcdn.net/ajax/libs/blueimp-md5/2.18.0/js/md5.js"></script>
2
加密
设置隐藏输入框
<input type="password" id="pwd"><br>
<input type="hidden" id="hidden-pwd" name="password">
前端的payload有效负载将根据name属性接收识别其value,我们让真正的密码框没有name,在后台通过id调用真正的密码
同时将真正的密码用md5加密后赋值给后者,即给前端展示的name=password的虚假密码,实现加密
<!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>
<!-- 引入md5 ——> 加密 -->
<script src="https://cdn.bootcdn.net/ajax/libs/blueimp-md5/2.18.0/js/md5.js"></script>
</head>
<body>
<div id="app">
<form action="https://www.baidu.com" method="post" onsubmit="return aaa()">
<span>账号:</span>
<input type="text" id="name" name="username"><br>
<span>密码:</span>
<input type="password" id="pwd"><br>
<!-- 单选框用name属性去约束为同一个 -->
<!-- <span>性别:</span>
<input type="radio" name="gender" value="man"><span>男</span>
<input type="radio" name="gender" value="woman"><span>女</span><br> -->
<input type="hidden" id="hidden-pwd" name="password">
<button type="submit">提交</button>
</form>
</div>
<script>
function aaa() {
alert(1);
var username = document.getElementById("name");
var pwd = document.getElementById("pwd");
var md5Pwd = document.getElementById("hidden-pwd");
md5Pwd.value = md5(pwd.value);
return true;
}
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
前端加密展示效果
东秦教评
全部好评,建议为无
let inputs = document.querySelectorAll("input");
for (i in inputs) if (inputs[i].value == 0) inputs[i].checked = true;
document.querySelector("textarea").value = "无";
document.querySelector("#sub").click();
2
3
4
jQury
获取和使用
使用CDN引入JQury
<!-- 引入jQuery CDN-->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
2
下载在目录下,相对路径引用
<script src="jquery-3.6.0/jquery-3.6.0.min.js"></script>
公式:$(selector).action()
//id选择器
$('#a').click(function(){
alert("康nm呢");
});
2
3
4
选择器
与css选择器一模一样,用单引号或双引号括起来
标签选择器
$('p')
id选择器
$("#id")
类选择器
$(".class")
层次选择器:div后的p标签
$("div p")
子选择器:ul后的第一代li标签
$("ul>li")
相邻兄弟选择器:id为hahaha元素的同级的下一个p标签
$("#hahaha + p")
通用兄弟选择器:id为hahaha元素的同级向下所有p标签
$("#hahaha~p")
结构伪类选择器
$("a:hover")
事件
鼠标事件
- mousedown:鼠标按下
- mouseleave:离开
- mouseover:点击结束
- mousemove:移动
鼠标移动
$(document).ready(function(){
$("#app").mousemove(function(e){
$("#app").text("x:" + e.pageX + ", y:" + e.pageY);
})
})
2
3
4
5
等同于以下写法
// $(document).ready(function(){}) == $(function(){})
$(function(){
$("#app").mousemove(function(e){
$("#app").text("x:" + e.pageX + ", y:" + e.pageY);
})
})
2
3
4
5
6
鼠标点击
$('#a').click(function(){
alert("康nm呢");
$("body").append(h);
});
2
3
4
键盘事件、其他事件...详见文档
操作DOM
文本操作
$("#text-ul").text(); //获得值
$("#text-ul").text("hahaha"); //设置值
$("#text-ul li[name=java]").html(); //获得值
$("#text-ul li[name=java]").html("<span>123</span>");//设置值
2
3
4
5
css操作
使消失,本质 display: none
$("#app").show()
$("#app").hidden()
2
Ajax
网络通信框架
$("#from").ajax();
$.ajax({url: "text.html", context: document.body, success: function(){$(this).addClass("done")}});
2
3