JavaScript学习
1、什么是JavaScript
JavaScript是一种运行在浏览器中的解释型的编程语言。
1.1 引入JavaScript
* JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到head 中:由<script>...</script> 包含的代码就是JavaScript代码,它将直接被浏览器执行。
* 第二种方法是把JavaScript代码放到一个单独的.js文件,然后在HTML中通过
引入这个文件:
1.2 调试
- 安装Google Chrome浏览器,点击“控制台(Console)“,在这个面板里可以直接输入JavaScript代码,按回车后执行。
- 要查看一个变量的内容,在Console中输入console.log(a); ,回车后显示的值就是变量的内容。
2、快速入门
2.1 基本语法
* JavaScript的语法和Java语言类似,每个语句以; 结束,语句块用{...} 。
* JavaScript严格区分大小写,如果弄错了大小写,程序将报错或者运行不正常。
2.2 数据类型和变量
-
Number
JavaScript不区分整数和浮点数
-
字符串
JavaScript的字符串就是用 ’ ’ 或 " " 括起来的字符表示
-
多行字符串
`这是一个 多行 字符串`;
-
模板字符串
var name = '小明'; var age = 20; var message = `你好, ${ name}, 你今年${ age}岁了!`; alert(message);
-
字符串长度
str.length
-
字符串不可变
-
-
布尔值
-
比较运算
特别注意相等运算符== 。JavaScript在设计时,有两种比较运算符:
第一种是 == 比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果;
第二种是 === 比较,它不会自动转换数据类型,如果数据类型不一致,返回false ,如果一致,再比较。
由于JavaScript这个设计缺陷,不要使用== 比较,始终坚持使用=== 比较。 -
null和undefined
-
数组
JavaScript的数组可以包括任意数据类型
var arr = [1, 2, 3.14, 'Hello', null, true];
-
数组长度
arr.length
注意:如果给arr.length赋值,数组大小会发生变化。如果赋值过小,则数据会丢失。
-
indexof,通过元素获取下标索引
-
slice() 截取数组的一部分,返回一个新的数组
var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G']; arr.slice(0, 3); // 从索引0开始,到索引3结束,但不包括索引3: ['A', 'B', 'C'] arr.slice(3); // 从索引3开始到结束: ['D', 'E', 'F', 'G']
-
push,pop
push:压入到尾部
pop:弹出尾部的一个元素
-
unshift和shift
unshift:压入到头部
shift:删除第一个元素
-
sort 数组排序
-
reverse 数组反转
-
concat 数组连接
-
…
-
-
对象
- avaScript的对象是一组由键-值组成的无序集合
var person = { name: 'Bob', age: 20, tags: ['js', 'web', 'mobile'], city: 'Beijing', hasCar: true, zipcode: null };
- 要获取一个对象的属性,我们用对象变量.属性名的方式:
person.name; // 'Bob' person.zipcode; // null
-
对象添加或删除属性
delete xiaoming.age; // 删除age属性
-
in 操作符,检测对象是否拥有某一属性
-
变量
可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,但是要注意只能用var 申明一次
2.3 strict模式
-
如果一个变量没有通过var 申明就被使用,那么该变量就自动被申明为全局变量
-
strict模式下运行的JavaScript代码,强制通过 var 申明变量,未使用 var 申明变量就使用的,将导致运行错误。
-
启用strict模式的方法是在JavaScript代码的第一行写上,且 IEDA 需要设置支持ES6语法
'use strict'; // 严格检查格式,必须写在JavaScript代码的第一行 // 局部变量建议都是用 let 去定义
2.4 流程控制
-
for … in ,依次循环对象的所有属性:
var o = { name: 'Jack', age: 20, city: 'Beijing' }; for (var key in o) { if (o.hasOwnProperty(key)) { console.log(key); // 'name', 'age', 'city' } }
注意:由于 Array 也是对象,而它的每个元素的索引被视为对象的属性,所以遍历出来是下标
for … in 对Array 的循环得到的是String 而不是Number 。
2.5 Map 和 Set
- Map
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95
m.set('Bob', 59);
m.has('Adam');
m.delete('Adam');
一个key只能对应一个value,多次对一个key放入value,后面的值会把前面的值冲掉
-
Set
Set 中 Key 不能重复,重复元素再 Set 中自动被过滤
var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
s.add(4);
s.delete(3);
2.6 Iterable
-
遍历数组或者集合,可以都试用for … of来遍历元素
var a = ['A', 'B', 'C']; var s = new Set(['A', 'B', 'C']); var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]); for (var x of a) { // 遍历Array console.log(x); } for (var x of s) { // 遍历Set console.log(x); } for (var x of m) { // 遍历Map console.log(x[0] + '=' + x[1]); }
-
直接使用iterable 内置的forEach 方法,它接收一个函数,每次迭代就自动回调该
函数。a.forEach(function (element, index, array) { // element: 指向当前元素的值 // index: 指向当前索引 // array: 指向Array对象本身 console.log(element + ', index = ' + index); });
数组迭代:
a.forEach(function (element, index, array) { // element: 指向当前元素的值 // index: 指向当前索引 // array: 指向Array对象本身 console.log(element + ', index = ' + index); });
Set没有索引,因此回调函数的前两个参数都是元素本身:
var s = new Set(['A', 'B', 'C']); s.forEach(function (element, sameElement, set) { console.log(element); });
Map 的回调函数参数依次为value 、key 和map 本身:
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]); m.forEach(function (value, key, map) { console.log(value); });
3、函数
3.1 函数定义和调用
定义方式一
function abs(x) {
if (x >= 0) {
return x;
} else {
return -x;
}
}
定义方式二
var abs = function (x) {
if (x >= 0) {
return x;
} else {
return -x;
}
};
调用函数
JavaScript允许传入任意个参数而不影响调用,可以传入的参数比定义的多也可以少:
abs(10, 'blablabla'); // 返回10
abs(); // 返回NaN,参数 x 将收到undefined
要避免收到undefined ,可以对参数进行检查:
function abs(x) {
if (typeof x !== 'number') {
throw 'Not a number';
}
if (x >= 0) {
return x;
} else {
return -x;
}
}
arguments
利用arguments ,你可以获得调用者传入的所有参数,即使函数不定义任何参数,也可以拿到参数的值:
function foo(x) {
console.log('x = ' + x); // 10
for (var i=0; i<arguments.length; i++) {
console.log('arg ' + i + ' = ' + arguments[i]); // 10, 20, 30
}
}
可用于判断传入参数的个数:
function abs() {
if (arguments.length === 0) {
return 0;
}
var x = arguments[0];
return x >= 0 ? x : -x;
}
rest 参数
ES6引入的新特性,获取已经定义的参数之外的所有参数,保存在rest数组中:
function foo(a, b, ...rest) {
console.log('a = ' + a);
console.log('b = ' + b);
console.log(rest);
}
3.2 变量的作用域
提升变量的作用域
js 执行引擎,自动提升了 y 的声明,但是不会提升 y 的赋值:
function foo() {
var x = 'Hello, ' + y;
console.log(x);
var y = 'Bob';
}
养成规范:所有的变量定义都放在函数的头部
全局作用域
不在任何函数内定义的变量就具有全局作用域,JavaScript默认有一个全局对象window ,全局作用域的变量实际上被绑定到window 的一个属性。
JavaScript实际上只有一个全局作用域。任何变量(函数也视为变量),如果没有在当前函数作用域中找到,就会继续往上查找,最后如果在全局作用域中也没有找到,则报ReferenceError 错误。
// 唯一的全局变量MYAPP:
var MYAPP = {
};
// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;
// 其他函数:
MYAPP.foo = function () {
return 'foo';
};
把自己的代码全部放入唯一的名字空间MYAPP 中,会大大减少全局变量冲突的可能。
3.3 方法
方法定义一
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var y = new Date().getFullYear();
return y - this.birth;
}
}
this 是一个特殊变量,它始终指向当前对象
方法定义二
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
注意:如果单独调用函数,比如getAge() ,此时,该函数的this 指向全局对象,也就是window 。
apply
apply 方法可以控制 this 指向哪个对象,第一个参数就是需要绑定的this 变量,第二个参数是Array ,表示函数本身的参数。
xiaoming.age(); // 25
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
4、标准对象
4.1 标准对象
JavaScrip 一切都是对象,可以用 typeof 操作符获取对象的类
型,它总是返回一个字符串:
typeof 123; // 'number'
typeof NaN; // 'number'
typeof 'str'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof Math.abs; // 'function'
typeof null; // 'object'
typeof []; // 'object'
typeof {
}; // 'object'
4.2 Date
Date 对象用来表示日期和时间:
var now = new Date();
now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
now.getFullYear(); // 2015, 年份
now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
now.getDate(); // 24, 表示24号
now.getDay(); // 3, 表示星期三
now.getHours(); // 19, 24小时制
now.getMinutes(); // 49, 分钟
now.getSeconds(); // 22, 秒
now.getMilliseconds(); // 875, 毫秒数
now.getTime(); // 1435146562875, 以number形式表示的时间戳
4.3 JSON
- JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式
- 采用完全独立于编程语言的文本格式来存储和表示数据。
- 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
语法格式:
任何JavaScript 支持的类型都可以通过 JSON 来表示
- 对象表示为键值对,数据由逗号分隔
- 花括号{}保存对象
- 方括号[]保存数组
JSON 是 JavaScript 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
var obj = {
a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹
的
var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个
字符串
JSON 和 JavaScript 对象互转
- 要实现从JSON字符串转换为JavaScript 对象,使用 JSON.parse() 方法:
var obj = JSON.parse('{"a": "Hello", "b": "World"}');
//结果是 {a: 'Hello', b: 'World'}
- 要实现从JavaScript 对象转换为JSON字符串,使用 JSON.stringify() 方法:
var json = JSON.stringify({
a: 'Hello', b: 'World'});
//结果是 '{"a": "Hello", "b": "World"}'
5、面向对象编程
面向对象
- 类:类是对象的类型模板
- 对象:根据类创建的实例
JavaScript不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程。
原型
在JavaScript中,每个函数都有一个prototype属性,这个属性指向函数的原型对象。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qCrtTq7J-1606011511576)(C:\Users\JieMe\AppData\Roaming\Typora\typora-user-images\image-20201023102441034.png)]
class
原生的写法:
function Student(name) {
this.name = name;
}
// 现在要给这个Student新增一个方法
Student.prototype.hello = function () {
alert('Hello, ' + this.name + '!');
}
用新的class 关键字来编写Student:
class Student {
constructor(name) {
this.name = name;
}
hello() {
alert('Hello, ' + this.name + '!');
}
}
var xiaoming = new Student('小明');
xiaoming.hello();
class 继承
class PrimaryStudent extends Student {
constructor(name, grade) {
super(name); // 记得用super调用父类的构造方法!
this.grade = grade;
}
myGrade() {
alert('I am at grade ' + this.grade);
}
}
6、操作BOM
浏览器介绍
BOM:浏览器对象模型 (内核)
- IE6~11 (windows)
- Chrome (windows)
- Safari (苹果)
- FireFox (linux)
window
window 对象不但充当全局作用域,而且表示浏览器窗口。
location
location 对象表示当前页面的URL信息。
Document
document 对象表示当前页面。由于HTML在浏览器中以DOM形式表示为树形结构, document 对象就是整个DOM树的根节点。
用document 对象提供的getElementById() 和getElementsByTagName() 可以按ID获得一个DOM节点和按Tag名称获得一组DOM节点:
<dl id="code-menu" style="border:solid 1px #ccc;padding:6px;">
<dt>Java</dt>
<dd>Spring</dd>
<dt>Python</dt>
<dd>Django</dd>
<dt>Linux</dt>
<dd>Docker</dd>
</dl>
var menu = document.getElementById('code-menu');
var drinks = document.getElementsByTagName('dt');
var i, s;
s = '提供的饮料有:';
for (i=0; i<drinks.length; i++) {
s = s + drinks[i].innerHTML + ',';
}
console.log(s);
cookie
document.cookie; // 'v=123; remember=1 true; prefer=zh'
劫持cookie原理
JavaScript能读取到页面的Cookie,而用户的登录信息通常也存在Cookie中。
服务器在设置Cookie时可以使用httpOnly ,设定了httpOnly 的Cookie将不能被JavaScript读取。
7、操作Dom对象
7.1 选择器
DOM就是一个树形结构:
- 更新:更新该DOM节点的内容,相当于更新了该DOM节点表示的HTML的内容;
- 遍历:遍历该DOM节点下的子节点,以便进行进一步操作;
- 添加:在该DOM节点下新增一个子节点,相当于动态增加了一个HTML节点;
- 删除:将该节点从HTML中删除,相当于删掉了该DOM节点的内容以及它包含的所有子节点。
获取DOM节点方式
document.getElementById() document.getElementsByTagName()
document.getElementsByClassName()
7.2 更新DOM
修改节点的文本
一种是修改innerHTML 属性:
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置文本为abc:
p.innerHTML = 'ABC'; // <p id="p-id">ABC</p>
// 设置HTML:
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
// <p>...</p>的内部结构已修改
第二种是修改innerText 属性:
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置文本:
p.innerText = '<script>alert("Hi")</script>';
// HTML被自动编码,无法设置一个<script>节点:
// <p id="p-id"><script>alert("Hi")</script></p>
修改节点的CSS
DOM节点的style 属性对应所有的CSS,可以直接获取或设置。
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置CSS:
p.style.color = '#ff0000';
p.style.fontSize = '20px'; //需要将-去掉,改为驼峰命名
p.style.paddingTop = '2em';
7.3 插入DOM
appendChild
插入新的DOM节点
insertBefore
将节点插入指定位置
7.4 删除DOM
要删除一个节点,首先要获得该节点本身以及它的父节点,然后调用父节点的removeChild 把自己删掉:
// 拿到待删除节点:
var self = document.getElementById('to-be-removed');
// 拿到父节点:
var parent = self.parentElement;
// 删除:
var removed = parent.removeChild(self);
removed === self; // true
注意:删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置。
8、操作表
8.1 回顾
HTML表单的输入控件主要有以下几种:
- 文本框,对应的 ,用于输入文本;
- 口令框,对应的 ,用于输入口令;
- 单选框,对应的 ,用于选择一项;
- 复选框,对应的 ,用于选择多项;
- 下拉框,对应的 ,用于选择一项;
- 隐藏文本,对应的 ,用户不可见,但表单提交时会把隐藏文本发送到服务器。
8.2 获取值
对于单选框和复选框应该用 checked 判断
var mon = document.getElementById('monday');
var tue = document.getElementById('tuesday');
mon.value; // '1'
tue.value; // '2'
mon.checked; // true或者false
tue.checked; // true或者false
8.3 设置值
对于单选框和复选框,设置checked 为true 或false 即可。
// <input type="text" id="email">
var input = document.getElementById('email');
input.value = '[email protected]'; // 文本框的内容已更新
8.4 提交表单
浏览器默认点击 时提交表单,或者用户在最后一个输入框按回车键。响应 本身的onsubmit 事件,在提交form时作修改:
<!-- HTML -->
<form id="test-form" onsubmit="return checkForm()">
<input type="text" name="test">
<button type="submit">Submit</button>
</form>
<script>
function checkForm() {
var form = document.getElementById('test-form');
// 可以在此修改form的input...
// 继续下一步:
return true;
}
</script>
注意:要用 return true 来告诉浏览器继续提交,如果return false ,浏览器将不会继续提交
form,这种情况通常对应用户输入有误,提示用户错误信息后终止提交form。
md5加密密码,表单优化
要想不改变用户的输入,可以利用 实现:
<script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js">
</script>
<!-- HTML -->
<form id="login-form" method="post" onsubmit="return checkForm()">
<input type="text" id="username" name="username">
<input type="password" id="input-password">
<input type="hidden" id="md5-password" name="password">
<button type="submit">Submit</button>
</form>
<script>
function checkForm() {
var input_pwd = document.getElementById('input-password');
var md5_pwd = document.getElementById('md5-password');
// 把用户输入的明文变为MD5:
md5_pwd.value = md5(input_pwd.value);
// 继续下一步:
return true;
}
</script>
9、jQuery
9.1 什么是jQuery
jQuery库,里面存在大量的JavaScript函数。
使用jQuery只需要在页面的head 引入jQuery文件即可:
公式: $(selector).action()
- 美元符号定义 jQuery
- 选择符(selector)“查询"和"查找” HTML 元素
- jQuery 的 action() 执行对元素的操作
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<title>Title</title>
<script src="lib/jquery-3.4.1.js"></script>
</head>
<body>
<a href="" id = "test-jquery">点我</a>
<script>
//选择器就是css选择器
$('#test-jquery').click(function(){
alert('hello,jQuery!');
});
</script>
</body>
</html>
9.2 选择器
//jQuery css中的选择器它全部都能用!
$('p').click(); //标签选择器
$('#id1').click(); //id选择器
$('.class1').click; //class选择器
var email = $('[name=email]'); //按属性查找
文档工具站:http://jquery.cuishifeng.cn/
9.3 操作DOM
修改Text和HTML
- 获取文本和HTML:
<!-- HTML结构 -->
<ul id="test-ul">
<li class="js">JavaScript</li>
<li name="book">Java & JavaScript</li>
</ul>
$('#test-ul li[name=book]').text(); // 'Java & JavaScript'
$('#test-ul li[name=book]').html(); // 'Java & JavaScript'
- 设置文本或HTML:
var j1 = $('#test-ul li.js');
var j2 = $('#test-ul li[name=book]');
j1.html('<span style="color: red">JavaScript</span>');
j2.text('JavaScript & ECMAScript');
修改CSS
<!-- HTML结构 -->
<ul id="test-css">
<li class="lang dy"><span>JavaScript</span></li>
<li class="lang"><span>Java</span></li>
<li class="lang dy"><span>Python</span></li>
<li class="lang"><span>Swift</span></li>
<li class="lang dy"><span>Scheme</span></li>
</ul>
$('#test-css li.dy>span').css('background-color', '#ffd351').css('color','red');
var div = $('#test-div');
div.css('color'); // '#000033', 获取CSS属性
div.css('color', '#336699'); // 设置CSS属性
div.css('color', ''); // 清除CSS属性
显示和隐藏DOM
var a = $('a[target=_blank]');
a.hide(); // 隐藏
a.show(); // 显示
9.4、事件
jQuery能够绑定的事件主要包括:
鼠标事件、键盘事件,其他事件
mousedown()(jQuery)----按下
mouseenter()(jQuery)
mouseleave()(jQuery)
mousemove()(jQuery)----移动
mouseout()(jQuery)
mouseover()(jQuery)
mouseup()(jQuery)
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<title>Title</title>
<script src="lib/jquery-3.4.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>
//当网页元素加载完毕之后,响应事件
//$(document).ready(function(){})
$(function(){
$('#divMove').mousemove(function(e){
$('#mouseMove').text('x:'+e.pageX+"y:"+e.pageY)
})
});
</script>
</body>
</html>
初始化事件
$(document).ready(function () {
// on('submit', function)也可以简化:
$('#testForm).submit(function () {
alert('submit!');
});
});
// 简化后
$(function () {
// init...
});
节点文本操作
$('#test-ul li[name=python]').text();//获得值
$('#test-ul li[name=python]').text('设置值');//设置值
$('#test-ul').html();//获得值
$('#test-ul').html('<strong>123</strong>');//设置值
比较好的设计网站:友人C
**狂神说JAVA B站个人空间:
https://space.bilibili.com/95256449?from=search&seid=842697730049080**