JavasSript
ES6 Promise 对象
从语法上说, Promise 是一个对象, 从它可以获取异步操作的消息; Promise 异步操作有三种状态: pending(进行中), fulfilled(已成功)和 rejected(已失败);除了异步操作的结果, 任何其他操作都无法改变这个状态;
Promise 对象只有: 从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变;只要处于 fulfilled 和 rejected , 状态就不会再变了即 resolved(已定型);
const promise = new Promise(function(resolve,reject){
//修改为成功状态, then 回调
resolve('success1');
//修改为失败状态,catch 回调
//reject('reject');
})
promise.then(function(res){
resolve(res);
}).catch(function(err){
reject(err);
});
let p3 = p2.then(function(value){
console.log(value); // success3
return "p2 ok"//这里的返回值, p3的 then 可以接受到
}).catch(function(err){
console.log(err);
return "p2 fail"//这里的返回值, p3的 then 可以接受到
});
p3 .then(res=>{
console.log(res);// "p2 ok" 或者 "p2 fail"
})
.catch(res=>{
//这里永不会调用
}
///调用所有的 Promise
Promise.all([p1, p2]).then(result => {
call(true);
}).catch(errs=>{
call(false);
})
ES6 async 函数
async 函数中可能会有await,async 函数执行时,如果遇到 await 就会先暂停执行 , 等到触发的异步操作完成后, 恢复 async 函数的执行并返回解析值;
await 关键字仅在 async function 中有效; 如果在 async function 函数体外使用 await , 你只会得到一个语法错误; await 操作符用于等待一个 Promise 对象, 它只能在异步函数(async function) 内部使用;
function testAwait(){
return new Promise((resolve) => {
setTimeout(function(){
console.log("testAwait");
resolve();
}, 1000);
});
}
async function helloAsync(){
await testAwait();
console.log("helloAsync");//1 /会等待testAwait()的Promise 执行完毕
}
helloAsync();//2 /不会等待
console.log("testAwait2");
//输出↓
// testAwait2
// testAwait
// helloAsync注意一点, 效果是: 在代码1处, 会等待testAwait()函数执行完毕获取到返回值, 但在代码2处(async外面),还是异步的不会等testAwait()的返回, 继续向下执行!!
ES6 队列实现一则
let Queue = (function(){
const items = new WeakMap()
class Queue {
constructor(){
items.set(this,[])
}
enqueue(element){
let q = items.get(this)
q.push(element)
}
dequeue(){
let q = items.get(this)
let r = q.shift()
return r
}
size(){
let q = items.get(this)
return q.length
}
print(){
let q = items.get(this)
console.log(q.toString())
}
}
return Queue
})()
export default Queue
//使用
import Queue from './Queue'
var a = new Queue();
a.enqueue(123)
(https://www.cnblogs.com/pluslius/p/10331661.html)
call(), apply(), bind()
call(), apply(), bind() 都是可以用来重定义 this
第一个参数都是 this 的指向对象, call 的参数是直接放进去的, 第2 3 N个参数全都用逗号分隔, 直接放到后面 obj.myFun.call(this,‘参数2’, ‘参数3’ ); apply 的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(this,[‘参数2’, ‘参数3’ ]);
bind 除了返回是函数以外, 它的参数和 call 一样;
JavaScript 标准
最大安全整数值
MAX_SAFE_INTEGER 是一个值为 9007199254740991 的常量; 因为Javascript的数字存储使用了IEEE 754中规定的双精度浮点数数据类型, 而这一数据类型能够安全存储 -(2^53 - 1) 到 2^53 - 1 之间的数值(包含边界值);
JS 的最大和最小安全值可以这样获得:
console.log(Number.MAX_SAFE_INTEGER); //9007199254740991 = 2^53-1
console.log(Number.MIN_SAFE_INTEGER); //-9007199254740991标准内置对象
集合处理
数组元素分组
const array = [
{ id: 1, typeId: 'A' },
{ id: 2, typeId: 'B' },
{ id: 3, typeId: 'A' },
{ id: 4, typeId: 'C' },
{ id: 5, typeId: 'B' },
{ id: 6, typeId: 'A' },
{ id: 7, typeId: 'C' },
];
const groupedById = array.reduce((acc, obj) => {
const typeId = obj.typeId;
if (!acc[typeId]) {
acc[typeId] = [];
}
acc[typeId].push(obj);
return acc;
}, {});
console.log(groupedById);
// out
{"A": [{"id": 1,
"typeId": "A"
},
{"id": 3,
"typeId": "A"
},
{"id": 6,
"typeId": "A"
}
],
"B": [
...
],
"C": [
...
]
}数组元素 求最大值
const objects = [
{ id: 1, value: 10 },
{ id: 2, value: 25 },
{ id: 3, value: 15 },
{ id: 4, value: 30 }
];
const maxObject = objects.reduce((max, obj) => max.value > obj.value ? max : obj);
console.log(maxObject); // 输出: { id: 4, value: 30 }一些业务功能代码
将JsonObject 转为 FormData
function getFormData(obj, rootName, ignoreList) {
var formData = new FormData();
function appendFormData(data, root) {
if (!ignore(root)) {
root = root || '';
if (data instanceof File) {
formData.append(root, data);
} else if (Array.isArray(data)) {
for (var i = 0; i < data.length; i++) {
appendFormData(data[i], root + '[' + i + ']');
}
} else if (typeof data === 'object' && data) {
for (var key in data) {
if (data.hasOwnProperty(key)) {
if (root === '') {
appendFormData(data[key], key);
} else {
appendFormData(data[key], root + '.' + key);
}
}
}
} else {
if (data !== null && typeof data !== 'undefined') {
formData.append(root, data);
}
}
}
}
function ignore(root){
return Array.isArray(ignoreList)
&& ignoreList.some(function(x) { return x === root; });
}
appendFormData(obj, rootName);
return formData;
}读取文件为base64
var inputObj = document.createElement("input");
inputObj.type = "file";
inputObj.accept = ".jpg, .png";
inputObj.click();
inputObj.addEventListener("change", event => {
let fileObj = inputObj.files[0];//读取选中文件的文件名
if (fileObj) {
var reader = new FileReader();//这是核心,读取操作就是由它完成.
reader.readAsDataURL(fileObj)//读取 以url
reader.onload = function(e) {//当读取完成后回调这个函数,然后此时文件的内容存储到了result中,直接操作即可
this[pop] = +e.target.result//包括前缀 data:image/jpeg;base64,ffx
}
}
});Blob
下载Blob
function dl(blob, fileName) {
// const blob = new Blob([content]);
const a = document.createElement("a");
const url = window.URL.createObjectURL(blob);
const filename = fileName;
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
}
读取Blob
// 创建FileReader对象
var reader = new FileReader();
// 当读取完成时的回调函数
reader.onloadend = function() {
// 读取完成后,reader.result包含Base64编码的字符串
console.log(reader.result);
};
// 以DataURL格式读取Blob,并触发onloadend事件
reader.readAsDataURL(myBlob);纯前端 创建zip
// 下载的文件名
const filename = new Date().getTime() + '_s.zip';
var zip = new JSZip();
//添加一个文件
zip.file("file.txt", "content");
//访问该文件
zip.file("file.txt").name // "file.txt"
zip.file("file.txt").async("string") // a promise of "content"
zip.file("file.txt").dir // false
// 添加一个文件夹
zip.folder("sub").file("file.txt", "content");
zip.file("sub/file.txt"); // the file
zip.folder("sub").file("file.txt") // the file
// 生成zip文件并下载
zip.generateAsync({
type: 'blob'
}).then(function(content) {
// 创建隐藏的可下载链接
var eleLink = document.createElement('a');
eleLink.download = filename;
eleLink.style.display = 'none';
// 下载内容转变成blob地址 // 触发
eleLink.href = URL.createObjectURL(content);
document.body.appendChild(eleLink);
eleLink.click();
document.body.removeChild(eleLink);
});
原生Ajax
post请求
function getTestToken(callback){
var baseURL = process.env.BASE_API;
var login = baseURL+'/auth/directLogin2'
//创建异步对象
var xhr = new XMLHttpRequest();
xhr.open('post', login );
//设置请求的类型及url
//post请求一定要添加请求头才行不然会报错
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//发送请求
xhr.send('username=testUser&password=123456');
xhr.onreadystatechange = function () {
// 这步为判断服务器是否正确响应
if (xhr.readyState == 4 && xhr.status == 200) {
var json = JSON.parse(xhr.responseText);
callback(json)
}
}
} 原生form 上传
var inputObj = document.createElement("input");
inputObj.type = "file";
inputObj.accept = ".model";
inputObj.click();
inputObj.addEventListener("change", event => {
let fileObj = inputObj.files[0];
if (fileObj) {
var formData = new FormData();
formData.append("modelFile",fileObj);//文件
// formData.append("name","abc");//可追加 form
var xhr = new XMLHttpRequest();
xhr.open('post', './up_std_ref_item_model?id='+data.id );//请求参数
// xhr.setRequestHeader("Content-type","multipart/form-data");//不能设置 表单头
//发送请求
xhr.send(formData);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var json = JSON.parse(xhr.responseText);
}
}
}
});封装
function Ajax(options) {
options = options || {};
options.type = (options.type || "GET").toUpperCase();
options.async = options.async || true;
options.contentType = options.contentType || 'application/json';
var params = getParams(options.data);
var xhr;
if (window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
xhr.onreadystatechange = function () {
if (xhr.readyState > 3){
var status = xhr.status;
if (status >= 200 && status < 300 ){
options.success && options.success(xhr.responseText,xhr.responseXML);
}else{
options.error && options.error(status);
}
}
};
if (options.type == 'GET'){
xhr.open("GET",options.url + '?' + params ,options.async);
xhr.setRequestHeader('Content-Type',options.contentType);
xhr.send(null)
}else if (options.type == 'POST'){
xhr.open('POST',options.url,options.async);
// xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('Content-Type',options.contentType);
xhr.send(params);
}
function getParams(data) {
var arr = [];
for (var param in data){
arr.push(encodeURIComponent(param) + '=' +encodeURIComponent(data[param]));
}
return arr.join('&');
}
}
////
Ajax({url: queryUrl,
type:'post',
data:{ id:'username'},
dataType:'json',
contentType:"application/json",
success:function(data){
console.log(data);
},
error :function(e){
console.error(e);
alert("查询错误! 请稍后再试.")
}
})
}
封装dom (事件委托)
var dialog = function(){
var self = this;
this.elementBind = function(element = this.element){
//绑定顶层的元素 及点击事件
element.addEventListener("click",function(_this,e){
e.bindElement = this;
var dom = e.target;
var even = "action";
var ev;
//向上遍历
for( ;; ){
ev = dom.getAttribute(even);//获得属性
if( ev ){
break;//退出
}else{
dom = dom.parentElement;
if( !dom &&dom == this ){//最顶层 & 自己 退出
break;
}
}
}
if( ev ){//如果该 action 属性存在 执行
_this[ev] && _this[ev].call(_this,e);
}
}.bind(element,this))
}
this.clickOk = function(){
}
}
DBconfigDialog = function (ele){
this.element = ele;
this.db_option;
var self = this;
this.setOption =function(db_option){
this.db_option = db_option;
},
this.getOption = function(){
return db_option;
},
this.elementBind = function(element = this.element){
element.addEventListener("click",function(_this,e){
e.bindElement = this;
var dom = e.target;
var even = "action-click";
var ev;
for( ;; ){
ev = dom.getAttribute(even);
if( ev ){
break;
}else{
dom = dom.parentElement;
if( !dom &&dom == this ){
break;
}
}
}
if( ev ){
_this[ev] && _this[ev].call(_this,e);
}
}.bind(element,this))
},
this.getFormParam = function(){
var paramArr = {};
self.element.find("input[name],select[name],textarea[name]").each(function(index,domEle){
var name = $(domEle).attr("name");
var value = $(domEle).val();
paramArr[name] = value;
});
return paramArr;
},
this.applyFormParam = function(param){
self.element.find("input[name],select[name],textarea[name]").each(function(index,domEle){
var name = $(domEle).attr("name");
if(param[name]){
$(domEle).val(param[name]);
}
});
},
}获取URL中的参数
//TODO 中文是乱码问题
{key: val}//形式
function getQueryParams() {
var url = location.search; //获取url中"?"符后的字串
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
var strs = str.split("&");
for(var i = 0; i < strs.length; i ++) {
theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]); }
}
return theRequest;
}封装 Cookie
var g_cookie_obj = {
//time 过期时间 毫秒
set:function(key,val,time){//设置cookie方法
var date=new Date(); //获取当前时间
date.setTime(date.getTime()+time);
document.cookie=key + "=" + val +";expires="+date.toGMTString(); //设置cookie
},
get:function(key){//获取cookie方法
var getCookie = document.cookie.replace(/[ ]/g,""); //获取cookie, 并且将获得的cookie格式化, 去掉空格字符
var arrCookie = getCookie.split(";") //将获得的cookie以"分号"为标识 将cookie保存到arrCookie的数组中
var tips; //声明变量tips
for(var i=0;i<arrCookie.length;i++){ //使用for循环查找cookie中的tips变量
var arr=arrCookie[i].split("="); //将单条cookie用"等号"为标识, 将单条cookie保存为arr数组
if(key==arr[0]){ //匹配变量名称, 其中arr[0]是指的cookie名称, 如果该条变量为tips则执行判断语句中的赋值操作
tips=arr[1]; //将cookie的值赋给变量tips
break; //终止for循环遍历
}
}
return tips;
},
delete:function(key){ //删除cookie方法
var date = new Date(); //获取当前时间
date.setTime(date.getTime()-1000); //将date设置为过去的时间
document.cookie = key + "=v; expires =" +date.toGMTString();//设置cookie
}
}Map 实现
//map 实现
function Map(){
this.data = {};
this.get = function(key){
return this.data[key];
}
this.put = function(key, val){
data[key]= val;
},
this.remove = function(key){
delete data[key];
},
this.returnArrayForValue = function(){
let arr = new Array();
for (const key in this.data) {
if (this.data.hasOwnProperty(key)) {
arr.push(this.data[key]);
}
}
return arr;
}
}base64
原生实现
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function encode64(input) {
input = escape(input);
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
do {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
keyStr.charAt(enc1) +
keyStr.charAt(enc2) +
keyStr.charAt(enc3) +
keyStr.charAt(enc4);
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return output;
}
function decode64(input) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
var base64test = /[^A-Za-z0-9\+\/\=]/g;
if (base64test.exec(input)) {
alert("Expect errors in decoding.");
}
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return unescape(output);
}
浏览器自带的
window.btoa('china is so nb') // 编码
"Y2hpbmEgaXMgc28gbmI="
window.atob("Y2hpbmEgaXMgc28gbmI=") // 解码
"china is so nb"requirejs 简易使用
<script src="${ctx}/js/require.js"></script>
<script >
//规定加载路径
require.config({
baseUrl:"${ctx}"
,paths: {
"UdsetTable":["js/model_udset_table_data"]
,"UdsetTree":["js/lwz/app/plugin/dataModel/model/udset_dialog"]
}
})
//加载
require(["UdsetTable","UdsetTree"], function(null_is_golbal, UdsetTree){
var UdsetTree = new UdsetTree();
});
//UdsetTree 定义部分
define([],function(){
var dialog = function(){
//容器
this.$topContainer;
this.$ztreeContainer;
//点击回调
this.folderClickCall;
this.dsetClickCall;
//ztree对象
this.zTreeObj;
}
dialog.prototype = {
}
return dialog;
})
</script>美化JSON为Html显示
监视对象属性修改
vue 2 的原理
Object.defineProperty(data_conf,"inner_edit",{
set: function(value){
debugger;
return value;
},
}) 调用浏览器打印
var img = dialogel.getElementsByTagName("img")[0]
var iframe = document.createElement('IFRAME');
var doc = null;
iframe.setAttribute('style', 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;');
document.body.appendChild(iframe);
doc = iframe.contentWindow.document;
doc.write('<div>' + img.outerHTML + '</div>');
doc.close();
iframe.contentWindow.focus();
iframe.contentWindow.print();
if(navigator.userAgent.indexOf("MSIE") > 0) {
document.body.removeChild(iframe);
}文件夹树 -搜索实现
const reg_key_ = new RegExp("根2文件", 'i');
reg_key_.compile(reg_key_);
let searchResult = searchChilren(reg_key_, sourcelist);
console.log("searchResult\n"+JSON.stringify(searchResult));
document.getElementById("txtarea").innerHTML="输出:"+JSON.stringify(searchResult);
}
function searchChilren(reg_key, list){
let new_list = new Array();
for (let index = 0; index < list.length; index++) {
const element = list[index];
let obj = {};
let s_lst = [];
copyNotArray(obj, element);
if(element.children.length > 0 ){//子
s_lst = searchChilren(reg_key, element.children);
}
if(reg_key.test(element.name) || (s_lst.length > 0) ){//比较逻辑
obj['children'] = s_lst;
new_list.push(obj);
}
}
return new_list;
}
function copyNotArray(toObj, obj){
for(key in obj){
let type = obj[key];
if( !Array.isArray(type) )
toObj[key] = obj[key]
}
}
vol 2
var html = "";
for (let index = 0; index < this.user_directory.length; index++) {
var t = "";
const element = this.user_directory[index];
let add = "<div ng-re-id='" + element.id + "' data-name='" + element.name + "'>";
add += "<div class='operate-col3_div></div>";
add += "<ul class='ng-scope'>";
if (element.child.length > 0) {
t = searchBuildTree(element.child, reg, 2);
add += t;
}
add += "</ul></div>";
if (!reg.test(element.name) && t == "") {
add = "";
}
html += add;
}
$(data_container).html(html);
$(data_container).show();
function searchBuildTree(obj, reg, deep) {
let html = "";
for (let index = 0; index < obj.length; index++) {
let add = ""
let t = "";
const element = obj[index];
add += "<li ng-repeat='fo-" + deep + "' data-uniq-id='" + element.id
if (element.child.length > 0) {
t = searchBuildTree(element.child, reg, (deep + 1));
add += t;
}
add += "</ul> </li>";
if (!reg.test(element.name) && t == "") {
add = "";
}
html += add;
}
return html;
}
中英数字 混合排序排序
sortChinese(data_arr, 'name');
function sortChinese (arr, dataLeven) { // 参数: arr 排序的数组; dataLeven 数组内的需要比较的元素属性
function getValue (option) { // 参数: option 数组元素
if (!dataLeven) return option
var data = option
dataLeven.split('.').filter(function (item) {
data = data[item]
})
return data + ''
}
arr.sort(function (item1, item2) {
return getValue(item1).localeCompare(getValue(item2), 'zh-CN');
})
}如何判断Json 点是[] 还是 {}?
var a = [];
a.constructor === Array && a.constructor === Object
TypeScript ---------------------
为旧Vue项目添加ts支持
安装
npm install typescript ts-loader -D
修改 vue.config.js
configureWebpack: config => {
const configNew = {}
if (process.env.NODE_ENV === 'production') {
}else{
config.resolve.extensions.push('.ts'); // 添加ts扩展文件:引用ts文件的时候不用写后缀名
config.module.rules.push({ // 使用ts-loader对ts/tsx文件打包编译
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [/\.vue$/], // ts编译器tsc不能识别.vue文件,所以在 .vue文件后加.ts后缀
},
});
}
return configNew
},
忽略语法检查
@ts-ignore 增加 @ts-ignore 的注释,会忽略下一行的语法检查。
优雅的处理 null
可选链 ?.
?. 遇到 null 或 undefined 就可以立即停止某些表达式的运行,并返回 undefined