【前端】JavaScript

JavaScript

JavaScript是一门世界上最流行的脚本语言。ECMAScript可以理解为是JavaScript的一个标准

引入 JavaScript

  1. 内部标签
1
2
3
4
<!--Script标签内,写JavaScript代码-->
<script>
....
</script>
  1. 外部引入
1
<script src="js/helloworld.js"></script>

基本语法

1
2
3
4
5
6
7
8
9
10
11
12
<!--Script标签内,写JavaScript代码-->
<script>
// alert('hello world');
var score = 1;
if (score > 60){
alert(true);
} else {
alert(false);
}
// console.log() 在浏览器的控制台打印变量

</script>

严格检查格式

'use strict'; 严格检查模式,必须写在JavaScript第一行,防止JavaScript不严谨的语法误用。(前提:IDEA需要设置支持ES6语法)

数据类型

JavaScript数据类型包括:数值、文本、图形、音频、视频。

所有变量类型都是var / let

1
2
var num;
let num; //(推荐)局部变量建议使用let定义

number

JavaScript不区分小数和整数

1
2
3
4
123      // 整数
123.1 // 浮点数
1.123e4 // 科学计数法
NaN // not a number

字符串

1
2
3
var str1 = 'abc';
var str2 = "abc";
var str3 = `abc ${str1}`;

比较运算符

1
2
3
=    // 赋值
== // 等于(类型不一样,值一样,也会判断为true)
=== // 绝对等于(类型一样,值一样,才会判断为true)

注意:

  • NaN===NaN,这个与所有数值都不相等,包括自己
  • 只能通过isNaN(NaN)判断是否为NaN

null 和 undefined

  • null:空
  • undefined:未定义

数组

1
var arr = [1,2,3,4,5,'hello',null,true];

取数组下标如果越界了,则返回undefined

常用方法:

  • indexOf():获取某元素对应的索引
  • slice():截取Array的一部分,返回一个新数组
  • push():向尾部压入一个数据
  • pop():弹出尾部的一个元素
  • unshift():向头部压入数据
  • shift():弹出头部的第一个数据
  • sort():排序
  • reverse():元素反转
  • concat():连接数组
  • join():打印使用特定字符串连接后的数组

对象

对象是大括号,数组是中括号。每个属性之间使用逗号隔开,最后一个不需要

1
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
var person = {
name: "zhangsan",
age: 13,
tags:['js', 'java', 'web']
}

// 查看某属性对应的值
person.name
> "zhangsan"

// 删除属性
delete person.name
> true

// 赋值
person.name = "lisi"

// 动态添加
person.newAttribute = "new attribute"

// 判断某属性是否在这个对象中 xxx in xxx
'name' in person
> true
person.hasOwnProperty('toString')
> true

// 判断一个属性是否是这个对象自身拥有的 hasOwnProperty()
person.hasOwnProperty('toString')
> false
person.hasOwnProperty('name')
> true

Map 和 Set

Map:可重复的键值对集合

1
2
3
4
5
var map = new Map([['tom', 100], ['jack', 90]]);
var name = map.get('tom');
map.set('admin', 123456);
map.delete('tom');
console.log(name);

Set:无序不重复的集合

1
2
3
4
var set = new Set([1,3,3,2,2]);
set.add(4);
set.delete(1);
console.log(set.has(3));

iterator

遍历数组

1
2
3
4
5
6
7
8
9
10
11
12
13
// in:取索引
var arr = [3, 4, 5];
for (var x in arr) {
console.log(x);
}
> 0 1 2

// of:取元素值
var arr = [3, 4, 5];
for (let x of arr) {
console.log(x);
}
> 3 4 5

遍历Map

1
2
3
4
var map = new Map([['tom', 100], ['jack', 90]]);
for (let x of map){
console.log(x);
}

遍历Set

1
2
3
4
var set = new Set([5, 6, 7]);
for (let x of set){
console.log(x);
}

函数

定义函数

定义方式一

1
2
3
4
5
6
7
function abs(x) {
if (x >= 0) {
return x;
} else {
return -x;
}
}

定义方式二

1
2
3
4
5
6
7
var abs = function(x){
if (x >= 0) {
return x;
} else {
return -x;
}
}

function(x){....}是一个匿名函数。但是可以把结果赋值给abs,通过abs就可以调用函数。

调用函数

1
2
abs(10);
abs(-10);

参数问题:JavaScript可以传任意个参数,也可以不传参数(返回undefined)。假设不传入参数,需要手动判断:

