历史
参考狂神说Java b站视频
入门
1.JavaScript定义
行为层
合格的后端人员,必须要精通 JavaScript(了解、熟悉、掌握、精通)
JavaScript 是一种弱类型脚本语言,其源代码在发往客户端运行之前不需经过编译,而是将文本格式的字符代码发送给浏览器,由浏览器解释运行。
Native原生 JS 开发
原生JS开发,也就是要按照【ECMAScript】标准的开发方式,简称ES,特点是所有浏览器都支持。
(ECMAscript 是 JavaScript的一个标准)
(版本区别就是逐步增加新特性)
ES3
ES4(内部,未正式发布)
ES5(全浏览器支持、大部分浏览器还停留在此)
ES6(常用,当前主流版本:webpack打包成为ES5支持!)
ES7
ES8
ES9(草案)
开发环境、线上环境,版本不一致
TypeScript
形成JavaScript文件
2.JavaScript框架
JQuery(是一个库)
优点
简化了DOM操作
封装了很多方法,直接用就可以。
缺点
DOM操作太频繁,影响前端性能
(使用它,仅仅是为了兼容IE6、7、8)
三大框架
a.Angular
Google收购的前端框架,由一群 Java程序员 开发。
特点是
-
将后台的MVC模式搬到了前端
-
并增加了模块化开发的理念
-
与微软合作,采用TypeScript语法开发。
-
(对后台程序员友好,对前端程序员不太友好)
最大的缺点
版本迭代不合理(除了名字,基本是两个东西)
b.React
Facebook出品,一款高性能的 JS 前端框架。
特点
-
提出了新概念【虚拟DOM】(增加网页响应速度),用于减少真实DOM操作。
-
在内存中模拟DOM操作,有效提升了前端渲染效率。
缺点
使用复杂,需要额外学习一门 【JSX】 语言
c.Vue(综合了其他两个的特点)
一款渐进式 JavaScript框架,渐进式——逐步实现新特性的意思。
(如实现模块化开发,路由,状态管理等新特性)
特点
综合了Angular(模块化)和 React(虚拟DOM)的优点
Axios(封装更简单)
前端通信框架
Vue的边界很明确,就是为了处理DOM,所以不具备通信能力。
(需要额外使用一个通信框架与服务器交互)
也可以直接选择使用 JQuery 提供的 AJAX 通信功能
3.UI框架
Ant-Design,阿里巴巴出品,基于React的UI框架(有后端的模板)
ElementUI、iview、ice:饿了么出品,基于Vue的UI框架
(前后端分离之后用的多,以上两个)
Bootstrap:Twitter推出的一个用于前端开发的开源工具包
(前后端没有分离时,用的多,较为成熟)
AmazeUI:“妹子UI”,一款HTML5跨屏前端框架
(可以写个人博客)
4.JavaScript构建工具
Babel:
JS 编译工具,主要用于浏览器不支持的ES 新特性,比如用于编译TypeScript
Webpack:
模块打包器(打包成ES5)
主要作用是打包、压缩、合并以及按序加载。
以上全部都要安装Nodejs才能进行使用
5.三端统一(H5)
混合开发(Hybrid App)
主要目的是实现一套代码三端统一(PC、Android:.apk、IOS:.ipa)
并能够调用到设备底层硬件(如,传感器、GPS、摄像头等)
打包方式(两种)
云打包:HBuild -> HBuildX,Dcloud出品;API Cloud
本地打包:Cordova(前身是PhoneGap)
微信小程序
详情见微信官网,方便开发的框架:WeUI
6.后端技术
前端人员为了方便开发,也需要掌握一定的后端技术,但Java后台人员知道后台知识体系极其庞大复杂,所以为了方便前端人员开发后台应用,就出现了 NodeJS 这样的技术。
NodeJs作者声称已经放弃,开始开发全新架构的Deno
后台技术,也需要框架和项目管理工具,NodeJS框架及项目管理工具如下
Express:NodeJS框架
Koa:Express简化版
NPM:项目综合管理工具,类似于Maven
YARN:NPM的替代方案,类似于Maven和Gradle的关系
入门基本
1.引入JavaScript
内部标签引入
在head标签内,或者body最下面。(最好放最后面)
外部引入
abs.js
test.html
一般不在HTML里面写,会另外开一个专门放 js 的文件夹。然后在html里面引入
PS:script 必须成对出现;且不用写定义type,它默认是JavaScript。
2.基本语法入门(js严格区分大小写)
改成es6语法,eslink 语法检查插件。
a.变量类型 变量名 = 变量值;
var num = 1;
不能用数字开头,可以用$开头,大写字母可以,小写字母可以。
可以 var 你好 = “好的”
b.条件控制
if(2>1){
alter(“true”);
// 弹窗
}
3.浏览器控制台使用(调试必须会)
右键——审查元素——控制台。
在浏览器控制台打印变量 console.log(score) (system.out.println() )
调试器Source(打断点)
堆栈信息,可以打断点(点一下行号就可以),刷新就可以运行。
网络Network(抓包)
网络请求,
存储Application
web里的数据(储存在网页上)
cookies用的最多
4.数据类型(可以在控制台调试)
数值,文本,图形,音频,视频。。。
a. number
JS(不区分小数(浮点数),整数,科学计数法,复数,NaN(不是数字))****
b. 字符串
不可以在控制台换string内部的字符
‘abc’ “abc”
打印\'
就可以写出引号。
- \n 换行
- \t table
- \u4e2d \u#### Unicode字符
- \x41 Ascll字符
多行字符串编写
tab上面,esc下面,那个飘里面可以编写多行字符串
模板字符串(el表达式)
你好,${}
不用写+号了,就直接连接了。
字符串长度
console.log(变量名.length)
console.log(变量名[0]) (字符不可变)
substring( 包头不包尾 [ ) )
c. 布尔值
true false
d. 逻辑运算
与 &&
或||
非!
e. 比较运算符(坚持不用==)
= 赋值
== 等于(类型不一样,值一样,也会判断为true)
=== 绝对等于(类型不一样,值一样,结果为true,否则是false)
NaN===NaN (这个与所有数值都不相等,包括自己)
只能通过isNaN(NaN)来判断这个数是否是NaN
f. 浮点数问题
console.log(1/3) === (1-(2/3)) 会出问题!
尽量避免使用浮点数进行运算,存在精度问题。
这样可以:console.log(Math.abs(1/3-(1-2/3)<0.00000001))
g. Null 和 Undefined
Null 定义了,但是空
Undefined 没有定义
h. 数组[ ] (中括号) 存储数据,知道如何存如何取就行。
Java的数组必须是相同类型的对象,JS 中不需要相同类型。
(可以包含任意的数据类型)
var arr = [1,2,3,4,“hello”,null,true]
保证代码的可读性,尽量使用中括号[]
1.长度
arr.length(可以在控制台改变数组的 长度)
假如给 arr.length 赋值,数组大小就会发生变化。
如果赋值过小,元素会丢失。
在数组里没有写的,就会undefined
2.IndexOf
arr.IndexOf(元素),通过元素获得下标索引。
字符串的 “1” 和数字 1 不同。
3.slice()类似substring
截取array的一部分,返回一个新数值,包头不包尾。
4.push,pop 尾部
arr.push(‘a’,‘b’) 往里面压入到尾部
arr.pop() 弹出尾部的元素
5.unshift() shift() 头部
arr…unshift(‘a’,‘b’) 往里面压入到头部
arr.shift() 弹出头部的元素
6.sort() 排序
7.reverse() 元素反转
8.concat() 拼接
返回新的数组,并不会修改数组
9.连接符 join
打印拼接数组,使用特定的字符串连接
arr.join(’-’)
数组就变成“C-B-A”
10.多维数组
可以无限继承object
i. 对象{ } (大括号) 叫函数,不叫方法
若干个键值对。键是字符串,值任意对象。
var person对象名 = {
name属性名: “hello”属性值,
age:3,
tags:[‘js’,‘java’]
}
每个属性之间用逗号隔开,最后一个不用加逗号。
1.对象赋值
直接赋值就行
2.使用一个不存在的对象属性,不会报错!undefined
person.haha
undefined
3.动态的删减属性
delete直接删除属性
4.动态的添加
直接给新的属性添加值,即可
person.haha = “haha”
“haha”
person就多了一个属性
5.判断属性值是否在这个对象中
‘age’ in person
true
//继承
‘toString’ in person
true
6.判断一个属性,是否是这个对象,自身拥有的
person.hasOwnProperty(‘age’)
true
5.流程控制
最好用 let 局部变量
5.1、if 判断(if,else if,else)(和java一样)
5.2、while循环,避免死循环(和java一样)
for(let i = 1;i < 100; i++){
console.log(i);
}
5.3、forEach循环(es5.1引入的)
var age = [12,1,12,3,212]
age.forEach(
//函数
function (value) {
console.log(value)
}
)
5.4、for…in(和java差不多)(let 是索引、下标)有bug
java里面
// for(Type str: el){ }
JavaScript里
// for(let index in object对象){ }
for(let num in age){
if( age.hasOwnProperty(num) ){
console.log(“存在”);
console.log( age[num] )
}
}
5.5、for…of 遍历 数组 和map(let 是数组里的值)(比in好用)
es6才有的
for(let x of map){
console.log(x)
}
5.6、iterator(最好用这个 去 遍历)
es6才有
遍历 Map 和 Set
6.严格检查格式
‘use strict’; (严格检查模式,预防js的随意性导致产生的一些问题。)
必须写在js的第一行!
局部变量(let 定义 es6)
let i = 1;
7.Map和Set
es6里才有这两个
new Map();
//和 java 的map 很像
var map = ( [‘tom’,100], [‘jack’,90] );
var name = map.get(‘tom’); //通过key 获得value
map.set(‘admin’,123); // 新增或者修改
map.delete(‘admin’); // 删除
console.log(name);
new Set();(无序不重复的集合)
set可以去重
var set = new set( [5,6,7] );
set.delete(1) ;
set.add(2);
set.has(3); //是否包含某个元素
8.函数及面向对象
8.1、函数定义及变量作用域
在类里面的叫方法,不在类里面的叫函数。
定义函数
定义方式一(后端喜欢)
// return 不要换行!
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;
}
}
上面是个匿名函数。但是可以把结果赋值给abs,通过abs就可以调用函数!
调用函数
函数名(传递值)
方法名(参数)
参数问题
JavaScript可以传任意个参数,也可以不传递参数。
参数是否存在的问题? 假设不存在参数,如何规避。
//手动抛出异常
if(typeof x !== ‘number’){
throw ‘Not a number’;
}
arguments(所有参数都接受了 包括x本身)
免费赠送的关键词
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)
rest参数(接受除了x 之外的所有参数)
es6新特性,获取 除了已经定义的参数之外的 所有参数。
是数组。
以前如何获取
if(arguments.length>2){
for(var i = 2; i < arguments.length; i++){
//…
}
}
现在(必须要有…):
function aaa(a,b,…rest){
console.log(“a=>” + a);
console.log(“b=>” + b);
console.log(rest);
}
变量的作用域
局部函数
在javascript中,var 定义变量实际是有作用域的。
假设在函数体中声明的,则在函数体外不可以使用~(非要想实现的话,后面可以研究一下闭包)
如果两个函数使用了相同的变量名,只要在函数内部,就不冲突。
内部函数可以访问外部函数的成员,反之则不行。
假设内部函数变量和外部函数变量,重名!
在JavaScript中,函数查找变量从自身函数开始,由“内”向”外“查找,假设外部存在这个同名的函数变量,则内部函数会**屏蔽 ** 外部函数的变量。
变量局部生效,内部可以访问外部,内部有了外部的变量但就只用内部的,外部不能访问内部。
提升变量的作用域
结果:xundefined
说明:js执行引擎,自动提升了y的声明,但是不会提升变量y的赋值
这个是在JavaScript建立之初就存在的特性。
养成规范:所有的变量定义,不要乱放,便于代码维护。
全局函数
‘use strict’;
var x = 1;?// 全局变量
function f(){
console.log(x);
}
f();
console.log(x);
全局对象 window(window代表浏览器)
var x = ‘xxx’;
alert(x);
alert(windows.x); // 默认所有的全局变量,都会自动绑定在windows对象下
(以上作用相似)
alert() 这个函数本身也是一个 window的变量
JavaScript 实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,报错referenceError
规范 (自己去定义一个全局变量)
由于我们所有的全局变量都会绑定到我们的windows上。如果不同的js文件,使用了相同的全局变量,冲突~>如果能够减少冲突?
// 唯一一个全局变量
var Me = {};
// 定义全局变量
Me.name = ‘Hi’;
Me.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); //问题: i 出了function的作用域还可以使用
}
ES6 关键字let,解决局部作用域冲突问题!
function aaa(){
for (let i = 0; i <100; i++){
console.log(i);
}
console.log(i+1); // Uncaught ReferenceError: i is not defined (正确)
}
建议都使用 let 去定义局部作用域的变量
常量 const
在ES6 之前 如何定义常量:只有用全部大写字母命名的变量就是常量;建议不要修改这个值
const PI = ‘3.14’; // 只读变量,不能改
PI = ’123‘; // TypeError: Assignment to constant variable
8.2、方法
定义方法
方法在对象的内部,调用时记得在名字后面加上()
var Me = {
name: 'Hi',
birth: 2000,
// 方法
age:function(){
//今年 - 出生的年
var now = new Date().getFullYear();
return now - this.birth;
}
//属性
Me.name
//方法,一定要带()
Me.age()
}
拆写方法
this. 代表什么?(当前对象)拆开上面的代码看看
在对象内部只用写方法(函数)名字。
function getAge() {
//今年 - 出生的年
var now = new Date().getFullYear();
return now - this.birth;
}
var Me = {
name: 'Hi',
birth: 2000,
age: getAge
}
//Me.age() ok
// getAge() NaN windows 调用
this 是无法指向的,是默认指向调用它的那个对象;
关键词 apply
在js 中可以控制 this 指向
getAge.apply(Me,) //this,指向 Me 这个对象,参数为空
所有函数都有,可以指定函数
8.3、闭包(难点)
8.4、箭头函数(新特性)
9.具体特殊对象
标准对象
Date
var now = new Date(); // 当时的时间
转换
JSON
早期,所有数据传输习惯使用 XML(重量级的数据传输文件) 文件!
是什么?
- 是一种轻量级的数据交换格式,是基于ECMAscript的一个子集。
- 简洁和清晰的层次结构使得JSON 成为理想的数据交换语言
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
在JavaScript里,一切皆为对象,任何js 支持的类型都可以用 JSON表示。
JSON格式:
- 对象都用{}
- 数组都用[]
- 所有的键值对 都是用 key: value
JSON 和 JS 对象的区别
JSON 是字符串,JS 对象是键值对。
后端给前端传递一个JSON,通过前端去解析它。
Ajax
- 原生的 js 写法,xhr异步请求
- JQuery 封装好的方法 $("#name").ajax("")
- axios请求
前端做后台用Node.js,后端用JAVA。
10.面向对象编程
什么是面向对象(原型对象)
JavaScript、java、C#… 特性:面向对象。JavaScript有一些区别!
- 类:模板 原型对象(抽象)
- 对象:具体的实例(具体)
在JavaScript 需要大家换一下思维方式!
原型继承
xiaoming._proto_ = Student; // 小明原型是 student
(可以随便换原型。。。)
class继承
es6之前
es6之后class引入了,现在很多浏览器还没有办法应用。
1.定义一个类
2.继承
3.JavaScript原型链(面试考的多)(Java叫继承)
指针,
11.操作BOM对象(重点)
浏览器介绍
JavaScript诞生就是为了让他能在浏览器中运行!
B:浏览器
BOM:浏览器对象模型
(内核)
- IE6~11
- Chrome
- Safari
- FireFox(Linux开发比较多)
- Opera(安卓,塞班、OPPO的浏览器)
三方
-
QQ浏览器
-
360浏览器
1、window
window代表 浏览器窗口
2、navigator
封装了浏览器的信息,大多数时候,我们不会使用 navigator 对象,因为会被人人为修改!
不建议使用这些属性来判断和编写代码。
3、screen
代表当前屏幕的尺寸、大小
获取计算机屏幕,浏览器可以操控电脑,脚本、、
4、location(重要)
代表当前页面的URL信息(网页的核心URL)
5、Document(内容,DOM里具体讲)
代表当前页面(可以改title
获取具体的文档树节点
获取cookie
劫持cookie原理
服务器端可以设置cookie:httpOnly
6、History
代表浏览器的历史记录
12.操作DOM元素(文档树)
DOM:文档对象模型
核心:整个浏览器网页就是一个DOM树形结构!
- 更新:更新Dom节点
- 遍历Dom节点:得到Dom节点
- 删除:删除一个Dom节点
- 添加:添加一个新的节点
要操作一个Dom节点,就必须要先获得这个Dom节点
12.1、获得DOM
document.getElementById('xx')
这是原生代码,之后我们尽量用JQuery
12.2、插入DOM(节点)
我们获得了某个DOM节点,假设这个dom节点是空的,我们通过innerHTML就可以增加一个元素。
但是这个DOM节点已经存在元素,那我们就不能这么添加了。(会覆盖原始的内容,全变成新的了)
方法:
1.用追加 append (把已有的标签添加在后面)
2.创建一个新的标签,append实现插入
3.创建一个标签节点
4.创建一个style标签
5.插入到前一个
<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');
list.appendChild(js); //追加到后面
//方法二:通过JS创建一个新的节点
document.createElement('p'); //创建一个p标签
newP.id = 'newP';
newP.innerText = 'hello,nihao';
list.appendChild(newP);
//创建一个标签节点(通过这个属性,可以设置任意的值)
var myScript = document.createElement('script');
myScript.setAttribute('type','text/javascript')
</script>
4.创建一个style标签
5.插入到前一个
12.3、更新DOM
修改内容
在console里写
id1.innerText='456'
修改文本的值
id1.innerHTML=‘<strong>123</strong>’
可以解析HTML文本标签
操作css
id1.style.color = 'yellow'; // 属性使用 字符串 包裹
id1.style.fontSize = '20px'; // 驼峰命名
id1.style.padding = '2em';
直接在console里修改
12.4、删除DOM
步骤:先获取父节点,再通过父节点删除自己
<script>
var self = document.getElementById('p1');
var father = p1.parentElement;
father.removeChild(p1)
</script>
删除是一个动态的过程,删除0,后面的(1,2)会自动补上变成(0,1)
注意:删除多个节点的时候,children是在时刻变化的,删除节点的时候一定要注意。
13、获得和设置表单的值
form, DOM树里的一个节点
- 文本框 text
- 下拉框
- 单选框 radio
- 多选框 checkbox
- 隐藏域 hidden
- 密码框 password
- 。。。。
表单的目的:提交信息
获得要提交的信息
表单提交验证
1.绑定事件
2.表单绑定提交事件
前端密码MD5加密
导入MD5工具类
<script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
14、初识JQuery及公式
JavaScript
JQuery库,里面存在大量的JavaScript函数
获取JQuery
1.官网下载
2.cdn(content delivery network)从网页上引入
公式
$(selector).action()
selector就是css的选择器
选择器
文档工具站
id选择器前面要加#
事件
鼠标、键盘、其他事件
操作DOM
Ajax
15、未来学习
1.读小游戏源码(不是太长的)
2.扒已有的网页,学习(巩固HTML和CSS)
3.看JQuery源码
Layer弹窗组件
Element-UI
Ant Design