复习
jQuery
是个功能包,独立的js文件(本质)
es5写的(没有class)使用原型链来写的是(所以)
时间久远(所以不能使用es6的语法)
版本问题:1-3,不使用3的原因是无法兼容ie678,且也有更好的框架,鸡肋
(但是仍然不排除他很好用,虽然就现在来说直接操作DOM元素会大大的消耗资源,但是ajax那一部分的方法仍可以使用,好用嘛,相较XMLHTTPRequest来说一步步的处理代码量要少很多)
错误:
出现以下错误的原因:是style前面的属性有问题
然后一层一层的去打印前面的信息,去一层一层排查
(先加载脚本再去选择html里已有的元素就会出现这种错误)
只要把脚本引入写在最后面就行了
第二行错误原因:函数没有返回值/没有这个属性
关于函数
函数,对象的方法,构造函数(涉及到)原型对象及其原型链)闭包等都是函数
解决了变量污染问题:使用闭包(自运行函数)
箭头函数可在嵌套函数中改变this指向
使用闭包(自运行函数)(需要好好理解)
JS三大块:
1.ES:JS语法部分
2.DOM:文档对象模型,可以操作浏览器的页面效果,是因为浏览器为我们提供了API接口,才有对应方法的使用
3.BOM:浏览器对象模型
常用功能包,框架
1.zepto:jQuery简化版(主要是放弃兼容低版本)
2.echart:画图神器(图表类工具)
3.three:游戏开发,3D渲染,效果制作
4.elementUI,bootstrap(前端构造,特色的栅格系统),layUI(前端页面快速构建),ant design Swiper(轮播图专用)
5.Vue,React,Angular(挺有用的,多学习学习)
遗漏知识点
1.AJAX请求过程和使用jQuery实现
通常流程
function fn1() {
//1.创建ajax对象并且做上兼容
var xhr = new XMLHttpRequest() || ActiveXObject("Microsoft.XMLHTTP")
//2.建立链接
xhr.open("get", "http://192.168.191.1:3000/test.json", true)
//get速度快,post反应慢但是安全
xhr.send()
//3.发送数据
//HTTP协议 get post 区别 状态码 请求msg和响应msg的格式
//4.事件 监听整个请求变化的过程
//readyState值的意义
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) { //readyState和status的区别
//readyState代表后端到底有没有返回数据,网络请求的状态
//status代表数据包的的状态
//5.后端给前端传输的数据
console.log(xhr.responseText)
}
}
}
//6.setdataToUI jquery dom Vue react wx
HTTP协议:
请求方式get和post的区别:首先本质上是没有区别的,都是基于TCP链接上的信息传输方式,不同是由于HTTP协议和服务器的种类造成了使用方式和响应,接受数据方式上的不同,以及便于管理
详细的说:get用于获得数据,post用于发送数据,可能会改变服务器信息
get的请求参数是放在请求行URL之后的,post则是放在请求数据中的
get请求会被服务器主动缓存,post不会
具体说一说get和post传值的区别
get的值在xhr.open("get", "http://192.168.191.1:3000/test.json?name=123&pwd=456", true)
路由的后面用问号开头,以键值对的方式进行传递值
当然如果是登录之类,就要先获取表单的值,以下都针对于表单
常规方式:var name = document.querySelector('#name').value
Vue:要先给对应input的属性里添加v-model,v-model里填上对应的变量,再在创建的vue对象里的data里注册该变量(键值对的方式),然后在methods里写ajax的五步请求,获取值直接用this.name,如下
<form action="" id="app">
<input type="text" v-model='name'>
<input type="password" v-model='pwd'>
<input type="button" value="Log" @click="getter">
</form>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
name: '',
pwd: ''
},
methods: {
getter: function() {
console.log(this.name)
console.log(this.pwd)
var xhr = new XMLHttpRequest()
xhr.open('post', `http://192.168.191.1:3000/ss`)
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(`name=${this.name}&pwd=${this.pwd}`)//这里就是获取到输入框的值了
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log('success')
}
}
}
}
})
然后再说说post
两者在代码上的最大区别是这两点
get:传值是在指定url后面以?
开头&
做连接符,以键值对的方式传值
post:首先要添加请求头这一行代码
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
(第二个参数不定,视传输数据类型而定)
第二是如果以上面的请求头方式,那么数据就必须以下列方式实行
xhr.send(`name=${this.name}&pwd=${this.pwd}`)
Ps:模板字符串很好用的噢
jQuery(再补充,未完成)
2.es6常用语法
一.let&const
1.let:其实es6改变了很多东西,至少让我又习惯了JS,为什么说是又,那就是let,毕竟以前C,Java学习惯了,对于变量的声明和作用域比较严格,Js在es5,还没提出这些功能,例如,块级作用域这类
但是从let出现之后,变量的声明和赋值就不存在es5里的声明提前,隐式声明等等,总结来为以下特点:
①.不能先使用在声明
②.不能重复声明
③.有块级作用域
2.const:这个关键字修饰的变量,声明后必须赋值,也就是初始化,而且初始化之后,不能进行修改(覆盖),可以理解成自己规定的常量
二,解构赋值
简单的说就是按照某种数据的解构,解析然后进行赋值(就是给数据写个模子,然后去对应数据里取数据,取出来的数据,按照模子里的结构,对应的去给它们赋值)
是一个相当简洁的方法,同样的还可以进行多层的解构,加上for循环,便可以用于大型后台数据的全部打印
例子:
//数组
var [a,b,c] = [1,2,3]; //把数组的值分别赋给a,b,c几个变量
console.log(a); //1
console.log(b); //2
console.log(c); //3
//对象
var {a:{b}} = {"a":{"b":1}};
console.log(b); //1
同样的,也可以运用于函数的形参上
es6解构赋值详解
PS:…xx
2个用法
…xx xx是已知的容器名字:把容器中数据取出来: var arr=[1,2,2,1,3];var arr2=[…arr]
…xx xx是自己取的名字 在解构赋值中把容器中剩余数据取出来,给剩余数据去个xx的名字
类与对象(再补充)
简单的说类似Java的class
箭头函数(再补充)
两者的区别在于函数的执行环境对象不同,传统函数一般是调用函数者,调用方法者,箭头函数不同
一般来说是window对象或者说箭头函数所在的嵌套函数的上层
//传统的函数格式
var fn = function(){
......
}
//箭头函数形式
window.fn(()=>{
......
})
3.闭包
4.iframe 和 frame的缺点
5.promise(重点)
6.数组和字符串常用方法(重点)
数组
1.concat连接两个或更多的数组
7.判断对象在不在类中
8.判断数据类型(方法的区别和优劣)
9.事件委托和冒泡
10.Firefox和IE事件机制区别
11.js代码书写规范
12.里氏替换原理(还没看过)
13.单继承和多继承及es6继承方式
14.Nodejs三大特性
单线程,非阻塞I/O,事件驱动
单线程:node就是不同于java,php,.net可以启动多个线程,nodejs是单线程,为什么是单线程,是为了提高服务器性能,因为多开一个线程就会多占用一个cpu资源,单线程减少了内存开销,操作系统的内存换页
非阻塞I/O:单线程在执行时不会因为I/O阻塞就等待I/O执行结束而是响应其他排队的事件等I/O执行结束,再把I/O返回的结果继续执行,也就是这个线程是一直在工作的
事件驱动:不管是新用户的请求,还是老用户的I/O完成,都将以事件方式加入事件环,等待调度
这个三个特性是统一的缺一不可
15.JS两种标准异步处理工具
Promise,Generator
16.call,apply,bind
一.call
1.一般来说,当函数或者构造函数中,含有this关键字这类程序
如果不调用就不会运行,也就是说,当去调用函数的时候,this才会指向调用者的名字,所以不运行就不知道this指向的到底是谁。
2.当使用call关键字时,如下
// var obj1={name:"jack",age:18,say:function (arg1,arg2) {
// console.log(arg1,arg2)
// console.log(this.name,this.age)
// }}
// var obj2={name:"xxxxx",age:"xxxx"}
// obj1.say()
// obj2.xxx=obj1.say
// obj2.xxx()
// obj1.say.call(obj2,100,200)
最后一行代码就是call的用法
先看个简单的obj1.say.call(obj2) 这里就是说将obj2指定为函数obj1.say的调用者,所以当你去使用obj1.say.call(obj2) 时里面的this指向的就是obj2,打印的name,age都是obj2的name,age
关于 obj1.say.call(obj2,100,200),这里就是先将函数的调用者标明为obj2,然后再传入100,200这两个参数
二.apply
1.apply和call类似,唯一不同的就是在传入参数的时候,传入的数据要用数组来传递例如 obj1.say.call(obj2,[100,200])
三.bind
1.bind也是设计用来指向函数的调用者的,与apply,call的区别就是bind是在设计函数时就已经把函数的调用者写好了,call和apply是在使用时再去传入指定的函数调用者。
2.不过声明的函数一般来说不能直接绑定,只能方法直接绑定,如
var obj2={name:'karen',say:function() {
console.log(this)
}.bind(obj1)}
17.深度克隆方式
简单的说 for-in可以完成
这里说到的区别就是:声明变量的拷贝本质上只是为相同内存增加了更多的引用值
所以实现深度拷贝的原理实际上是重新开辟一片内存,然后再将之前的内存数据写入到新的内存中
18.防抖与节流
19.数组和字符串的去重(不使用map)和计算字符串中最多字符和各字符数量
//字符串的
var str = 'adiadaidsaidiasd'
function rid(str) {
var newarr = ''
for (let i = 0; i < str.length; i++) {
if (newarr.indexOf(str[i]) == -1) {
newarr += str[i]
}
}
return newarr
}
//数组的
var num = [1, 5, 1, 4, 1, 6, 1, 5, 1, 5, 1, 5]
function ridnum() {
var newnum = []
for (let i = 0; i < num.length; i++) {
if (newnum.indexOf(num[i]) == -1) {
newnum.push(num[i])
}
}
return newnum
}
//计算字符串中最多字符和各字符数量
function objMethod(str) {
var obj = {};
for (var i = 0; i < str.length; i++) {
var char = str.charAt(i);
if (obj[char]) {
obj[char]++;
} else {
obj[char] = 1;
}
}
console.log(obj);
var max = 0;
for (var key in obj) {
if (max < obj[key]) {
max = obj[key];
}
}
for (var key in obj) {
if (max == obj[key]) {
console.log(key + ":" + max);
}
}
}
objMethod("asddddasasssssassf");