1
2
3
4
5
6
7
8
9
10
11
var abs = function(x){
// 手动抛出异常
if (typeof x !== 'number') {
throw 'not a number';
}
if (x >= 0) {
return x;
} else {
return -x;
}
}

arguments

代表传递进来的所有参数,是一个数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}
}

rest

ES6引入的新特性,获取除了已经定义的参数外的所有参数

1
2
3
4
5
function test(a, b, ...rest) {
console.log("a=>" + a);
console.log("b=>" + b);
console.log(rest);
}

变量的作用域

在JavaScript中,var定义变量实际是有作用域的。假设在函数体中声明,则在函数体外不可以使用。内部函数可以访问外部函数的成员变量,反之不行。

1
2
3
4
5
function test() {
var x = 1;
}

x = x + 2; // Uncaught Reference

提升变量的作用域

JavaScript执行引擎会先定义所有全局变量,然后按顺序赋值。

全局变量

放在函数外面的变量都是全局变量。默认所有的全局变量,都会自动绑定在window对象上.

1
2
3
var x = 'xxx';
alert(x);
alert(window.x);

JavaScript实际上只有一个全局作用域(window对象),任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域(windows对象中)都没找到,报错ReferenceError

规范

由于所有的全局变量都会绑定到window上,如果不同的js文件,使用了相同的全局变量,就会发生冲突。为避免冲突,可使用自定义唯一全局变量。

1
2
3
4
5
6
7
8
// 唯一全局变量
var MyApp = {};

// 定义全局变量
MyApp.name = "zhangsan";
MyApp.add = function (a, b) {
return a + b;
}

将自己的代码全部放入自定义的唯一空间名中,降低全局命名冲突的问题

局部作用域 let

ES6 let关键字,解决局部作用域冲突问题

常量 const

ES6 const关键字

1
const PI = '3.14';

方法

定义方法

方法就是把函数放在对象的里面,对象只有两个东西:属性和方法

1
2
3
4
5
6
7
8
9
10
11
12
var person = {
name: "zhangsan";
birth: 2020;
age: function() {
// 今年-出生的年
let now = new Date().getFullYear();
return now - this.birth;
}
}

person.name;
person.age();

内部对象

JSON

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。在JavaScript中一切即为对象,任何js支持的类型都可以用JSON表示。格式:

  • 对象用{ }
  • 数组用[ ]
  • 所有的键值对用key: value

JSON字符串和JS对象的转换:

1
2
3
4
5
6
7
8
9
10
var user = {
name: "zhangsan",
age: 3
}

// 对象转化为json字符串
var jsonUser = JSON.stringify(user);

