JavaScript总结
JavaScript知识点
一.概述
1.什么是JavaScript
- JavaScript是一门脚本语言
- Java,JavaScript的关系:无半毛钱关系
注意:后端人员要精通JavaScript
2.JavaScript的历史
https://www.cnblogs.com/ghost-xyx/p/4035615.html
3.标准(ECMAScript)
https://baike.baidu.com/item/ECMAScript/1889420?fr=aladdin
- 最新版本为es6版本,但是现在大部分浏览器还只支持es5代码!
二.入门
1.js的引入
//内部标签
<head>
<meta charset="UTF-8">
<title>js</title>
<!--script标签内写js代码 -->
<script>
alert('hello,javascript');
</script>
</head>
外部引入
//注意:script标签必须成对出现
//script标签必须成对出现
<script src="js/js1.js"></script>//写在html中head内部
alert('hello,javascript');//写在js文件中
- 弹窗标签
alert('hello,javascript');
2.基本语法
<!--JavaScript严格区分大小写-->
<script>
//定义变量
var score=88;
//alert(score);
//2.条件控制
if(score>60 &&score<70){
alert("60-70");
}else if(score>70&& score<80){
alert("70-80");
}else{
alert("other");
}
//console.log(score) 在浏览器的控制台打印变量!
</script>
3.数据类型
数值,文本,图形,音频,视频...
number
js不区分整数和小数
123 //整数
123.4 //浮点数
1.23e4 //科学计数法
-99 //负数
NaN //not a number
Infinity //无限大
字符串
'a' "abc"
布尔值
true , false
逻辑运算符
&&
||
!
比较运算符(重要)
=
== 等于(类型不一样,值一样,也会判断为true)
=== 绝对等于(类型一样,值一样,结果true)
- JS坚持不要使用==比较
须知: - NaN===NaN,NaN与所有的数值都不相等,包括自己
- 只能通过isNaN(NaN)来判断这个数是否是NaN
浮点数问题:
console.log((1/3)===(1-2/3))
尽量避免使用浮点数进行运算,存在精度问题
console.log(Math.abs(1/3-(1-2/3))<0.000000001)
null和undefined
- null 空
- undefined 未定义
数组
js中的数值不一定要是相同类型的对象
var arr=[1,2,3,'hello',null,true];
new Array(1,2,3,'hellojs',null,true);
取数组下标:如果越界了,就会undefined
对象
- 对象是大括号,数组是中括号
- 每个属性之间使用逗号隔开,最后一个不需要
var Person={
name:"chen",
age:18,
tags:['js','java',2,5]
}
取对象值
person.name
>"chen"
person.age
>18
4.严格检查模式
<!--
前提:IDEA需要设置支持ES6语法
'use strict';严格检查模式,预防JavaScript的随意性导致产生一些问题
必须写在JavaScript的第一行!
局部变量建议都使用let去定义
-->
<script>
'use strict';
//全局变量
let i=1;
//ES6 let
</script>
三.数据类型
1.字符串
- 正常字符串使用单引号或者双引号包裹
- 注意转义字符\
\'
\n
\t
\u#### Unicode字符
\x41 Ascll字符
- 多行字符串编写
//tab键上的`
var msg=`
hello,javascript,你好呀
`
- 模板字符串
let name = "chen_study";
let age = 18;
let msg = `你好呀,${name}`
- 字符串长度
console.log(str.length)
- 字符串不可变性
- 大小写转换
//注意:这里是方法
student.toUpperCase()
student.toLowerCase()
- 返回某个字符位置
student.indexOf('u')
- 截取字符串
[)
student.substring(1)//从第一个字符串截取到最后一个字符串
student.substring(1,3)//[1,3)
2.数组
- 长度
arr.length
注意:给arr.length赋值,数组大小会发生变化,如果赋值过小,元素就会丢失
- indexOf,通过元素获得下标索引
arr.indexOf(2)
字符串的"1"和数字1是不同的
- slice() 截取Array的一部分,返回一个新数组,类似于String中substring
- push(),pop() 尾部
push: 压入到尾部
pop: 弹出尾部的一个元素
- unshift(),shift() 头部
unshift: 压入到头部
shift: 弹出头部的一个元素
- 排序sort()
arr.sort()
- 元素反转reverse()
arr.reverse()
- 拼接concat()
arr.concat([1,2,3])
注意:concat()并没有修改数组,只是会返回一个新的数组
- 连接符join
打印拼接数组,使用特定的字符串连接
arr.join('-')
- 多维数组
arr = [[1,2],[3,4],["5","6"]];
arr[1][1] //4
3.对象
若干个键值对
var 对象名 = {
属性名:属性值,
属性名:属性值,
属性名:属性值
}
//定义了一个person对象,他有四个属性
var person = {
name:"chen",
age:18,
email:1234567@qq.com,
score:100
}
Js中对象,{......}表示一个对象,键值对描述属性,多个属性之间使用逗号隔开,最后一个属性不加逗号!
- 对象赋值
Person.name = "hu"
"hu"
person.name
"hu"
- 使用一个不存在的对象属性,不会报错!undefined
person.a
undefined
- 动态的删减属性,通过delete删除属性
delete person.name
true
- 动态添加属性,直接给新属性添加值即可
person.a="a"
"a"
- 判断属性值是否在这个对象中,xxx in xxx(js中所有的键都是字符串,值是任一对象!)
'age' in person
true
//继承
'toString' in person
true
- 判断一个属性是否是这个对象自身拥有的hasOwnProperty()
person.hasOwnProperty('toString')
false
person.hasOwnProperty('age')
true
4.流程控制
- if判断
- 循环
while
do while
for
forEach
var age = [1,2,3,4,5,6,86,345]
age.forEach(function(value){
console.log(value)
})
for...in
5.Map和Set
ES6的新特性
- Map
//ES6 Map
var map = new Map([['xiaoming',100],['zhangsan',60]]);
var name = map.get('xiaoming');//get
console.log(name);//100
map.set('admin',90)//set新增
map.delete('xiaoming')//删除
- Set(无序不重复的集合)
var set = new Set([1,1,2,2,3,3]);//1,2,3 set会去重
set.add(4) //1,2,3,4 add增加
set.delete(4) //1,2,3 delete删除
console.log(set.has(3)); //是否含某个元素
6.iterator
- 遍历数组
ES6新特性
//通过for of/ for in下标
var arr=[1,2,3]
for(var x of arr){
console.log(s)
}
- 遍历Map
var map = new Map([['xiaoming',100],['zhangsan',60]]);
for(let x of map){
console.log(x)
}
- 遍历Set
var set = new Set([3,4,5]);
for(let x of set){
console.log(x)
}
四.函数
1.定义函数
绝对值函数
定义方式一
function abs(x){
if(x>=0){
return x;
}else{
return -x;
}
}
一旦执行到return代表函数结束,返回结果!
如果没有执行return,函数执行完也会返回结果,结果为undefined
定义方式二
var abs = function(x){
if(x>=0){
return x;
}else{
return -x;
}
}
//function(x){......} 匿名函数,可以把结果赋值给abs通过abs可以调用函数
2.调用函数
- js可以传递任意个参数,也可以不传递参数
- 规避不参在参数问题
//手动抛出异常
var abs = function(x){
if(typeof x!== 'number'){
throw 'Not a Number'
}
if(x>=0){
return x;
}else{
return -x;
}
}
arguments
arguments是JS免费赠送的关键字;代表传递的所有参数是一个数组
var abs = function(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
ES6引入的新特性,获取除了已经定义的参数之外的所有参数
function text(a,b,...rest){
console.log("a=>"+a);
console.log("b=>"+b);
console.log(rest);
}
//rest参数只能写在最后面,必须用...标识
3.变量作用域
- 在JS中,var定义变量实际是有作用域的。
- 假设在函数体声明,则在函数体外不可以使用(非实现的话,可以研究一下闭包)
function add(){
var x=1;
x=x+1;
}
x=x+2; //Uncaught ReferenceError: x is not defined
- 如果两个函数是用来相同的函数名,只要是在函数内部,就不冲突
function add(){
var x=1;
x=x+1;
}
function add1(){
var x=1;
x=x+1;
}
- 内部函数可以访问外部函数的成员,反之不行
function add(){
var x=1;
fuction add1(){
var y=x+1; //2
}
var z=y+1; //Uncaught ReferenceError: y is not defined
}
- 养成规范:所有的变量定义都放在函数的头部,不要乱放,便于代码维护
全局函数
x=1;
function f(){
console.log(x);
}
f();
console.log(x);
- 全局对象window
var x='xxx';
alert(x);
alert(window.x);
//alert()这个函数本身也是一个window变量
规范
由于我们所有的变量都会绑定到我们的window上,如果不同的JS文件,使用了相同的全局变量,如何能够减少冲突
//唯一全局变量
var ChenStudy = {};
ChenStudy.name='chen';
ChenStudy.add = function(a,b){
return a+b;
}
把自己的代码放入自己定义的空间名字中,降低全局命名冲突问题
jQuery
局部作用域 let
function abc(){
for(var i=0;i<100;i++){
console.log(i)
}
console.log(i+1); //问题:i出了作用域还能够使用
}
- ES6 let关键字,解决了局部作用域冲突问题
function abc(){
for(let i=0;i<100;i++){
console.log(i)
}
console.log(i+1); //Unacught ReferenceError: i is not defined
}
- 建议使用let定义局部作用域
常量 const
const PI = '3.14';
console.log(PI);
//PI = '123';
4.方法
定义方法
- 对象:属性和方法
var fangfa = {
name: 'chenstudy',
birth: 2000,
//方法
age:function(){
var now = new Date().getFullYear();
return now-this.birth;
}
}
//属性
chenstudy.name
//方法,一定要带()
chenstudy.age()
this默认指向调用它的那个对象
apply
- 在js中可以控制this指向
function getAge(){
var now = new Date().getFullYear();
return now-this.birth;
}
var fangfa = {
name: 'chenstudy',
birth: 2000,
age: getAge
};
getAge.apply(fangfa,[]);
五.内部对象
标准对象
number,string,boolean,object,function,undefined
1.Date
基本使用
var now = new Date(); //Sun May 09 2021 17:09:00 GMT+0800 (中国标准时间)
now.getFullYear(); //年
now.getMonth(); //月 0—11
now.getDate(); //日
now.getDay(); //星期
now.getHours(); //时
now.getMinutes(); //分
now.getSeconds(); //秒
now.getTime(); //时间戳 全世界统一 从 1970-1-1 00:00:00 毫秒数
console.log(new Date(1620551340587)) //事件戳转事件
转换
now.toLocaleString() //调用的是一个方法,不是一个属性
now.toGMTString()
2.JSON
json是什么
- 早期,所有数据传输习惯使用XML文件!
- JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式
- 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
在
JS中一切皆对象,任何js支持的类型都可以用JSON表示 - 对象用{}
- 数组用[]
- 键值对用key:value
JS对象和JSON字符串的转换
var user={
name:"chenstudy",
age:18,
sex:"男"
}
var jsonUSer = JSON.stringify(user);//JS->JSON
var obj = JSON.parse('{"name":"chenstudy","age":18,"sex":"男"}')
JSON和JS对象的区别
var obj={name:"chenstudy",age:18,sex:"男"};
var json='{"name":"chenstudy","age":18,"sex":"男"}'
3.Ajax
- 原生js写法 xhr异步请求
- jQuey封装好的方法
- axios请求
六.面向对象编程
1.对象和类
- 类:模板
- 对象:具体的实例
原型
var Student ={
name="xiaoming",
study:function(){
console.log(this.name+"study")
}
};
var chen = {
name:"chen"
};
//原型
chen._proto_=Bird;
class继承
class关键字,在ES6引入的
class Student{
constructor(name){
this.name=name;
}
hello(){
alert('hello');
}
}
var chen = new student("chen");
chen.hello;
继承(本质:原型)
class midStudent extends Student{
constructor(name,grade){
super(name);
this.grade =grade;
}
mygrade(){
alert("hello,midStudent");
}
}
原型链
七.操作BOM对象(重点)
window
window代表浏览器窗口
window.alert(1)
undefined
window.innerHeight
879
window.innerWidth
167
window.outerHeight
878
window.outerWidth
683
Navigator
Navigator封装了浏览器的信息
navigator.appName
"Netscape"
navigator.appVersion
"5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
navigator.userAgent
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
navigator.platform
"Win32"
大多数情况,我们不会使用navigator对象
不建议使用这些属性
scree
代表屏幕尺寸
screen.width
1549 px
screen.height
872 px
location
location代表当前页面的URL信息
host: "www.baidu.com"
hostname: "www.baidu.com"
href: "https://www.baidu.com/"
protocol: "https:"
reload: ƒ reload() //刷新网页
location.assign('https://i.cnblogs.com/posts/edit;postId=14736906') //设置新的地址
document
document代表当前的页面,HTML DOM文档树
document.title
"百度一下,你就知道"
document.title="chenstudy"
"chenstudy"
获取具体的文档数节点
<dl id="ip">
<dt>Java</dt>
<dd>JavaSE</dd>
<dd>JavaEE</dd>
</dl>
<script>
var dl =document.getElementById('ip')
</script>
获取cookie
document.cookie
"BIDUPSID=8FFC189A44E65B4082968A90334BA305; PSTM=1610976142; BAIDUID=8FFC189A44E65B40E0850B796C795C7D:FG=1; BD_UPN=12314753; sug=3; sugstore=0; ORIGIN=2; bdime=0; H_PS_PSSID=33823_31253_34004_33676_33607_26350_22160; BD_HOME=1; rsv_jmp_slow=1620483057243; delPer=0; BD_CK_SAM=1; PSINO=3; BAIDUID_BFESS=8FFC189A44E65B40E0850B796C795C7D:FG=1; BDRCVFR[dG2JNJb_ajR]=mk3SLVN4HKm; BDRCVFR[-pGxjrCMryR]=mk3SLVN4HKm; BDRCVFR[tox4WRQ4-Km]=mk3SLVN4HKm; BDRCVFR[Tp5-T0kH1pb]=mk3SLVN4HKm; H_PS_645EC=3634BMU6WIVhhsixuAIIO4euErZR2nrNXHuWEFtqd%2FWEJ%2BPU3PIj%2BhUXIOQ; BA_HECTOR=ah0k0181al0gag05ip1g9fi390q; BDSVRTM=0"
- 截取cookie:恶意人员获取你的cookie上传到它的服务器
- 服务器端可以设置cookie为httpOnly
history
history:浏览器的历史记录
history.back() //后退
history.forward //前进
八.操作DOM对象(重点)
核心
DOM树形结构就是浏览器的网页
- 更新:更新DOM节点
- 删除:删除一个DOM节点
- 遍历DOM节点:得到DOM节点
要操作DOM节点,就必须先获得这个DOM节点
获取节点
//原生代码,之后使用jQuery
<div id="father">
<h1>标题</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
</div>
<script>
var h1=document.getElementsByTagName('h1');
var p1=document.getElementsById('p1');
var p2=document.getElementsByClassName('p2');
var father=document.getElementsById('father');
//father.children;
//father.firstChild;
//father.lastChild;
</script>
更新节点
<div id="id1">
</div>
<script>
var id1= document.getElementById('id1');
</script>
操作文本
id1.innerText='456'//修改文本的值
id1.innerHTML='<strong>123<strong>';
操作css
id1.style.color = 'red';
id1.style.fontSize='18px';
id.style.margin = '10px';
删除节点
- 删除节点的步骤:先获取父节点,再通过父节点删除自己
<div id="father">
<h1>标题</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
</div>
//删除p1节点
<script>
var self = document.getElementById('p1');
var father = p1.parentElement;
father.removechild(self)
</script>
- 注意:删除节点是一个动态的过程,children时刻在变化!
father.removechild(father.children[0])
father.removechild(father.children[1]) //这里的children[1]是开始的children[2]
插入节点
- 节点不存在元素时,可以通过innerHTML增加一个元素
- 已经存在元素时,就不能这么干了,会产生覆盖
追加 - 追加已存在的节点
<p id='js'>JavaScript</p>
<div id='lost'>
<p id='SE'>JavaSE</p>
<p id='EE'>JavaEE</p>
<p id='ME'>JavaME</p>
</div>
<script>
var js=document.getElementById('js');
var lost = document.getElementById('lost');
lost.appendChild(js);//追加已存在的节点
</script>
- 追加一个新节点
<p id='js'>JavaScript</p>
<div id='lost'>
<p id='SE'>JavaSE</p>
<p id='EE'>JavaEE</p>
<p id='ME'>JavaME</p>
</div>
<script>
var js=document.getElementById('js');
var lost = document.getElementById('lost');
var newp = document.createElement('p');//创建一个p标签
newp.id='newp';//为节点赋值一个id
newp.innerText = 'hello,java';
lost.appendChild(newp);//追加一个新节点
</script>
- 设置样式
<p id='js'>JavaScript</p>
<div id='lost'>
<p id='SE'>JavaSE</p>
<p id='EE'>JavaEE</p>
<p id='ME'>JavaME</p>
</div>
<script>
//创建一个标签节点
var myScript = document.createElement('script');/创建一个空的script标签
myScript.setAttribute('type','text/javascript');
//创建style标签
var myStyle = document.createElement('style');/创建一个空的style标签
myStyle.setAttribute('type','text/css');
myStyle.innerHTML = 'body{backgroud-color: white}';//设置标签内容
doucment.getElementsByTagName('head')[0].appendChild(myStyle); //将标签插入head中
</script>
- insert
list.insertBefore(js,ee);//将js节点插入到ee节点前
//选择的节点.insertBefore(newNode,targetNode)
九.操作表单(验证)
表单是什么
常见表单
- 文本框 text
- 下拉框