javascript
JavaScript是一门世界上最流行的脚本语言
1、JS基础
1、JS的两种引入方式
1.1、内部标签
<script>
alert("hello world");
</script>
1.2、外部引入
abc.js
alert("hello world");
heml文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- <script>-->
<!-- alert("hello world");-->
<!-- </script>-->
<script src="js/hello.js"></script>
</head>
<body>
</body>
</html>
2、JS基础语法
-
定义变量:var 变量名 = 赋值;(var name = "string")
-
条件控制:if-else同Java
-
控制台调试
console.log(num):在浏览器控制台打印信息
3、JS基本数据类型
变量
var a = 1
number:JS不区分小数和整数
123 //整数123
123.1 //浮点数123.1
1.23e2 //科学计数法
-99 //负数
NaN //not a number
Infinity //无限大
字符串
\'abc\' "abc"
布尔值
true,false
逻辑运算
&&,||,!
比较运算符
=:赋值
==:等于(类型不一样,值一样,也会判断为true)
===:绝对等于(类型一样,值一样,结果为true)
坚持使用 === 比较,尽量不用 == 比较
须知:
- NaN==NaN,这个数与所有的数值都不相等,包括它自己。
- 只能通过isNaN(NaN)来判断这个数是否是NaN
浮点数问题:
console.log((1/3) === (1-2/3)) //结果为false,有精度损失
尽量避免使用浮点数进行计算,会有精度问题。
Math.abs(1/3 - (1 - 2/3))<0.00000001
null和undefined
- null:空
- undefined:未定义
数组
var arr = [1,2,3.1,"string",null,true];
数组下标不存在越界,如果超过会显示undefined
对象
对象用{},数组用[]
每个属性之间用逗号隔开,最后一个不需要添加。
var person = {
name: "Lv",
age:3,
tags: ["js","java"]
}
取对象的值
console.log(person.name)
Lv
4、严格检查模式
<!--
\'use strict\';严格检查模式,预防JavaScript的随意性带来的问题。必
须写在JavaScript的第一行
局部变量建议都使用let定义
-->
<script>
\'use strict\';
let i = 1;
</script>
2、数据类型
2.1 字符串
-
正常字符串使用单引号或者双引号
-
注意转义字符\\
\\\' \\n \\t \\u4e2d //u#### Unicode码 \\x41 //Ascll码
-
多行字符串
//tab键上方,esc键下方 var msg = ` hello world 你好 `
-
模板字符串
let name = "Lv"; let age = 18; let msg = `你好,${name}`
-
字符串长度
str.length
-
字符串的可变性
不可变
-
大小写转化
//注意:这里是方法了,不是属性了 str.toUpperCase() str.toLowerCase()
-
str.indexOf()、str.substring()等方法与Java一样
2.2 数组
Array可以包含任意的数据类型
let arr = [1,2,3,4,5,6]
-
长度
//长度 console.log(arr.length); //给arr.length赋值可以改变数组大小,如果赋值过小数据就会丢失
-
indexOf(),通过元素获得下标索引
字符串的"1"和数字的1不一样
-
slice() 截取Array的一部分,返回一个新数组,类似于String中的substring()
-
push,pop
push:向尾部增加元素(str.push("a","b");
pop:取出尾部的元素 (str.pop());
-
unshift(),shift()
unshift:向头部增加元素(str.unshift("a","b");
shift:取出头部的元素 (str.shift());
-
排序 str.sort()
-
元素反转 str.reverse()
-
拼接数组 str.concat
let arr = ["A","B","C"]; arr.concat([1,2,3]) arr //输出结果为["A","B","C"]
arr中的元素并没有改变,只是返回一个新的数组
-
连接符join
打印拼接数组,使用特定的字符串连接
-
多维数组 arr = [[1,2],[3,4]]
2.3 对象
若干个键值对,键值对之间用逗号隔开,最后一个不写逗号
var 对象名 = {
属性名:属性值,
属性名:属性值,
属性名:属性值
}
var person = {
name: "lvJ",
age: 18,
}
JavaScript中的所有键都是字符串,值时任意对象
-
对象赋值
直接点出对象后直接赋值即可
person.name = "Lv";
-
使用一个不存在的对象时,不会报错,只会报undefined。
-
动态添加一个不存在的属性,直接赋值即可添加进去。
//原来的类中没有a这个属性 person.a = "a";
-
动态的删除属性,用delete后直接跟对象属性即可删除
delete person.name
-
判断一个属性是否在这个对象内:XXX in XXX
\'age\' in person true //继承 \'toString\' in person true
-
判断一个属性是否是这个对象自身拥有的:hasOwnProperty()
person.hasOwnPeoperty(\'toString\') false person.hasOwnPeoperty(\'age\') true
2.4 流程控制
if-else,for循环,while以及do-while和Java一样。
数组遍历,foreach
var a = [1,2,3,4,5,6]
a.forEach(function(value)){
console.log(value)
}
for...in
//for(var index in object){}
for(var num in a){
console.log(a[num])
}
2.5 Map和Set
ES6的新特性
Map:
//ES6
\'use strict\';
let map = new Map([["tom",15],["jack",16],["Lv",13]]);
let name = map.get("tom"); //通过key获得value值
console.log(name);
map.set("ta",12); //添加一个元素
console.log(map.get("ta"));
map.delete("ta"); //删除一个元素
Set:
let set = new Set([3,1,1,1,1,1,1]);
set.add(2);
set.delete(1);
//判断是否包含
set.has(3)
2.6 iterator
ES6新特性
遍历数组:
let arr = [3,4,5];
//通过for of,for in只能返回下标
for (let s of arr){
console.log(x);
}
遍历Map:
let map = new Map([["tom",15],["jack",16],["Lv",13]]);
for (let s of map){
console.log(x);
}
遍历Set
let set = new Set([3,4,8]);
for (let s of set){
console.log(x);
}
3、函数
3.1 定义函数
定义方式一
绝对值函数
function abs(x){
if(s >= 0){
return x;
}else{
return -x;
}
}
执行到return函数结束,返回结果!
如果没有执行return,代表函数执行完也会返回结果,结果为undefined。
定义方式二
var abs = function(x){
if(s >= 0){
return x;
}else{
return -x;
}
}
参数问题
无论函数中有几个参数都可以传任意个参数,都不会报错。
手动抛出异常
function f(a) {
if (typeof a !== \'number\'){
throw "Not a Number";
}
console.log(a);
}
arguments
arguments
是一个JS免费赠送的关键字;代表所有传入进来的参数,是一个数组。
function f(a) {
console.log(a);
for (let lengthKey in arguments) {
console.log(arguments[lengthKey]);
}
}
问题:arguments获取的是所有的参数,在不知道原函数有多少参数的情况下,想用多余的函数就无法计算。
rest
获取除函数所需的参数外的所有参数
function f(a,...rest) {
console.log(a);
console.log(rest);
}
rest只能写在参数最后
3.2 变量作用域
- JavaScript中变量有作用域,函数体内声明函数体外不可用。但是闭包可以实现。
<script>
function f() {
var a = 1;
a = a + 1;
}
a = a + 2; //报错: \'a\' is not defined
</script>
-
内部函数可以访问外部函数的变量,反之则不行。
-
内部变量和外部变量重名时,先查找自身,没有则向外部函数查找,有则屏蔽外部变量调用自身变量。
-
提升变量作用域
<script> function f() { var x = "x" + y; console.log(x); var y = "y"; } </script>
结果:xundefined
说明:js执行引擎自动提升了y的声明,但是不会提升变量y的赋值;
相当于下面的操作:
<script> function f() { var y; var x = "x" + y; console.log(x); y = "y"; } </script>
这个实在JavaScript建立之初就存在的。所以,在平常编程的时候将变量声明都放函数最前面。
-
全局变量
<script> var x = "123456"; function f() { console.log(x); } f(); console.log(x); </script>
-
全局对象 window
默认所有的全局变量都绑定在window对象下
<script> var x = "123456"; alert(x); alert(window.x); </script>
alert()函数本身也是一个window下的函数
<script> var x = "123456"; window.alert(x); alert(window.x); </script>
JS中实际上只有一个全局作用域,任何变量(函数也可视为变量),如果没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,就会报错。
-
规范
由于所有的迁居变量都会绑定到window上。如果不同的JS文件,使用了相同的全局变量,就会产生冲突。
解决方法:
//自定义一个唯一全局作用域 var Lv = {}; //定义全局变量 Lv.name = "LvJ"; //定义函数 Lv.f = function (a,b){ return a + b; }
把自己的代码全部放入自己定义的唯一空间中,避免全局命名冲突的问题。
-
局部作用域let
function f(){ for (var i = 0; i <100; i++){ console.log(i); } console.log(i+1); //出了作用域还能用 }
因此,ES6中新出let关键字,解决局部作用域冲突问题
function f(){ for (let i = 0; i <100; i++){ console.log(i); } console.log(i+1); //i不能用了,报错:i is not defind }
推荐使用let定义局部作用域
-
常量
ES6前定义常量:只要大写字母定义的全部是常量。但可以改变。
ES6引入了常量关键字:const
const PI = \'3.14\';
用const定义的常量不可再改变,再去复制就会报:Assignment to const
3.3 方法
方法就是把函数放在对象里面,对象只有两个东西:方法和属性
var Lv = {
name: "Lv",
birth: 2010,
age: function () {
var now = new Date().getFullYear();
return now-this.birth;
}
}
拆开
function getage() {
var now = new Date().getFullYear();
return now-this.birth;
}
var Lv = {
name: "Lv",
birth: 2010,
age: getage
}
//Lv.age() 调用成功
//直接调用getage() 会显示NaN
this始终指向使用它的对象,直接调用getage()时,指向window对象,window没有birth这个值,所以显示NaN。
apply
在js中可以控制this的指向
function getAge() {
var now = new Date().getFullYear();
return now-this.birth;
}
var Lv = {
name: "Lv",
birth: 2010,
age: getage
}
var J = {
name: "Lv",
birth: 2010,
age: getage
}
getAge.apply(Lv,[]); //this指向了Lv,参数为空
4、内部对象
标准对象
typeof 123
"number"
typeof \'123\'
"string"
typeof true
"boolean"
typeof NaN
"number"
typeof []
"object"
typeof Math.abs
"function"
typeof undefined
"undefined"
4.1 Date
var now = new Date();
now.getFullYear(); //年
now.getMonth(); //月
now.getDate(); //日
now.getDay(); //星期
now.getHours(); //时
now.getMinutes(); //分
now.getMilliseconds(); //秒
now.getTime(); //时间戳,自1970.01.01 00:00 开始到当前的毫秒数
now.toLocaleString(); //当地时间
"2020/7/11 下午5:26:57"
4.2 JSON
- JSON(JavaScript Object National)是一种轻量级的数据交换格式。
- 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
在JavaScript一切皆为对象任何js支持的类型都可以用JSON来表示
格式:
- 对象都用{}
- 数组都用[]
- 所有的键值对都是用key:value
\'use strict\';
var person = {
name: "Lv",
age: 18,
sex: "男"
}
//将js对象转为JSON字符串{"name":"Lv","age":18,"sex":"男"}
var jsonperson = JSON.stringify(person);
//将字符串转为对象,参数为JSON字符串
var obj = JSON.parse(\'{"name":"Lv","age":18,"sex":"男"}\');
js对象和JSON的区别
//对象
var a = {b: 1,c: 2};
//JSON字符串
var json = {"b": "1","c": "2"};
5、面向对象编程
原型对象
-
类:模板
-
对象:具体实例
在JS中需要转换思维
原型:
var Student = {
name: "xiaoxioa",
age: 18,
sex: "女",
run: function(){
console.log(this.name + "run.....");
}
};
var feifei = {
name: "feier"
};
//feifei的原型指向Student,就可以调用Student中的属性及方法
feifei.__proto__ = Student; //注意;这里是两个_
//feifei.run()
//feierrun.....
class继承
class关键字是在ES6引入的
1、定义一个类,有属性和方法
//定义一个学生的类
class Student {
constructor(name){
this.name = name;
}
hello(){
alert("Hello");
}
}
var xiaoxiao = new Student("xiaoxiao");
var feifei = new Student("feifei");
2、继承
//定义一个Person的类
class Person {
constructor(name){
this.name = name;
}
hello(){
alert("Hello");
}
}
class Student extends Person{
constructor(name,age){
super(name);
this.age = 18;
}
myMethod(){
alert("i am a student!");
}
}
6、操作BOM对象(重点)
浏览器介绍
JavaScript的诞生就是为了让它能在浏览器中运行
BOM:浏览器对象
window
window代表浏览器窗口
window.alert()
//获取浏览器的宽度和高度
window.innerHeight
window.innerWidth
window.outerHeight
window.outerWidth
Navigator
Navigator封装了浏览器的信息
navigator.appVersion
"5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362"
navigator.appName
"Netscape"
navigator.userAgent
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362"
navigator.platform
"Win32"
大多数,不会使用navigator对象,因为会被人修改。
不建议使用这些属性来判断和编写代码
screen
//屏幕尺寸
screen.width
1561
screen.height
878
location(重要)
location代表当前页面的URL信息
host: "www.baidu.com" //主机
href: "https://www.baidu.com/" //跳转的页面
protocol: "https:" //协议
reload: function reload() { [native code] } //方法,重新加载
//设置新的地址
location.assign(\'地址\')
document
document代表当前的页面,HTML DOM文档树
document.title
"百度一下,你就知道"
document.title = "Lv"
"Lv"
获取具体的文档树节点
<body>
<dl id="docu">
<dt>Java</dt>
<dd>JavaScript</dd>
<dd>JavaSE</dd>
<dd>JavaEE</dd>
</dl>
<script>
var dl = document.getElementById(\'docu\');
</script>
</body>
注意:如果将js代码写在head标签里面是无法获取出来的
获取cookie
document.cookie
history
代表浏览器的历史记录
history.back() //后退
history.forward() //前进
7、操作DOM对象(重点)
DOM:文档对象模型
核心
浏览器网页就是一个DOM树形结构
- 更新:更新DOM节点
- 遍历DOM节点:得到DOM节点
- 删除:删除一个DOM节点
- 添加:添加一个新的节点
要操作一个DOM节点,就必须先获得这个DOM节JavaScript
var h1 = document.getElementsByTagName("h1");
var p1 = document.getElementById("p1");
var p2 = document.getElementById("p2");
var div = document.getElementById("div");
//获取父节点下的子节点(注意:通过id找到的有这个功能,通过class找到的没有)
var childrens = div.children;
// div.firstChild
// div.lastChild
这是原生代码,之后会尽量使用jQuery
更新节点
<div id="id1"></div>
<script>
var id1 = document.getElementById(\'id1\');
</script>
- id1.innerText = \'123\' 修改文本的值
- id1.innerHTML\'< strong>123< /strong>\' 可以解析HTML文本标签
操作JS
id1.style.color = \'red\'; //属性使用字符串包裹
id1.style.fontSize = \'20px\';
id1.style.padding = \'2em\';
删除节点
删除节点的步骤:先获取父节点,在通过父节点删除子节点
<div id="father">
<h1 class="h1">h1</h1>
<p id="p1">p1</p>
<p id="p2">p2</p>
</div>
<script>
//方法一:
var self = document.getElementById(\'p1\');
var father = p1.parentElement;
father.removeChild(self)
//方法二:
//删除是一个动态的过程
father.removeChild(father.children[0]);
father.removeChild(father.children[1]);
father.removeChild(father.children[2]);
</script>
注意:删除多个节点的时候,children是在时刻变化的,删除节点的时候一定要注意;
插入节点
我们获得了某个DOM节点,假设这个DOM节点是空的,我们通过innerHTML就可以增加一个元素,但是如果这个DOM节点已近存在元素,那么就会覆盖原有内容。
<p id="js">JavaScript</p>
<div id="list">
<p id="ee">JavaEE</p>
<p id="se">JavaSE</p>
</div>
<script>
var js = document.getElementById(\'js\');
var list = document.getElementById(\'list\');
//追加到后面
list.appendChild(js)
</script>
创建一个新标签
<script>
var js = document.getElementById(\'js\');
var list = document.getElementById(\'list\');
var nas = document.createElement(\'p\'); //创建一个新的p标签
nas.id = \'nas\'; //给新的标签建立ID
nas.innerText = \'Hello\'; //设置内容
list.appendChild(nas); //追加到list中,注:list.append("ab")是直接将字符串ab追加进去
//创建一个标签节点
var myScript = document.createElement(\'script\');
myScript.setAttribute(\'type\',\'text/javascript\');
//可以创建一个Style标签
var myStyle = document.createElement(\'style\');
myStyle.setAttribute(\'type\',\'text/css\');
myStyle.innerHTML = \'body{background-color: red;}\';
document.getElementsByTagName(\'head\')[0].appendChild(myStyle);
</script>
insertBefore
var ee = documentElementById(\'ee\');
var se = documentElementById(\'se\');
var list = documentElementById(\'list\');
//list:要插入的节点地方,js:要插入的节点,ee:在ee节点之前
list.insertBefore(js,ee);
8、操作表单
表单是什么 form DOM 树
- 文本框 text
- 下拉框 < select>
- 单选框 radio
- 多选框 checkbox
- 隐藏矿 hidden
- 密码框 password
- ......
表单的目的:提交信息
获得要提交的信息
<body>
<div>
<p>
<span>用户名:</span>
<input type="text" id="userName">
</p>
<p>
<input type="radio" name="sex" id="boy" value="man"> 男
<input type="radio" name="sex" id="girl" value="women"> 女
</p>
</div>
<script>
var username = document.getElementById(\'userName\');
var boy = document.getElementById(\'boy\');
var girl = document.getElementById(\'girl\');
//获得输入框的值
username.value;
username.vale = \'123456\'; //赋值
//对于单选框、多选框等,value只能获得当前的值
boy.checked; //查看返回的结果,是否为true,选中即为true
girl.checked = true; //赋值
</script>
</body>
提交表单 MD5加密,表单优化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="http://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
</head>
<body>
<!--表单提交事件-->
<form action="http://www.baidu.com" method="post" onsubmit="return aaa()">
<div>
<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">提交</button>
</div>
</form>
<script>
function aaa() {
var uname = document.getElementById(\'username\');
var pwd = document.getElementById(\'input-password\');
var md5pwd = document.getElementById(\'md5-password\');
md5pwd.value = md5(pwd.value);
//可以判断表单内容,true是通过提交,false是阻止提交
return true;
}
</script>
</body>
</html>
9、jQuery
jQuery:封装的大量JavaScript函数的库
获取jQuery
CDN 在线链接或直接下载jQuery加载到自己项目中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.slim.min.js"></script>
</head>
<body>
<a href="" id="test-jQuery">点我</a>
<script>
//公式:$(selection).action()
$(\'#test-jQuery\').click(function () {
alert(\'hello jQuery\');
})
</script>
</body>
</html>
选择器
css选择器
jQuery文档工具站:http://jquery.cuishifeng.cn/
事件
鼠标事件,键盘事件,其他事件
//页面加载完成后执行操作
$(document).ready(function () {
});
//等价于下面
$(function () {
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.slim.min.js"></script>
<style>
#div{
width: 500px;
height: 500px;
border: 1px solid red;
}
</style>
</head>
<body>
mouse:<span id="MouseMove"></span>
<div id="div">在这里移动鼠标哦</div>
<script>
$(function () {
$(\'#div\').mousemove(function (e) {
$(\'#MouseMove\').text("x:"+e.pageX+"y:"+e.pageY);
});
});
</script>
</body>
</html>
操作DOM
节点文本操作
$(\'p\').text() //获得值,其中p为p标签
(\'p\').text(\'123\') //设置值
$(\'p\').HTML()
$(\'p\').HTML(\'123\')
css操作
$(\'p\').css("color","red") //多个的话用键值对({"color","red"})
元素的显示与隐藏:本质 display:none
$(\'p\').show()
$(\'p\').hide()