// json字符串转换为对象
var obj = JSON.parse('{"name": "zhangsan", "age": 3});

面向对象编程

  • 类:模板,原型对象
  • 对象:具体的实例

原型对象

语法:childObj.__proto__ = parentObj。子对象的原型是父对象,可获得父对象的方法。

class继承

class关键字,是在ES6引入的。

  1. 定义一个类,包含属性和方法
1
2
3
4
5
6
7
8
9
10
11
12
13
class Student {
constructor(name) {
this.name = name;
}

hello() {
alert('hello');
}
}

// 创建对象
var xiaoming = new Student("xiaoming");
xiaoming.hello();
  1. 继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class PrimaryStudent extends Student {
constructor(name, grade) {
super(name);
this.grade = grade;
}

myGrade() {
alert(".....");
}
}

var xiaoming = new Student("xiaoming");
var xiaohong = new PrimaryStudent("xiaohong", 3);

xiaohong.myGrade();

原型链

__ proto __:Object()的原型对象还是Object()对象。

操作 BOM 对象

BOM:浏览器对象模型。

window

window代表浏览器窗口。

Navigator

Navigator封装了浏览器的信息。

screen

screen代表屏幕属性。

location

location代表当前界面的URL信息。

1
2
3
4
5
6
7
host: "www.baidu.com"
href:"http://www.baidu.com/"
protocol:"https:"
reload:f reload() 刷新网页

// 设置新的地址,网页会跳转到指定为地址
location.assign('https://xxxxx')

document

document代表当前页面

1
document.title // 当前页面的标题

获取具体的文档树节点

1
document.getElementById('id');

获取cookie

1
document.cookie

history

1
2
history.back()    // 后退
history.forward() // 前进

操作 DOM 对象

DOM:文档对象模型。浏览器网页就是一个DOM属性结构。

  • 更新:更新DOM节点
  • 遍历:遍历得到DOM节点
  • 删除:删除DOM节点
  • 添加:添加新DOM节点

获得DOM节点

1
2
3
4
5
6
var h1 = document.getElementsByTagName('h1');
var p1 = document.getElementsById('p1');
var p2 = document.getElementsByClassName('p2');
var father = document.getElementsByTagName('father');

var children = father.children;

更新DOM节点

1
2
3
4
5
<div id='id1'> </div>

<script>
var id1 = document.getElementsById('id1');
</script>

操作文本

1
2
id1.innerText = '456' // 修改文本的值
id1.innerHTML = '<strong>123</strong>'

操作JS

1
2
id1.style.color = 'red';
id1.style.fontSize = '20px';

删除节点

步骤:获取父节点 ——> 通过父节点删除自己

1
2
3
var self = document.getElementById('p1');
var father = p1.parentElement;
father.removeChild(self);

插入节点:appendChild

1
2
3
var js = document.getElementById('js');
var list = document.getElementById('list');
list.appendChild(js);

插入节点:insert

1
2
// 要包含的节点.insertBefore(newNode, targetNode)
list.insertBefore(js, ee);

操作表单

表单:form DOM树

  • 文本框 text
  • 下拉框 select
  • 单选框 radio
  • 多选框 checkbox
  • 隐藏域 hidden
  • 密码框 password

表单的作用:提交信息

获得要提交的信息

1
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
<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="woman" 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 = '123'

boy_radio.checked; // 查看是否被选中
girl_radio.checked = true; // 设置被选中
</script>

事件

静态注册事件

在html标签中直接添加事件的响应函数,并在js文件中定义函数内容,这样既可在触发html标签事件时执行相应的响应函数。

1
2
3
4
5
6
7
<script type="text/javascript">
function onclickFun() {
...
}
</script>

<button onclick="onclickFun();">

动态注册事件

网页加载后就注册好事件。这样每次检测到事件被触发就会执行响应函数

1
2
3
4
5
6
window.onload = function() {
var btnObj = document.getElementById("btn01");
btnObj.onclick = function() {
...
}
}

JQuery

jQuery库,里面存在大量的JavaScript函数,用于简化开发。

jQuery的本质:jQuery对象是DOM对象的数组 + jQuery提供的一系列功能函数。其会将查询到的符合条件的DOM对象封装成一个数组存放并附加一些功能函数。

jQuery对象和DOM对象互相转换:

  • DOM转jQuery:var $obj= $(DOM对象)
  • jQuery转DOM:var dom = $obj[下标]

公式:$(选择器).事件(响应函数)

1
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>

<!-- 导入jQuery -->
<script src="lib/jquery-3.6.0.js"></script>
</head>
<body>

<!--
公式:$(selector).action()
selector就是css的选择器
-->

<a href="" id="test-jquery">点我</a>

<script>
document.getElementById('id');
$('#test-jquery').click(function(){
alert('hello, jQuery');
})
</script>

</body>
</html>

选择器

1
2
3
$('p').click(); // 标签选择器
$('#id1').click(); // id选择器
$('.class1').click(); // class选择器

事件

  • 鼠标事件
  • 键盘事件
  • 其他事件
1
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="lib/jquery-3.6.0.js"></script>
<style>
#divMove{
width: 500px;
height: 500px;
border: 1px solid red;
}
</style>
</head>
<body>

<!--
公式:$(selector).action()
selector就是css的选择器
-->
mouse: <span id="mouseMove"></span>
<div id="divMove">
在这里移动鼠标试试
</div>

<script>
document.getElementById('id');
$('#test-jquery').click(function(){
alert('hello, jQuery');
})

// 当网页元素加载完毕之后响应事件
$(function(){
$('#divMove').mousemove(function (e) {
$('#mouseMove').text(' x: '+e.pageX + ' y: '+e.pageY)
});
})

</script>

</body>
</html>

操作DOM

节点文本操作

1
2
3
4
5
6
7
// 获得值
$('#test-ul li[name=cpp]').text();
$('#test-ul').html();

// 设置值
$('#test-ul li[name=cpp]').text('c');
$('#test-ul').html('xxx');

css操作

1
$('#test-ul li[name=cpp]').css("color:red");

元素的显示和隐藏。本质:display: none

1
2
$('#test-ul li[name=cpp]').show()
$('#test-ul li[name=cpp]').hide()