一、快速入门
1.1 引入JavaScript
-
内部标签使用:在HTML的head中直接添加
<head> <script> alert("Hello World"); </script> </head>
-
外部引入:在HTML的head中引入js文件
注意:script必须成对出现,不能使用自闭合标签
<head> <script src="js/note01.js"></script> </head>
1.2 基础语法入门
-
基础语法与Java几乎一致,不同点是定义的变量类型全部为var
<script> // 1.定义变量 js中的变量类型全部为var var num=1; // 2.条件控制 if (2 > 1) { alert("true") } </script>
-
浏览器控制台介绍:
- console:可以通过console.log(变量名)在浏览器的控制台打印变量,相当于Java的"sout"
- sources:可以在sources中打开源码打断点测试代码
1.3 数据类型
-
常见数据类型:数值、文本、图形、音频、视频…
-
js与Java中数据类型的差异
-
NaN代表not a number
-
Infinity表示无限大
-
==:类型不一样,值一样会判断为true(js中不要使用 == 判断)
===:绝对等于,必须要类型跟值都一样才可以判断为true
须知:NaN与所有的数值都不相等,包括自己
-
只能通过isNaN(NaN)来判断这个数是不是NaN
-
尽量避免使用浮点数进行运算,存在精度问题,例如以下代码执行结果为false
console.log(1/3===(1-2/3))
-
浮点数判断
console.log(Math.abs(1/3-(1-2/3))<0.000000001)
-
null:空
-
undefined:未定义
-
js数组使用中括号,其中的元素不一定是相同类型,下标越界后会报undefined
var arr=[1,2,"hello",null,true];
-
对象使用大括号,每个属性之间用逗号隔开,最后一个不需要添加,输出时使用:类名.属性
var person={ name:"xxx", age:3, tags:[1,3,5,"hello"] }
-
1.4 严格检查模式
前提:编译器必须设置为Script6模式,设置方法见下图:
-
use strict:严格审查模式,预防js的随意性产生的一系列问题必须写在js的第一行
-
局部变量建议使用let定义
<script> "use strict"; let i=1; </script>
二、数据类型
2.1 字符串
-
正常的字符串使用单引号或双引号包裹
-
转义字符的使用
\' 字符串 \n 换行 \t tab \u4e2d \u#### unicode字符 \x41 ASCII字符
-
多行字符串编写
用两个波浪线引起来即可~ ~
var msg= `hello world 你好 `
-
模板字符串
"use strict" let name="xiaoming"; let age = 4; let msg=`hello,${name}`; console.log(msg);
-
字符串长度
console.log(student.length)
-
字符串可变性
字符串不可变,但可以通过下标取值
console.log(student[0])
-
大小写转换
console.log(student.toUpperCase()) console.log(student.toLowerCase()) //注意此处是方法而不是属性
-
获取指定元素下标
console.log(student.indexOf('t'))
-
根据下标截取字符串
console.log(student.substring(1,3))//下标含前不含后 [) console.log(student.substring(1))//从该下标开始截取之后的所有字符
2.2 数组
Array可以包含任意的数据类型
var array=[1,2,3,4,5]
//通过下标取值和赋值
1.长度
array.length
//给array.length赋值可以改变数组的大小,如果赋值小于元素个数则会导致元素丢失
2.indexOf:通过元素获得下标索引
array.indexOf(3)
字符串的"1"和数字 1 是不同的
3.slice():截取Array的一部分,返回一个新数组
array.slice(3)
//截取第三个之后的所有元素
4.在数组尾部操作:push()、pop()
array.push()
//在尾部压入元素
array.pop()
//弹出尾部的一个元素
5.在数组头部操作:unshift()、shift()
array.shift()
//在头部插入元素
array.shift()
//弹出头部的一个元素
6.排序
array.sort()
7.元素反转
array.reverse()
8.拼接
array.concat([1,2,3])
//该方法不会修改原数组,只是返回了一个新数组
9.连接符:join
array.join('-')
//打印拼接数组,使用特定的字符串连接
10.多维数组
array=[[2][2]]
//与Java相同
2.3 对象
- js的对象实际上是若干的键值对,而且js中所有的键都是一个字符串,值是任意对象。多个属性之间用逗号隔开,最后一个属性不加逗号
var 对象名={
属性名:属性值,
属性名:属性值,
属性名:属性值
}
- 可以动态删减元素:delete
delete person.name
- 动态增添:直接给新的属性赋值即可
person.email=lll
- 判断属性值是否在这个对象中
'age' in person
//true
'tostring' in person
//true
- 判断一个属性是否是这个对象自身拥有的
person.hasOwnProperty('age')
//true
person.hasOwnProperty('tostring')
//false
2.4 流程控制
-
if、while、for语法均与Java相同,注意避免死循环
-
forEach循环
var age=[1,2,3,4,5,6,34];
age.forEach(function (value) {
console.log(value);
})
-
for…in(不建议使用)
bug:增加元素后会将增加的元素也当作下标
var age=[1,2,3,4,5,6,34];
for(var num in age){
console.log(age[num]);
}
2.5 Map和Set
ES6的新特性
Map:
var map=new Map([['tom',100],['jack',90],['jerry',80]]);
var name=map.get('tom');//通过key获得value
map.set('admin', 123456);//添加元素
map.delete('tom');//删除元素
Set:无序不重复的集合
var set = new Set([1, 3, 5, 6]);//Set可以去重
set.add(2);//增加元素
set.delete(1);//删除元素
console.log(set.has(3));//判断是否包含某元素
2.6 iterator
通过for…of实现遍历元素,for…in只能遍历下标,Map跟Set也可以用同样的方法遍历
var array = [1, 6, 9];
for(var x of array){
console.log(x);
}
遍历Map
var map = new Map([['tom', 100], ['jack', 90], ['jerry', 80]]);
for (let x of map) {
console.log(x);
}
遍历Set
var set = new Set([6,7,8]);
for (let x of set) {
console.log(x);
}
三、函数
3.1 定义函数
- 定义方式一
function abs(x) {
if (x > 0) {
return x;
}else {
return -x;
}
}
如果没有执行return,函数执行完也会返回结果,结果就是undefined
- 定义方式二
var abs =function (x) {
if (x > 0) {
return x;
}else {
return -x;
}
}
//function(x){......}是一个匿名函数,但是可以把结果赋值给abs,通过abs也可以调用函数
- 由于js代码比较随意,传入的参数不符合要求也不会报错,所以需要我们手动定义异常
- 参数类型错误
var abs =function (x) {
if (typeof x !== "number") {
throw "Not a number";
}
if (x > 0) {
return x;
}else {
return -x;
}
}
-
参数数量错误
使用arguments关键字,它代表所有传递进来的参数,是一个数组
var abs =function (x) {
console.log("x->:"+x);
for (let i=0;i<arguments.length;i++) {
console.log(arguments[i]);
}
if (x > 0) {
return x;
}else {
return -x;
}
}
问题:arguments包含所有的参数,我们有时候想使用多余的参数进行附加操作,就需要排除已有参数
解决:使用rest函数(ES6引入的新特性),获取除了已经定义的参数之外的所有参数
function f(a,b,...rest) {
console.log("a->" + a);
console.log("b->" + b);
console.log(rest);
}
rest参数只能写在最后面,必须用…标识
3.2 变量的作用域
- 在js中,var定义的变量是有作用域的,假设在函数体内声明,则不能在函数体外使用(如果一定要使用,则可以用闭包解决)
function f() {
var x = 1;
x += 1;
}
x += 2;
//报错:Uncaught ReferenceError: x is not defined
- 如果两个函数使用了相同的变量名,只要在函数体内部,就不会冲突;同理,内部函数可以访问外部函数的成员,反之不可以
function f() {
var x = 1;
function f1() {
var y = x + 1;
}
}
var z = y + 1;//Uncaught ReferenceError: y is not defined
- 内外函数变量重名时,从当前函数开始,从内到外查找,假设外部存在这个同名的函数变量,则内部函数会屏蔽外部函数的变量
function f() {
var x = 1;
function f1() {
var x = x + 1;
console.log('inner->' + x);//inner->A
}
f1();
console.log('outer->' + x);//outer->1
}
f();
- 提升变量作用域
function f() {
var x='x'+y;
console.log(x);
var y = 'y';
}
//xundefined
说明:js执行引擎自动提升了y的声明,但不会提升y的赋值,相当于下面的代码:
function f() {
var y;
var x='x'+y;
console.log(x);
y = 'y';
}
规范:所有的变量定义都放在函数的头部,不能乱放,便于代码维护
- 全局函数
var x = 1;
function f() {
console.log(x);
}
console.log(x);
- 全局对象 window
var x = 'xxx';
alert(x);
alert(window.x);//默认所有的全局变量都会绑定在window对象下
alert()这个函数本身也是window的一个变量
var x = 'xxx';
window.alert(x);
var old_alert = window.alert;
//old_alert(x);
window.alert=function () {
};
//alert()失效,被手动定义的全局变量覆盖了
window.alert(123);
//恢复
window.alert = old_alert();
window.alert(456);
js实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果最终在全局作用域都没有找到,就会报错:RefrenceError
由于所有的全局变量都会绑定到window上,如果不同的js文件使用了相同的全局变量,就会产生冲突
解决方法:把自己的代码区全部放入自己定义的唯一空间名字中,降低全局命名冲突的问题
//唯一全局变量
var LinApp = {};
//定义全局变量
LinApp.name='xiaoming';
LinApp.add=function (a,b) {
return a + b;
}
- 局部作用域
function f() {
for (var i = 0; i < 100; i++) {
console.log(i);
}
console.log(i+1);
}
//问题:i出了作用域还能继续使用
解决:使用let关键字
function f() {
for (let i = 0; i < 100; i++) {
console.log(i);
}
console.log(i+1);
}
- 常量:const
const PI = 3.14;
3.3 方法
对象里面的函数就叫做方法
var tust={
name:'TUST',
birth:1958,
//方法
age:function () {
var now = new Date().getFullYear();
return now - this.birth;//this始终指向调用它的对象
}
}
//调用方法必须带()
js中控制this的指向:apply
function getAge() {
var now = new Date().getFullYear();
return now - this.birth;
}
var tust={
name:'TUST',
birth:1958,
//方法
age:getAge
};
getAge.apply(tust, []);//this指向tust这个对象,传入的参数为[]
//调用:tust.age() 或 getAge.apply(tust,[])
四、内部对象
4.1 Date
基本使用
var now = new Date();
now.getFullYear();//年
now.getMonth();//月 0~11
now.getDate();//日
now.getHours();//时
now.getMinutes();//分
now.getSeconds();//秒
now.getTime();//时间戳:从1970/1/1 00:00到现在的毫秒数
console.log(new Date(1667027327623));//通过时间戳获取时间
转换
now=new Date(1667027327623)
Sat Oct 29 2022 15:08:47 GMT+0800 (中国标准时间)
now.toLocaleString()//调用是一个方法,不是属性
'2022/10/29 15:08:47'
now.toGMTString()
'Sat, 29 Oct 2022 07:08:47 GMT'
4.2 JSON
什么是json
- JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。
- 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
js中一切皆对象,任何js支持的类型都可以用JSON表示
格式:
- 对象用{ }
- 数组用[ ]
- 所有的键值对都用key : value
JSON和JS字符串的转化:
var user={
name:'tust',
age:64,
address:'tianjin'
}
//对象转化为json字符串
var jsonuser = JSON.stringify(user);
//字符串转化为对象,参数为json字符串
var obj = JSON.parse('{"name":"tust","age":64,"address":"tianjin"}');
五、面向对象编程
6.1 原型继承
var Student={
name: "xiaoming",
age:3,
run:function () {
console.log(this.name+"run...");
}
};
var xiaohong={
name:"xiaohong"
};
var Bird={
fly:function () {
console.log(this.name+"fly...");
}
}
xiaohong.__proto__ = Bird;//小红的原型是Bird,此时具有Bird的方法,原型变为Student即可具有Student的方法
5.2 class继承
- 定义一个类
class Student{
constructor(name){
this.name = name;
}
hello(){
alert('hello')
}
}
var xiaoming=new Student("小明");
xiaoming.hello();
- 继承
class Student{
constructor(name){
this.name = name;
}
hello(){
alert('hello')
}
}
class pupil extends Student{
constructor(name, grade) {
super(name);
this.grade = grade;
}
mygrade(){
alert("我是小学生");
}
}
var xiaohong = new pupil("小红");
本质:查看对象原型
六、操作BOM对象
BOM:浏览器对象模型
6.1 window
window代表浏览器窗口
window.innerWidth
680
window.innerHeight
728
//调整浏览器窗口后该值也会随之变化
6.2 Navigator
Navigator:封装了浏览器的信息
navigator.appName
'Netscape'
navigator.appVersion
'5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'
navigator.platform
'Win32'
navigator.userAgent
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'
一般情况不使用navigator,因为会被认人为修改
6.3 screen
screen.width
1549
screen.height
872
6.4 location(重要)
location:代表当前页面的URL信息
host:主机
herf:当前指向的位置
protocol:协议
reload():刷新网页
//设置新的地址
location.assign(链接)//可以跳转到对应链接
6.5 document
document:代表当前页面的内容
document.title
'Title'
document.title='tust'
'tust'
获取具体的文档树节点
<dl id="app">
<dt>Java</dt>
<dd>JavaSE</dd>
<dd>JavaEE</dd>
</dl>
<script>
var dl = document.getElementById('app');
</script>
获取网页cookie(客户端本地信息),cookie被劫持后隐私就会暴露,服务器端可以设置cookie为httpOnly以保证安全
document.cookie
'isg=BI-P4esghvm-FjIKHjjhfbvgdGd9_4FcK9yqYATJyt56fnj'
6.6 history
history:浏览器的历史记录(不建议使用)
history.back()//网页后退
history.forward()//网页前进
七、操作Dom对象(重点)
7.1 核心
浏览器网页就是一个Dom树形结构
- 更新:更新Dom节点
- 遍历:得到Dom节点
- 删除:删除一个Dom节点
- 添加:添加一个新的节点
要操作一个Dom节点,就必须要获得这个Dom节点:
//对应css选择器
var h1 = document.getElementsByTagName("h1");
var p2 = document.getElementById("p1");
var p2 = document.getElementsByClassName("p2");
var father = document.getElementById("father");
var childrens=father.children;//获取父节点下的所有子节点
father.lastChild;
father.firstChild;
这是原生代码,之后尽量使用 jQuery();
7.2 更新节点
- 修改文本值:innerText
- 解析HTML文本标签:innerHTML
- 设置css属性:style.属性
<div id="id1"></div>
<script>
var id1 = document.getElementById('id1');
id1.innerText=123//修改文本的值
id1.innerHTML='<strong>234</strong>'//可以解析HTML文本标签
id1.style.color='blue'
</script>
7.3 删除节点
步骤:先获取父节点,再通过父节点删除自己
<div id="father">
<h1>标题一</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
</div>
<script>
var self = document.getElementById("p1");
var father=p1.parentElement;
father.removeChild(self);
father.removeChild(father.children[0])
//该方法删除多个属性时,下标会动态更新,删除时要注意。
</script>
7.4 插入节点
获得了某个Dom节点后,如果该Dom节点是空的,我们通过innerHTML就可以增加一个元素了,但是如果这个Dom已经存在了元素,就不能这样操作了,因为会覆盖之前的元素
- 追加:append
<p id="js">JavaScript</p>
<div id="list">
<p id="se">JavaSE</p>
<p id="ee">JavaEE</p>
<p id="me">JavaME</p>
</div>
<script>
var js = document.getElementById('js');//获取节点
var list = document.getElementById('list');
list.appendChild(js)//将js移到div内部
</script>
- 创建一个新的标签实现插入
<script>
var js = document.getElementById('js');//获取节点
var list = document.getElementById('list');
//通过JS创建一个新的节点
var newP = document.createElement('p');//创建一个P标签
newP.id = 'newP';//给创建的标签的id赋值
newP.innerText = 'Hello TUST';
//创建一个标签节点(通过该属性可以设置任意的值)
var myScript = document.createElement('script');
myScript.setAttribute('type', 'textJavaScript');
//创建一个style标签
var myStyle = document.createElement('style');//创建了一个空style标签
myStyle.setAttribute('type', 'text/css');
myStyle.innerHTML = 'body{background-color:black;}';//设置标签内容
document.getElementsByTagName('head')[0].appendChild(myStyle)
</script>
- 插入到前面
var ee = document.getElementById('ee');
var se = document.getElementById('se');
var js = document.getElementById('js');
var list = document.getElementById('list');
//要包含的节点:insertBefore(newNode,targetNode),把newNode插入到targetNode前面
list.insertBefore(ee,se);
八、操作表单(验证)
8.1 什么是表单
表单:form Dom树
- 文本框:text
- 下拉框:select
- 单选框:radio
- 多选框:check
- 隐藏域:hidden
- 密码框:password
- …
目的:提交信息
8.2 获得要提交的信息
<form action="post">
<p>
<span>用户名:</span><input type="text"id="username">
</p>
<!--多选框的值是定义好的value-->
<p>
<span>性别:</span>
<input type="radio" name="sex" value="man"id="boy">男
<input type="radio" name="sex" value="women"id="girl">女
</p>
</form>
<script>
var input_text = document.getElementById("username");
var boy_radio = document.getElementById("boy");
var girl_radio = document.getElementById("girl");
//得到输入框的值:
input_text.value
//修改输入框的值:
input_text.value="xxxxxxxxxx"
//对于单选框、多选框等固定的值,.value只能取到当前的值,要查看是否被选中,应该使用.checked
boy_radio.checked;//True说明被选中,反之为False,也可以通过给checked赋值来进行选择
</script>
8.3 提交表单
MD5加密
<form action="https://www.bilibili.com/"method="post"onsubmit="return aaa()">
<p>
<span>用户名:</span><input type="text"id="username"name="username">
</p>
<p>
<span>密码:</span><input type="password"id="input-password">
</p>
<input type="hidden"id="md5.password"name="password">
<!--绑按钮定事件-->
<button type="submit" onclick="aaa()">提交</button>
</form>
<script>
function aaa() {
var username = document.getElementById('username');
var password = document.getElementById('password');
var md5password = document.getElementById('md5-password');
md5password.value=md5(password.value);
return false;
}
</script>
九、jQuery
JavaScript和jQuery的关系:jQuery库中存在大量JavaScript函数
9.1 获取jQuery
- 引入jQuery
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--cdn引入-->
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
<!--本地引入-->
<script src="lib/jquery-3.6.1.js"></script>
</head>
<body>
<!--
公式:$(selector).action
选择器就是css选择器
-->
<a href="" id="test-jquery">点我</a>
<script>
document.getElementById('id');
$('#test-jquery').click(function () {
alert('hello jquery');
})
</script>
</body>
</html>
9.2 选择器
//原生js,选择器少,麻烦不好记
//标签
document.getElementsByTagName();
//id
document.getElementById();
//类
document.getElementsByClassName();
//jQuery选择器:css中的选择器均可使用
$('p').click()//标签选择器
$('#').click()//id选择器
$('.class').click()//class选择器
jQueryAPI帮助文档:https://jquery.cuishifeng.cn/
9.3 事件
鼠标事件、键盘事件、其他事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="lib/jquery-3.6.1.js"></script>
<style>
#divMove {
width: 500px;
height: 500px;
border: 1px solid red;
}
</style>
</head>
<body>
<!--获取鼠标当前坐标-->
mouse:<span id="mouseMove"></span>
<div id="divMove">
在这里移动鼠标
</div>
<script>
//当网页元素加载完毕之后响应事件
$(function () {
$('#divMove').mousemove(function (e) {
$('#mouseMove').text('x:' + e.pageX + 'y:' + e.pageY);
})
})
</script>
</body>
</html>
9.4 操作Dom
- 节点文本操作
$('#test-ul li[name=py]').text();//test后面的括号里有值代表修改值,没值代表获取值
$('#test-ul').html();//设置值与获取值的规则同上
- css操作
$('#test-ul li[name=py]').css('color','red')
-
元素的显示和隐藏
本质:display:none
$('#test-ul li[name=py]').hide();//hide为隐藏,show为显示