1,JS循环
1,遍历数组,20年前JavaScript刚萌生的时候,实现遍历的方法:
function eachArray(myArray) {
for(var index = 0; index < myArray.length; index++){
console.log(myArray[index])
}
}
/* 20年之前的for循环写法*/ var myArray = [1,2,3,4,5,5,6] eachArray(myArray)
自ES5发布之后,可以使用内建方法:forEach
/* ES5的写法*/
myArray.forEach(function(value) {
console.log(value)
})
这样写的缺点是:不能使用break语句,也不能使用return语句返回到外层
有很多人尝试用for-in 循环:比如:
for(var index in myArray){
console.log(myArray[index])
}
但是:千万不要这样做,有很大的问题存在
切记: (1)index是字符串,不是number类型
(2)for-in是为遍历对象而设计的,不适应数组的遍历
ES6最强大的集合遍历方法是:for-of
for-of可以遍历:数据,类数组,Set集合,Map集合,不支持普通对象的遍历
/*ES6的写法*/
for(var value of myArray) {
console.log(value)
}
/* for-of不仅可以遍历数组还可以遍历字符串*/
for(var chr of "abcdefg") {
console.log(chr)
}
/* for-of还可以遍历set,map对象*/
var words = ['a', 'b', 'c', 'd', 'a', 'a']
var uniqueWords = new Set(words)
for(var word of uniqueWords) {
console.log(word) }
/* map对象需要解构成键值对形式*/
var phone =[ ["a", 1], ["b", 2], ["c", 3] ]
var phoneMap = new Map(phone)
for(var [key, value] of phoneMap) {
console.log('key=' + key, 'value=' + value)
}
普通对象的遍历方法:
/*for-of不支持普通对象循环,对象的循环用for-in 或者 Object.keys()*/
for(var key of Object.keys(someObject)) {
console.log(key + ':' + someObject[key])
}
2, JS 变量
1,关于定义变量
(1)之前:var a=12;
作用域: 全局 , 函数作用域
(2)ES6中 新增 块级作用域
let 注意:
1,没有预解析,不存在变量提升
2,在代码块内,只用let定义变量,在之前使用,都是报错,即 先定义完,在使用
3,相当于之前的var 没有变量提升,同一个代码库中,不支持重复定义
4,for循环,for循环里面是父级作用域,
const 常量,定义好了,不能改变
const arr = Object.freeze(['zlm','orgin']);
(3)立即执行函数 IIFE
之前:(function(){})();
现在: {};
建议:以后再不要var 了
2,解构赋值
(1) 非常有用,特别是在做数据交互,ajax
let [a,b,c]=[1,3,5]; 注意:左右两边,结构格式要保持一致
解构可以取别名[name:n]
解构可以赋默认值[a,b,c="暂无数据"]=[1,3];
3,字符串模板:
优点:可以随意换行
这个是趋势${name}
新增字符串查找: 以前用indexOf();返回索引位置和 -1比较
includes();返回true/false
if(navigator.userAgent.includes('Chrome')){
alert("是Chrome");
}else{
alert("不是Chrome");
}
startsWith(检测的东西);//是否以谁开头
endsWith(检测的东西);//是否以谁结尾
repeat(次数)重复字符串
padStart(整个字符串长度,填充的东西);字符串头填充,padEnd();字符串尾填充
4,函数
(1)函数可以给默认值了
function({x=0;y=0}={}){
console.log(x,y);
}
(2)函数的参数默认是已经定义了,不能再使用let,const声明了
(3)扩展运算符,rest运算符 ...
排序
function show(){
return Array.prototype.slice.call(arguments).sort(function(a,b){
return a-b;
});
}
新的方法:
function show2(...a){
return a.sort();
}
let arr2 = [...arr1];
剩余参数:必须放到最后 (4)箭头函数 => () =>{ }
1,箭头函数中的this问题,指定义函数所在的对象,不再是运行时所在的对象
2,箭头函数里面没有arguments,但是有...
3,箭头函数不能当做构造函数
5,数组
arr.forEach(function(value,index,arr){
console.log(value,index,arr)
})
let b=arr.some((val,index,arr)=>{
return val=='orange'
});
以前: forEach() 循环之后没有返回值
map() 有返回值 ,返回新的数组
正常情况下,需要配合return 返回一个新的数组,若是没有return,相当于forEach,
注意:平时只要用map,一定是要有return,
filter() return 为true,数据保留下来 ,如果回调函数返回true,就留下来
some() 类是查找,数组里面某一个元素符合条件,返回true
every() 数据里面所有的元素都符合条件,才返回true
reduce() 和前面传递的参数不同,求数组的和,阶乘
let c = arr.reduce((pre,cur,index,arr)=>{
return prv+cur;
})
reduceRight()
新增: for...of.
for(let val of arr){
console.log(val);
}
for(let index of arr.keys()){
console.log(index)
}
把类数组转换为数组的方法 Array.from(arr); [].slice.call(arr); 或者 [...arr]
类数组:只有具有length属性的都可以当做类数组处理
Array.of()把一组值转换成数组
arr.find():查找第一个符合的成员
arr.findIndex():找的位置
arr.fill(填充值,开始位置,结束位置):填充
arr.includes()包含
6,对象
JSON:对象简介语法
let json={
a:1,
b:2,
show:function(){
}
}
Object.is(NaN,NaN) 判断两个东西是否相等
Object.assign()用来合并对象的 ,赋值一个对象,合并参数
let newObj = Object.assign({},json,json2)
Object.keys()
Object.values()
Object.entries()
解构:[keys,values,entries] = Object for(let value of values(json)){ } for(let key of keys(json)){ }
对象中也有... 扩展运算符
7,Promise 承诺,许诺
作用:解决异步回调函数
传统方式:大部分用回调函数,事件
let promise = new Promise(function(resolve,reject){}
本人用户:
new Promise().then(res=>{
}).catch(res=>{
});
Promise.sesolve('aa') :将现有的东西,转成一个promise对象,resolve状态,成功状态
new Promise(resolve=>{
resolve('aa')
})
Promise.reject('aaa') :将现有的东西转成一个promise对象,reject状态,失败状态
Promise.all([p1,p2,p3]);把promise打包,扔到一个数组里面,打包完还是一个promise对象
必须确保,p1,p2,p3都是resolve状态
Promise.race([p1,p2,p3]):只要有一个成功了,就返回
3, 跨域CORS详解
CORS是W3C标准。全场跨域资源共享(Cross-origin resourse sharing)
她允许浏览器向跨域资源服务器放出XMLHttpRequest请求,克服了AJAX只能同源使用的限制
1,CORS通信是浏览器自动完成的,不需要用户参与。CORS通信和同源的AJAX通信没有差别,代码完全一样,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以通信
Access-Control-Allow-Origin:* (1) 为什么会有跨域的问题
浏览器安全的基石是:同源策略。什么是同源策略,简言之就是:请求的
协议相同 + 域名相同 + 端口号相同,只有在这三种情况都相同的情况下,才能 被称为同源策略。特别是在前后端分离开发的条件下,几乎跨域是一定会遇到的问题。
(2)CORS请求分成两类:简单请求和非简单请求
只有满足一下两大请求就属于简单请求:
(1)请求方法是以下三种方法之一:Head,get,post
(2) Http的头消息不能超出一下几种字段:
Content-Type:只限于三个值:application/x-www-form-urlencoded,(一般请求默认的方法) multipart/form-data,text/plain
除此之外:凡是不满足的都是非简单请求 (3)CORS请求流程
对于简单请求,浏览器直接发出CORS请求,并且在请求当前头信息中添加一个origin字段。origin其实就是(协议+域名+端口号),服务器根据这个值决定是否同意这次请求。
对于非简单请求,比如请求方法是put或者delete,或者Content-Type字段类型是application/json,,在正是请求之前会,服务器发现你是一个非简单请求,就会自动发出一个预检请求,预检请求的方法是OPTIONS,表示咨询。如果如服务器对预检请求的结果是允许跨域请求,就会第二次发出请求跨域请求。一旦服务器通过了预检请求,以后的每一次CORS请求都是简单请求了。
(5)CORS默认请求不会发送Cookie和HTTP认证信息的。如果要把Cookie发送到服务器,需要知道服务器同意:
Access-Control-Allow-Credentials:true
前端需要设置: widthCredentials = true
(4)CORS与JSONP的比较
CORS与JSON的目的相同,但是比JSONP更强大。
JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSON的优势在与支持老式浏览器,可以向布置CORS的网站请求数据
注意:我们在使用POST方式是,JQuery,Axios等封装的Ajax库,都采用默认的
Content-Type:application/x-www-form-urlencoded,不会触发预请求
举例:处理POST预请求方法
前端发出请求,触发预请求
var data = { name: 'BruceLee', password: '123456' };
$.ajax({
url: "http://localhost:3000",
type: "post",
data: JSON.stringify(data),
contentType: 'application/json;charset=utf-8',
success: function (result) {
console.log(result); },
error: function (msg) { console.log(msg); } })
服务器端要增加对OPTIONS得请求,比如node.js
const http = require('http');
const server = http.createServer((request, response) => {
if (request.url === '/') {
if (request.method === 'GET') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*' });
response.end("{name: 'BruceLee', password: '123456'}"); }
if (request.method === 'POST') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*' });
response.end( JSON.stringify({state: true}) ); }
if (request.method === 'OPTIONS') {
response.writeHead(200, { 'Access-Control-Allow-Origin': '*',
// 设置 optins 方法允许所有服务器访问 'Access-Control-Allow-Methods': '*',
// 允许访问路径 '/' POST等所有方法 'Access-Control-Allow-Headers': 'Content-Type',
// 允许类 Content-Type 头部 }); } }
response.end('false'); });
server.listen(3000, () => { console.log('The server is running at http://localhost:3000'); });
总结:使用CORS跨域资源共享,是需要分成预请求和非预请求处理的。
(1)非预请求:只需要在服务器端简单的数字:
'Access-Control-Allow-Origin': '*'
(2)预请求,在服务器内,至少需要设置三个响应首部字段:
(3)前端使用Content-Type:application/json的时候,必须注意,这是要发生预请求的,后端需要相对于的处理一下OPTIONS方法
4, JavaScript的异步加载
需求:之所以涉及到这个问题,主要因为和其他的公司联合开发一个项目,需要远程加载他们的JS,但又不能影响到我们的业务
方法:采用JS的远程异步加载方式
分析:浏览器在javaScript的加载中,分为三个方式:异步加载,同步加载,延迟加载,主要参考的属性:async,defer,
总结:(1)
同步模式,又称阻塞模式,会阻止浏览器的后续处理。这种模式,从上往下一次执行,如果js报错或执行缓慢,会阻止后续页面的渲染和代码执行
JS之所以要同步执行,是因为JS中可能要修改DOM或其他对页面操作的行为,所以,默认同步执行才是安全的
所以常常建议把之前,这样尽可能减少这种阻塞行为,而先让页面展示出来了
function loadScript(){
var script=document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("async",true);
script.setAttribute("src", "http://110.192.108.165:6260/4k/probe/stat.js?
stbNo=${EPG_USER_SESSION.userId}");
var heads = document.getElementsByTagName("head");
if(heads.length){
heads[0].appendChild(script);
}else{
document.documentElement.appendChild(script);
}
}
异步加载,又称非阻塞,浏览器在下载执行JS同时,还会继续进行后续页面的处理
(3)延迟加载可以通过setTimeout实现
网上方法太多,能实现自己的需求即可。
5, JSON转换
1,因为JSON使用的JavaScript语法,有内置的方法可以处理JSON数据
JSON的文本类型:application/json
JSON数据转换成JSON对象 eval();
JSON.parse(string);
2,JSON的读取方式两种: var x = Obj.name; var x = Obj['name']; 3,在使用for遍历JSON时,只能通过Obj['name']形式来获取属性值
4,JSON.parse(json,function(k,v){})
第二个参数是个函数,用来转换json的值
5,在向服务器发送数据的时候,同时是JSON字符串,需要把对象转换成JSON字符串
JSON.stringify(json对象);
6,JSONP 跨域问题
因为同源策略,ajax请求所产生的跨域问题。
JSONP:不支持Post请求
JSONP的原理:
(1)使用Script标签发送请求,这个标签支持跨域访问
(2)在Script标签里面给服务器端传递一个callback回调函数
(3)服务器端会把和这个calllback回调函数返还给页面,在全局作用域中选择callback函数,
(4)调用这个全局函数,并把数据作为参数传递到函数里面
JSONP只能用get请求