JavaScript
1、概述
JavaScript是一门世界上最流行的脚本语言
一个合格的后端人员,必须要精通JavaScript
2、入门
引入JavaScript
-
内部标签
<script> alert("Hello World!"); </script>
-
外部引入
<script src="js/keleJs.js"></script>
基本语法入门
定义:
var score= 1;
条件控制:
if(){
}else{
}
数据类型
数值,文本,图形,音频,视频
变量
var来定义js的变量
number
js不区分小数和整数
123//整数123
123.1//浮点数123.1
1.2332e4//科学计数法
-99//负数
NaN// not a number
Infinity//表示无限大
字符串
'abc' "abc"
比较运算符!!!
= 赋值
== 等于(类型不一样,值一样,也会判断为true)
=== 绝对等于(类型一样,值一样,才会判断为true)
须知
- NaN===NaN,NaN与所有的数值都不相等,包括自己
- 只能通过isNaN(NaN),来判断这个数是不是NaN
浮点数问题
console.log(1/3) === (1-2/3) //false
尽量避免使用浮点数进行运算,存在精度问题
console.log(Math.abs(1/3-(1-2/3))<0.00000001) //true
null和undefined
null:空
undefined:未定义
数组
java的数组必须是相同类型的对象,js中不需要这样
var arr = [1, 2, 3, 4, 5, 'hello', null, true];
取数组下标,如果越界了,就会undefined
对象
对象是大括号{ },数组是中括号[ ]
每个对象之间使用逗号隔开,最后一个不需要添加
var Person = {
name :"kele",
age:3,
tags:['js', 'web','java']
}
取对象的值:
Person.name
kele
严格检查模式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--
前提:idea需要设置支持ES6语法
'use strict';严格检查模式,预防JS的随意性导致的一些问题
必须写在js的第一行
局部变量用let定义
-->
<script type="text/javascript">
'use strict';
let i = 1;
//es6 let
</script>
</head>
<body>
</body>
</html>
3、数据类型
3.1、字符串
- 正常字符串我们使用单引号或者双引号包裹
- 注意转义字符 \
\' 字符串
\n 换行
\t tab
\u4e2d 中
- 多行字符串编写
//波浪键包裹可以写多行字符串
// ``
var msg = `
hello
world
hihaoa
nihai`
- 模板字符串
let name = "kele";
let age = 18;
let m1 = `你好呀, ${name}`
- 字符串长度
console.log(str.length)
- 字符串的可变性:不可变
- 大小写转换
//注意这是方法,不是属性
student.toUppercase()
student.toLowercase()
//使用
console.log(student.toUppercase())
8.//获取指定下标
student.indexOf(‘t’)
//使用如下
console.log(student. indexOf(‘t’))
- //截取x~x之间的字符串[)
student.subString(x,x)
//使用如下
console.log(student. subString(1))//从第一个字符串截取到最后一个字符串
console.log(student. subString(1,3))//从第一个字符串截取到第三个字符串(包含第一个,不包含第三个)
student.subString(1,3)//1-2
//含头不含尾 [1,3)
3.2、数组
Array可以包含任意数据类型
var arr = [1,2,3,4,5]//通过下标取值和赋值
arr[0]
arr[0]=1
- 长度
arr.length
//注意:假如给arr.length赋值,数组长度就发生变化,赋值过大没有元素的为空值,赋值过小元素会丢失
- indexOf():通过元素获得下标索引
arr.indexOf(2)
1
字符串的”1“和数字1是不同的
- slice():截取Array的一部分,返回一个新的数组,类似于subString
- push,pop
push();压入到尾部
pop():弹出尾部的一个元素
- unshift(),shift()
unshift();压入到头部
shift():弹出头部的一个元素
- sort():排序
(3) ["b", "c", "a"]
arr.sort();
(3) ["a", "b", "c"]
- 元素反转 reverse()
(3) ["a", "b", "c"]
arr.reverse()
(3) ["c", "b", "a"]
8.拼接 concat();
arr
(3) ["c", "b", "a"]
arr.concat('1', '2','3')
(6) ["c", "b", "a", "1", "2", "3"]
arr
(3) ["c", "b", "a"]
//注意:concat()并没有修改数组,只是会返回一个新的数组
- 连接符 join();
(3) ["c", "b", "a"]
arr.join('-')
"c-b-a"
//打印拼接数组,使用特定的字符串连接
- 多维数组
arr = [[1,2], [3,4], ["kele", "20"]]
arr[2][1]
"20"
数组:存储数据(知道如何存,如何取,剩下的方法都可以自己实现)
3.3、对象
若干个键值对
var 对象名 = {
属性名:属性值,
属性名:属性值,
属性名:属性值
}
//定义一个person对象,有三个属性
var Person = {
name :"kele",
age : 3,
score : "good"
}
//js中的对象,{...}表示一个对象,键值对描述属性xxxx:xxxx,
//多个属性之间用逗号隔开,最后一个不加逗号
JS中所有的键都是字符串,值是任意对象
- 对象赋值
Person.name="kele"
"kele"
Person.name
"kele"
- 使用一个不存在的对象属性,不会报错!undefined
Person.haha
undefined
- 动态删减属性
delete Person.name
true
Person
{age: 3, score: "good"}
- 动态添加属性,直接给新的属性添加值即可
Person.haha = "haha"
"haha"
Person
{age: 3, score: "good", haha: "haha"}
- 判断属性值是否在对象中 xxx in xxx
Person
{age: 3, score: "good", haha: "haha"}
'age' in Person
true
//继承
'toString' in Person
true
- 判断一个属性是否是自身拥有的 hasOwnProperty()
Person.hasOwnProperty('age')
true
Person.hasOwnProperty('toString')
false
3.4、流程控制
if()else
var age =3;
if(age>3){
alert("haha");
}else if(age >5){
alert("kele");
}else{
alert("lili");
}
while()//避免程序死循环
while(age<100){
age=age+1;
console.log(age)
}
do{
age=age+1;
console.log(age)
}while(age<100)
for()
for(let i = 0 ; i < 100 ; i++){
console.log(age)
forEach()循环
var arr = [1,232,14,43,34,34,314,];
arr.forEach(function (value){
console.log(value)
})
for…in
//for(var index in object){}
for (var number in arr) {
if (arr.hasOwnProperty(number)){
console.log("存在");
console.log(arr[number])
}
}
3.5、Map和Set
ES6的新特性
Map
var map = new Map([['tom', 100], ['jerry', 90], ['haha', 80]]);
var name = map.get(`tom`)//通过Key获得value
map.set('admin', 12356)//新增,修改
map.delete('tom');//删除
console.log(name);
map
Map(4) {"tom" => 100, "jerry" => 90, "haha" => 80, "admin" => 12356}
Set
无序不重复的集合
var set = new Set([3,1,1,1,1,1]);//set可以去重
set.add(2);//添加
set.delete(1);//删除
console.log(set.has(3));//是否包含有些元素
3.6、iterator
ES6新特性
//通过for of 实现输出数组内的值 for in实现输出数组下标
var arr = [1,2,3,4,5,66,4223];
for (var x of arr) {
console.log(x)
}
遍历map
var map = new Map([['tom', 100], ['jerry', 90], ['kele', 80]])
for (let x of map) {
console.log(x)
}
遍历set
var set = new Set([5,6,7])
for (let x of set) {
console.log(x)
}
4、函数
4.1、定义函数
定义方式一
绝对值函数
function abs(x){
if(x>=0){
retun x;
}else{
return -x;
}
}
一旦执行到return,代表函数结束,返回结果!
如果没有执行return,函数执行完也会返回结果,结果就是undefined
定义方式二
var abs = function(x){
if(x>=0){
retun x;
}else{
return -x;
}
}
//这是一个匿名函数,但是可以把结果赋值给abs
//通过abs就可以调用函数!
方式一和方式二等价
调用函数
abs(10) // 10
abs(-10) // -10
参数问题:JS可以传任意个参数,也可以不传参数。
假设不存在参数,如何规避
function abs(x){
if (typeof x != 'number'){
throw 'Not a Number'
}
if(x>=0){
return x;
}else{
return -x;
}
}
参数存在多个问题
arguments
arguments是JS免费赠送的一个关键字
代表传递进来的所有的参数是一个数组
function abs(x){
console.log("x>= " + x);
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
if(x>=0){
return x;
}else{
return -x;
}
}
问题:arguments包含所有的参数,我们有时候想使用多余的参数来进行附加操作,需要排除已有的参数
rest
以前:
if(if (arguments.length>2){
for (let i = 2; i < arguments.length; i++) {
......
}
})
ES6引入的新特性,获取除了已定参数外的其他参数
现在:
function aaa(a,b,...rest) {
console.log("a>=" +a);
console.log("b>=" +b);
console.log(rest);
}
4.2、变量的作用域
在JS中,var定义的变量实际是有作用域的
假设在函数体内声明,则在函数体外不可调用
function kele() {
var x = 1;
x = x + 1;
}
x = x + 2;//x is not defined
如果两个函数使用了相同的变量名,只要在函数内,就不冲突
function kele() {
var x = 1;
x = x + 1;
}
function kele2() {
var x = 1;
x = x + 1;
}
内部函数可以调用外部函数的成员,反之则不行
function kele() {
var x = 1;
function kele2() {
var y = x + 1;
}
var z = y + 1;// z is not defined
}
假设,内部函数变量和外部函数变量重名!
function kele() {
var x = 1;
function kele2() {
var x = 'A';
console.log('inner' + x);
}
console.log('outer' + x);
kele2()
}
kele();
假设在JavaScript中,函数查找变量从自身函数开始,由内向外查找,假设外部存在同名的函数变量,则内部函数会屏蔽外部函数的变量。
提升函数的作用域
function kele() {
var x = 'x' + y;
console.log(x);
var y = 'y';
}
kele();
//xundefined
说明JS执行引擎,自动提升了y的声明,但是不会提升y的赋值。
function kele() {
var y;
var x = 'x' + y;
console.log(x);
y = 'y';
}
这个是在JS建立之初就存在的特性。养成规范:所有的变量定义都放在头部,不要乱放,便于代码维护。
全局函数
var x = 1;
function kele() {
console.log(x);
}
kele();
console.log(x);
//1
//1
全局对象***window***
var x = 'xxx';
alert(x);
alert(window.x)//默认所有的全局变量都会自动绑定在window下
alert()函数本身也是一个***window***的变量
规范
由于我们所有的全局变量都会绑定到我们的window上,如果不同的JS文件,使用了相同的变量,就会发生冲突—>如何减少冲突
//唯一全局变量
var KeleApp = {};
//定义全局变量
KeleApp.name = 'kele';
KeleApp.add = function (a,b) {
return a + b;
}
把自己的代码全部放在自己定义的唯一空间名字中,降低全局命名冲突的问题
JQuery
局部作用域 let
function aaa() {
for (var i = 0; i < 100; i++) {
console.log(i);
}
console.log(i+1);//101 i 出了这个作用域还可以使用
}
aaa();
ES6 let关键字解决局部作用域冲突问题
function aaa() {
for (let i = 0; i < 100; i++) {
console.log(i);
}
console.log(i+1);//Uncaught ReferenceError: i is not defined
}
aaa();
建议都是用let去定义局部作用域的变量
常量 const
在ES6之前,定义常量:只要是用全部大写字母命名的都是常量,建议不要修改
var PI = '3.14';
console.log(PI);//3.14
PI = '213';
console.log(PI);//213
在ES6引入了常量关键字 const
const PI = '3.14';//只读变量
console.log(PI);
PI = '213';
console.log(PI);
//Uncaught TypeError: Assignment to constant variable.
4.3、方法
定义方法
方法就是把函数放在对象里面,对象只有两个东西:属性,方法
var kele = {
name : 'kele',
birth: 2019,
age : function () {
//今年-出生的年份
var now= new Date().getFullYear();
return now - this.birth;
}
}
//属性 kele.name;
//方法 kele.age();
function getAge() {
var now= new Date().getFullYear();
return now - this.birth;
}
var kele = {
name : 'kele',
birth: 2019,
age : getAge
}
this是无法指向的,默认指向调用他的那个对象
apply
在JS中可以控制this的指向
function getAge() {
var now= new Date().getFullYear();
return now - this.birth;
}
var kele = {
name : 'kele',
birth: 2019,
age : getAge
};
getAge.apply(kele,[]);//this指向了kele对象,参数为空
5、内部对象
标准对象
typeof 123
"number"
typeof '123'
"string"
typeof NaN
"number"
typeof true
"boolean"
typeof []
"object"
typeof {}
"object"
typeof Math.abs
"function"
typeof undefined
"undefined"
5.1、Date
var now = new Date();//Tue Nov 10 2020 17:49:16 GMT+0800 (中国标准时间)
now.getFullYear()//年份
now.getMonth()//月份0-11
now.getDate()//日期
now.getDay()//星期几
now.getHours()//时
now.getMinutes()//分
now.getSeconds()//秒
now.getTime()//时间戳 1970年1月1号0:00到现在的毫秒数
console.log(new Date(1605002232224));//时间戳转时间
转换
now = new Date(1605002232224)
Tue Nov 10 2020 17:57:12 GMT+0800 (中国标准时间)
now.toLocaleString//注意:这是一个方法,不是属性
ƒ toLocaleString() { [native code] }
now.toLocaleString()
"2020/11/10 下午5:57:12"
now.toGMTString()
"Tue, 10 Nov 2020 09:57:12 GMT"
5.2、JSON
JSON是什么
- JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。
- 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
在JS中,一切皆为对象,任何JS支持的类型都可以用JSON来表示
格式:
- 对象都用 {}
- 数组都用 []
- 所有的键值对都是用 key:value
JSON和JS对象的转化
var user = {
name : "kele",
age : 3,
sex : "男"
}
//把对象转化为字符串 {"name":"kele","age":3,"sex":"男"}
var jsonUser = JSON.stringify(user);
//把JSON字符串转化为对象
var obj = JSON.parse('{"name":"kele","age":3,"sex":"男"}');
JSON和JS对象的区别
var obj = {a:"hello", b:"hellob"};
var json = '{"a": "hello", "b":"hellob"}'
5.3、Ajax
- 原生的JS写法,xhr异步请求
- jQuery封装好的方法$("#name"),ajax("")
- axios请求
6、面向对象编程
原型对象
6.1、什么是面向对象
JavaScript、Java、c#。。。。面向对象;JavaScript有些区别!
类:模板
对象:具体的实例
在JavaScript中需要大家换一下思维。
原型:
var Student = {
name:"kele",
age:3,
run:function () {
console.log(this.name + "run...");
}
};
var xiaoming = {
name:"xiaoming"
};
//原型对象
xiaoming._proto_ = Student;
var Bird = {
fly:function () {
console.log(this.name + "fly...");
}
};
//小明的原型 是Student
xiaoming._proto_ = Bird;
function Student(name) {
this.name = name;
}
//给student新增一个方法
Student.prototype.hello = function (){
alert('hello')
};
class继承
class关键字是在ES6引入的
1、定义一个类,属性,方法
//定义一个学生的类
class Student{
constructor(name) {
this.name = name;
}
hello(){
alert('hello')
}
}
var xiaoming = new Student("xiaoming")
var xiaohong = new Student("xiaohong")
xiaoming.hell0()
2、继承
//Es6之后==========
//定义一个学生的类
class Student{
constructor(name) {
this.name = name;
}
hello(){
alert('hello')
}
}
class xiaoStudent extends Student{
constructor(name,grade) {
super(name);
this.grade = grade;
}
myGrade(){
alert('我是一名小学生')
}
}
var xiaoming = new Student("xiaoming")
var xiaohong = new Student("xiaohong",1)
本质:查看对象原型
原型链
proto;
7、操作BOM对象(重点)
浏览器介绍
BOM:浏览器对象模型
IE6~11
Chrome
Safari
FireFox
Opera
三方
QQ浏览器
360浏览器
window
window代表浏览器窗口
Navigator
Navigator,封装了浏览器的信息
大多数时候,我们不会使用navigator对象,因为会被人为修改
scree
代表屏幕尺寸
screen.width
1536
screen.height
864
location
location代表当前页面的URL信息
document
document代表当前的页面,HTML DOM文档树
获取具体的文档树节点
获取cookie
劫持cookie原理
服务器端设置cookie:httpOnly
history
history代表浏览器的历史记录
history.back()//后退
history.forward()//前进
8、操作BOM对象(重点)
核心
浏览器就是一个Dom树形结构
- 更新:更新Dom节点
- 遍历dom节点:得到Dom节点
- 删除:删除一个Dom节点
- 添加:添加一个新的节点
要操作一个Dom节点,就必须要先获得这个Dom节点
获得Dom节点
<div id="father">
<h1>标题一</h1>
<p>p1</p>
<p>p2</p>
</div>
<script>
//对应css选择器
var h1 = document.getElementsByTagName('h1');
var p1 = document.getElementById('p1');
var p2 = document.getElementsByClassName('p2');
var father = document.getElementById('father');
var childrens = father.children[index];//获取父节点下所有的子节点
//father.firstChild
//father.lastChild
这是原生代码,之后我们尽量使用JQuery();
更新节点
<div id="id1">
</div>
<script>
var id1 = document.getElementById('id1');
</script>
操作文本
- id1.innerText=‘123’ 修改文本的值
- id1.getInnerHTML=‘123’ 可以解析html文本标签
操作js
- id1.style.color = ‘red’ 更改颜色 //属性使用 字符串 包裹
- id1.style.fontSize = ‘20px’ // - 转 驼峰命名
- id1.style.padding = ‘2em’
删除节点
删除节点的步骤:先获取父节点,在通过父节点删除自己
<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)
</script>
注意:删除多个节点时,children是在时刻变化的,删除节点是一定要注意
插入节点
我们获得了某个Dom节点,假设这个dom节点是空的,我们通过innerHT就可以增加一个元素了,但是这个DOM节点已经存在了,我们就不能这样干了,因为会产生覆盖
追加
<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');
</script>
list.appendChild(js)
创建一个新的标签,实现插入
<script>
var js = document.getElementById('js');//已经存在的节点
var list = document.getElementById('list');
//通过js创建一个新的节点
var newp = document.createElement('p');//创建一个p标签
nep.id = 'newp';
newp.innerText = "hello,kele";
//创建一个标签节点 (通过这个属性,可以设置任意的值)
var myscript = document.createElement('script');
myscript.setAttribute('type','text/javascript');
//可以创建一个style标签
var myStyle = document.createElement(('style'));//创建一个空style标签
myStyle.setAttribute('type','text/css');
myStyle.innerHTML = 'body{background-color:chartreuse;}';//设置标签内容
document.getElementsByTagName('head')[0].appendChild(myStyle);
</script>
list.appendChild(newp);
insertBefore
var ee = document.getElementById('ee');
var js = document.getElementById('js');
//要包含的节点.insertBefore(newNode,targetNode)
list.insertBefore(is,ee);
9、操作表单(验证)
表单是什么 from DOM 树
- 文本框 text
- 下拉框
- 单选框 radio
- 多选框 checkbox
- 隐藏域 hidden
- 密码框 password
- …
<form>
<p>
<span>用户名:</span><input type="text" id="user-name">
</p>
<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('user-name');
var boy_radio = document.getElementById('boy');
var girl_radio = document.getElementById('girl');
//得到输入框的值
input_text.value
//修改输入框的值
input_text.value = '123'
//对于单选框,多选框等等固定的值,boy_radio.value只能取到当前的值
boy_radio.checked;//查看返回的结果,是否为true,如果为true,则被选中~
girl_radio.checked = true;//赋值
</script>
提交表单
<script src="http://cdn.bootcss.com/blueimp-md/2.10.0/js/md5.min.js"></script>
<!--
表单绑定提交事件
onsubmit= 绑定一个提交检测的函数,true,false
将这个结果返回给表单,使用onsubmit接收!
onsubmit=return aaa()
-->
<form action="#" method="post" onsubmit="return aaa()">
<p>
<span>用户名:</span><input type="text" id="username" name="username">
</p>
<p>
<span>密码:</span><input type="password" id="password" name="input-password">
</p>
<input type="hidden" id="md5-password" name="password">
<!-- <button type="submit" onclick="aaa()">提交</button>-->
<button type="submit" >提交</button>
</form>
<script>
function aaa(){
var uname = document.getElementById('username');
var pwd = document.getElementById('input-password');
var md5pwd = document.getElementById('md5-password');
//pwd.value = md5(pwd.value);
md5.value = md5(pwd.value);
//可以效验判断表单内容,true就是通过提交,false,就是阻止提交
return true;
// console.log(uname.value);
// //MD5算法
// pwd.value = md5(pwd.value);
// console.log(pwd.value);
}
</script>
10、jQuery
javascript
jQuery库,里面存在大量的函数
获取
https://jquery.com/download/ //下载导入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--CND引入 -->
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
</body>
</html>
公式: $(selector).action()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--CND引入 -->
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<!--
公式: $(selector).action()
-->
<a herf = "" id="test-jquery">点我</a>
<script>
//选择器就是css选择器
$('#test-jquery').click(function (){
alert('hello,l');
})
</script>
</body>
</html>
选择器
//原生js
//标签
document.getElementsByTagName();
//id
document.getElementById();
//类
document.getElementsByClassName();
//jQuery css中的选择器他都能用
//标签
$('p').click();
//id
$('#id').click();
//类
$('.class1').click();
.......
文档工具:http://jquery.cuishifeng.cn/
事件
鼠标事件,键盘事件,其他事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--CND引入 -->
<script src="lib.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>
操作DOM
节点文本操作
$('#test-ul li[name=python]').text();//获得值
$('#test-ul li[name=python]').text('设置值');//设置值
$('#text-ul').html();//获得值
$('#text-ul').html('<strong>123</strong>');//设置值
css操作
$('#test-ul li[name=python]').css({"color","red"})
元素的显示和隐藏:本质 display : none;
$('#test-ul li[name=python]').show()
$('#test-ul li[name=python]').hide()