本人收藏来自互联网的JavaScript笔记,仅供学习自用(⊙o⊙)哦!
js之重点难点
https://www.cnblogs.com/xiaohuochai/p/5613593.html
false
推荐:【参考:js中绕晕你的true、false - 知乎】
console.log(null ? true : false); //false
console.log('null' ? true : false); //true 这里是字符串,下同
console.log(0 ? true : false); //false
console.log('0' ? true : false); //true
console.log(undefined ? true : false);// false
console.log('undefined' ? true : false); // true
打印信息 ***
console.log("请求成功"+res) // res是前端返回的一个json对象
output:请求成功:[object Object]
console.log("请求成功", res) // res是前端返回的一个json对象
output:
总结:
输出对象里有object不要用 + 号,要用英文逗号隔开
let a = 1,
b = 2,
c = 3;
console.log(a, b, c);
console.log({ a, b, c });
console.table([a, b, c]);
console.log(`%c ${a} in a number`, "color:red");
/**
%s 占位符
%d 或 %i 整数
%f 浮点数
%o%O object对象
%c css样式
*/
// 用来判断一个表达式或变量是否为真,只有表达式为false时,才输出一条相应信息,并且抛出一个异常)
console.assert(false, "判断为false才显示的信息");
console.log("log");
console.info("info");
console.warn("warning");
console.error("error");
console.clear();//清空上面的console显示
const flag = "timer";
console.time(flag); // 前后字符串一定要一致
for (let i = 0; i < 100; i++) {}
console.timeEnd(flag);
结果
timer: 0.010009765625 ms
dir
- 将对象以树状结构展现
- 显示一个对象所有的属性和方法
const obj = {
address: "x",
city: "y",
country: "z",
};
console.log(obj);
console.dir(obj); // 1.括号会自动收缩,需要自己展开查看
console.log(document);
console.dir(document); // 2.会打印出元素的所有参数,方便查看回顾
Chrome 控制台中原生支持类jQuery的选择器,也就是说你可以用$加上熟悉的css选择器来选择DOM节。
$(“body”); //选择body节点 会显示body所有属性和方法
函数传参
参数是啥类型就是传啥类型
<body>
<div>
<p onclick="demo(1,'2',false)">点我</p>
</div>
</body>
<script>
function demo(parm1, parm2, parm3) {
console.log({ parm1 });
console.log(typeof parm1);
console.log({ parm2 });
console.log(typeof parm2);
console.log({ parm3 });
console.log(typeof parm3);
}
</script>
动态元素绑定事件
火狐浏览器 绑定成功会出现event
for (const item of imgArr) {
$('#browse_diagrams_url').append(`
<li class="img-li">< img src=""/></li>
`)
}
// 绑定点击事件
$(".img-li").click(function () {}
也可以使用事件委托
$(selector).on(events,childSelector,function)
事件委托
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>我是新添加的元素</li>
<span>span</span>
</ul>
<script>
let ul = document.getElementsByTagName("ul")[0];// 获取数组中的第一个元素对象
// 给父元素添加点击事件
// ul.addEventListener("click", function (e) {
// e = e || window.event; // 兼容IE
// // 判断触发的对象是不是 li
// if (e.target.nodeName.toLowerCase() === "li") {
// // e.target 是被点击的对象
// console.log(e.target.innerHTML);
// }
// });
ul.onclick = function (e) {
e = e || window.event; // 兼容IE
// 判断触发的对象是不是 li
if (e.target.nodeName.toLowerCase() === "li") {
// e.target 是被点击的对象
console.log(e.target.innerHTML);
}
};
</script>
我们可以用change事件来完成元素值发生改变触发的监听,但是change 只适用于<input>、<textarea> 以及 <select> 元素
,对于 div,span等元素就不能使用了。
【参考:jquery监听div或者span内文本值的改变 - 夜半花开 - 博客园】
html页面
<span id="ceshi" >我是文本</span>
jquery代码
//'我是文本'改变时,触发
$("#ceshi").on('DOMNodeInserted',function(e){
//执行相应的操作
});
编码 解码
https://www.cnblogs.com/lvmylife/p/7595036.html
1.encodeURI 和 decodeURI
把URI字符串采用UTF-8编码格式转化成escape各式的字符串。
encodeURI不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-Z
太多了
所以常用encodeURIComponent和decodeURIComponent
encodeURI()用于整个url编码
console.log(encodeURI('你好')) // %E4%BD%A0%E5%A5%BD
MDN 例子
const uri = 'https://mozilla.org/?x=中文';
const encoded = encodeURI(uri);
console.log(encoded);
// expected output: "https://mozilla.org/?x=%E4%B8%AD%E6%96%87"
try {
console.log(decodeURI(encoded));
// expected output: "https://mozilla.org/?x=中文"
} catch (e) { // catches a malformed URI
console.error(e);
}
还有escape(str) ,unescape(str)但将来会被废弃,官方不建议使用
字符串“http%3A%2F%2F”转换成http://
http://429006.com/article/technology/4342.htm
“%2F”对应的就是 /
“%3A”表示冒号(百分号“%”是转义符, 相当于正则当中的反斜杠”/”)
encodeURIComponent和decodeURIComponent 容易理解, 前者是转义字符串, 后者是解析字符串
所以当遇到上面的字符串时, 那就可以用 decodeURIComponent解析, 而解析结果也会变成我们想要的字符串“http://www.baidu.com/asd?a=123”
而decodeURI和encodeURI, 跟前面的类似, 只不过不会转义特殊字符
http%3A%2F%2Fimg61.hbzhan.com%2F2%2F20130524%2F635049815930316074649.jpg
解码后
http://img61.hbzhan.com/2/20130524/635049815930316074649.jpg
a链接
- 在a中调用js函数最适当的方法推荐使用:
a href="javascript:void(0);" onclick="js_method()"
a href="javascript:;" onclick="js_method()"
a href="#" onclick="js_method();return false;"
- jq的onclick函数如何指向当前节点
//1,获取onclick所在节点的object,需要在调用function时就把this传递过去
<button type="submit" onclick="deletes(this)">删除</button>
//2,在function中可以用一个tmp临时存放传递过来的this
function deletes(obj){
var tmp = obj;
$(tmp).parent().remove();
}
JS中attribute和property的区别
https://www.cnblogs.com/lmjZone/p/8760232.html
property:属性,attribute:特性,可以自定义
一般常用setAttribute()
getAttribute()
attr()
removeAttr()
<div id="div1" class="divClass" title="divTitle" align="left" title1="divTitle1"></div>
var div1=document.getElementById('div1');
var className1 = div1.getAttribute("class"); //
var title = div1.getAttribute("title");
var title1 = div1.getAttribute("title1"); //自定义特性
浅拷贝与深拷贝
javascript中的深拷贝和浅拷贝? - 千锋教育的回答 - 知乎
https://www.zhihu.com/question/23031215/answer/326129003
总结:采用直接赋值的方式(例如b=a)
基本类型为深拷贝,引用类型为浅拷贝(引用)
浅拷贝:assign
深拷贝:concat
手写深拷贝
//封装深拷贝
function deepCopy(newObj, obj) {
for (const key in obj) {
//把对象或者数组的每一项都获取出来
var item = obj[key];
// 判断该项是否为对象
if (item instanceof Object) {
newObj[key] = {};
deepCopy(newObj[key], item);
//判断该项是否为数组
} else if (item instanceof Array) {
newObj[key] = [];
deepCopy(newObj[key], item);
// 这就是普通的类型的对象
} else {
newObj[key] = item;
}
}
return newObj
}
数组
https://blog.csdn.net/weixin_42246997/article/details/107341725
数组的直接赋值属于数组的浅拷贝,JS存储对象都是存内存地址的,所以浅拷贝会导致新数组和旧数组共用同一块内存地址,其中一个数组变化,另一个数组也会相应的变化。
数组内部不含有引用类型,使用slice() 、concat() 和 assign() 方法都属于数组的深拷贝,一个数组变化,另一个数组不受影响。
数组内部含有引用类型,使用slice() 、concat() 和 assign() 方法,非引用类型的值属于深拷贝,引入类型的值属于浅拷贝,一个数组变化,另一个也会相应的变化。
深拷贝
- for循环
- 数组的concat方法
concat() 方法用于连接两个或多个数组。
该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。 - 使用es6的展开操作符:
…arr
推荐 - 利用split join map方法
var arr = [0,1,2,3,4,5,6];
//方法1:for循环
var newArr1 = [];
for (var i = 0; i < arr.length; i++) {
newArr1.push(arr[i]);
}
console.log(newArr1); //ok [0,1,2,3,4,5,6]
//方法2:数组的concat方法
var newArr2 = [].concat(arr);
console.log(newArr2);
//方法3:使用ES6的展开操作符
var newArr3 = [...arr];
console.log(newArr3);
//方法4:字符串的split 数组的join方法:
var newArr4 = arr.join(" ").split(" ").map(function(i){return parseInt(i);});
console.log(newArr4);
//方法5:Object.assign()
let A = [ 1, 2, 3 ]
let B = Object.assign( [], A );
console.log(B);
//方法4: slice()
// arrayObject.slice(start,end),该方法返回一个新的数组,
//包含从 start 到 end (不包括该元素)的 arrayObject 中的元素
let A = [ 1, 2, 3 ]
let B = A.slice(0);
Event Loop
文档:https://zxuqian.cn/docs/videos/js/javascript-eventloop
视频:https://www.bilibili.com/video/BV1kf4y1U7Ln
调用栈(call stack)
消息队列(Message Queue)
微任务队列(Microtask Queue)
- 调用栈 (call stack)
Event Loop 开始时,会从全局代码开始,一行一行执行,遇到函数调用时,会把函数压入调用栈中(被压入的函数叫做帧(frame),当函数返回后,会从调用栈中弹出。
- 消息队列 (Message Queue)
JavaScript 中的异步操作比如**(fetch)、事件回调、setTimeout、setInterval 的回调函数**会入队到消息队列中,它们叫做消息。
- 微任务队列 (Microtask Queue)
使用 Promise、Async/Await 创建的异步操作会入队到微任务队列中,它也会在调用栈被清空的时候执行,比消息队列优先级高
总结:
浏览器可以理解成只有1个宏任务队列和1个微任务队列,
- 先执行全局Script代码,执行完同步代码调用栈清空后,
- 从微任务队列中依次取出所有的任务放入调用栈执行,微任务队列清空后,从宏任务队列中只取位于队首的任务放入调用栈执行(只取一个)
- 然后继续执行微队列中的所有任务,再去宏队列取一个,以此构成事件循环。
es6
模版字符串
https://www.cnblogs.com/xiaowie/p/11601599.html
https://es6.ruanyifeng.com/#docs/string#%E6%A8%A1%E6%9D%BF%E5%AD%97%E7%AC%A6%E4%B8%B2
-
在**${ }中的大括号里可以放入任意的JavaScript表达式(包括函数)**,还可以进行运算,以及引用对象属性。
-
如果使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中。
-
模板字符串甚至还能嵌套。
标签函数(进阶)
https://es6.ruanyifeng.com/#docs/string#%E6%A0%87%E7%AD%BE%E6%A8%A1%E6%9D%BF
三元表达式
除了 false, 0, undefined, NaN, “” ,null,js都认为是true;
1.
$('.item')[ flag ? 'addClass' : 'removeClass']('hover')
因为当flag = true 的时候 ,代码就变成以下代码:
$('.item')['addClass']('hover')
这样写法等同于
$('.item').addClass('hover')
2.
function a(){
//do something
}
function b(){
//do something
}
flag ? a() : b();
3.
this
this关键字 详解
https://www.cnblogs.com/pssp/p/5216085.html
总结
this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁
情况1:如果一个函数中有this,但是这个函数没有被上一级的对象所调用,那么函数里面的this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们这里不探讨严格版的问题,你想了解可以自行上网查找。
(在严格版中的默认的this不再是window,而是undefined)
// 最常见
function a(){
var user = "追梦子";
console.log(this.user); //undefined
console.log(this); //Window
}
a();
情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么这个函数中的this指向的就是上一级的对象。
情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象
// 情况 2,3
let a=1
let o = {
a:2,
b:{
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();
// fn被对象b调用,fn里面的this就指向对象b,但b没有a属性,所以this.a为undefined
构造函数版this
new关键字可以改变this的指向,将这个this指向对象a
首先new关键字会创建一个空的对象,然后会自动调用一个函数apply方法,将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。
function Fn(){
this.user = "追梦子";
}
var a = new Fn();
console.log(a.user); //追梦子
this碰到return时
如果返回值是一个对象,那么this指向的就是那个返回的对象
(null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊)
function fn()
{
this.user = '追梦子';
return {}; //return function(){};
}
var a = new fn;
console.log(a.user); //undefined
如果返回值不是一个对象那么this还是指向函数的实例。
function fn()
{
this.user = '追梦子';
return 1;
}
var a = new fn;
console.log(a.user); //追梦子
改变this指向
https://www.cnblogs.com/pssp/p/5215621.html
call
// 1
var a = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
var b = a.fn;
b.call(a); //把b放到a的环境中执行,b里面的this,就是a的this
// 2.call方法除了第一个参数以外还可以添加多个参数,如下:
var a = {
user:"追梦子",
fn:function(e,ee){
console.log(this.user); //追梦子
console.log(e+ee); //3
}
}
var b = a.fn;
b.call(a,1,2);
apply
// 1
var a = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
var b = a.fn;
b.apply(a);
// 2.同样apply也可以有多个参数,但是不同的是,第二个参数必须是一个数组,
var a = {
user:"追梦子",
fn:function(e,ee){
console.log(this.user); //追梦子
console.log(e+ee); //11
}
}
var b = a.fn;
b.apply(a,[10,1]);
注意:如果call和apply的第一个参数写的是null,那么this指向的是window对象
bind
返回的是一个修改过后的函数。
var a = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
var b = a.fn;
var c = b.bind(a);
c();
// 2.同样bind也可以有多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的。
var a = {
user:"追梦子",
fn:function(e,d,f){
console.log(this.user); //追梦子
console.log(e,d,f); //10 1 2
}
}
var b = a.fn;
var c = b.bind(a,10);
c(1,2);
ES6箭头函数的this指向详解
https://zhuanlan.zhihu.com/p/57204184
详细教程:https://wangdoc.com/javascript/oop/this.html
1.// 箭头函数的上一级是obj对象,而对象是没有作用域的,即没有this,再往上找到window的this
<script type="text/javascript">
var age = 100;
var obj = {
age: 20,
say: () => {
console.log(this.age)
}
}
obj.say(); //100
</script>
函数传this和其他参数
<body>
<a onclick="shanchu('1',this)">点击</a>
</body>
<script type="text/javascript">
function shanchu(a,obj){ // obj 就相当于 this 的别名
alert(a);
alert($(obj).html());
}
</script>
cookie
设置Cookie 有效期 检测cookie:https://www.jb51.net/article/116305.htm
原生js获取、设置cookie值:https://blog.csdn.net/qq_27870421/article/details/89928919
常用:jquery.cookie.js
https://blog.csdn.net/qq_29207823/article/details/81745757
Ajax
get请求数据不用序列化 数据会自动加在url后面的
data 序列化
Json对象和Json字符串的区别:https://www.cnblogs.com/wxh0929/p/11132073.html
JSON的属性名必须有双引号,如果值是字符串,也必须是双引号;
js对象
// 键名 可用双引号、单引号、无引号
// 字符串值 可用双引号、单引号、反引号
//js对象的字面量表示法(常用)
var people1={
name:'hehe',
age:18
};
// json对象 (不常用)
//(类似于JSON格式的JavaScript对象,简称json对象)
var person={
"name":"shily",
"sex":"女",
"age":23
}
//json字符串 (JSON格式的字符串)
// 键名必须用双引号包裹,且最后一个键值对后面不能有逗号
// 键值如果是int和bool(js不区分),可以不用用双引号包裹,其他的字符串必须引用双引号包裹,尤其是记得把时间日期引起来!
var person={
"name":"shily",
"sex":"女",
"age":23,
"职业":["演员","运动员"],
"已婚":true,
"技能":{
"软件":["PS","PR"],
"水平":"中等",
"证书":null
}
}
//发送
js对象转化为**Json字符串** JSON.stringify()
//接收
Json字符串转化为**js对象**(字面量表示法) JSON.parse()
技巧: typeof *** 查看类型
总结:@RequestBody接收的是一个Json对象的字符串,而不是一个Json对象。
在ajax请求往往传的都是Json对象,用 JSON.stringify(data)的方式就能将对象变成字符串。
同时ajax请求的时候也要指定dataType: “json”,contentType:”application/json”
这样就可以轻易的将一个对象或者List传到Java端,使用@RequestBody即可绑定对象或者List.
JSON.parse(res.data);报错:Uncaught (in promise) SyntaxError: “[object Object]” is not valid JSON
【参考:关于"[object,Object]"在javaScript中解析不了或者转化不了的解决方案_Sukyo_h的博客-CSDN博客】
JSON.parse(JSON.stringify(res.data));
localStorage存对象
localStorage.setItem(“token”,res.data.token)
存对象
let user=res.data
localStorage.setItem("user",JSON.stringify(user))
取对象
let user = JSON.parse(localStorage.getItem('user')) //String=>Object
// console.log(user)
// console.log(typeof user) // Object
console.log(user.name)
Ajax返回true或false不生效的问题
(不能再回调函数中返回)
https://blog.csdn.net/qq_18335837/article/details/80748182
解决办法:
- 使用Promise (推荐)
- 使用回调函数
// 问题回显
// ajax请求中的回调函数,例如success
/*
if(data == xxx)
return true; //原因是在回调函数中返回只是退出了回调函数
//解决办法:定义一个外部全局变量 在回调函数外面返回值。
else
return false;
*/
flag=false;
if (data=="用户名可用"){
flag = true;
}else{
flag = false;
}
return flag;
ES6
引号里加变量
`字符串${变量名}字符串`
遍历 **
数组
var a=[1,2,3,4]
for (let index in a) {
console.log(a[index]) // 1 2 3 4
}
for (let item of a) {
console.log(item) // 1 2 3 4
}
a.forEach((item,index)=>{
console.log(item,index)
//在forEach里面return不会终止迭代
})
对象
const user = {
name: "张三",
age: 20,
addr: "江西南昌",
sex: "男",
};
//遍历key和value
const keys = Object.keys(user);
for (const k of keys) {
console.log(k, user[k]);
}
for (const [key, value] of Object.entries(user)) {
console.log(key, value);
}
name 张三
age 20
addr 江西南昌
sex 男
函数
Promise
基本使用
Promise构造函数接受一个函数(执行器函数)作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(reason);
}
});
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
promise.then(
function(value) {
// success
}, function(reason) {
// failure
}
);
then方法可以接受两个回调函数作为参数。
第一个回调函数onResolved()是Promise对象的状态变为resolved时调用
第二个回调函数onRejected()是Promise对象的状态变为rejected时调用
这两个函数都是可选的,不一定要提供。它们都接受Promise对象传出的值作为参数
一个 promise 指定多个成功/失败回调函数,都会调用
const p = new Promise((resolve, reject) => {
//resolve(1)
reject(2)
})
p.then(
value => {},
reason => {console.log('reason',reason)}
)
p.then(
value => {},
reason => {console.log('reason2',reason)}
)
// reason 2
// reason2 2
await async
官方文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await
await 就是 then 的语法糖(await只能拿到resolve的值)
注意点:
- 我们不能在最外层代码中使用 await,因为其不在 async 函数内。
JS中的async/await的用法和理解:https://www.cnblogs.com/xiaofeilin/p/14306374.html
正常情况下,await命令后面是一个Promise对象,如果不是,会被转成一个立即resolve的Promise对象,且会按照异步程序
返回值处理,为undefined,所以不介意这样使用。
例如: let res = await 123; // res = 123
async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。
当函数执行的时候,一旦遇到 await 就会先返回一个 Promise 对象,等到触发的异步操作完成后
,再接着执行函数体内后面的语句。
标准使用方式
// 最外层函数要是 async
async function parent() {
let flag = false;
function child() {
return new Promise((resolve, reject) => {
// 模拟异步请求
setTimeout(() => {
flag = true;
resolve("1s后我才开始执行");
}, 1000);
});
}
let res = await child();
console.log(res);
console.log(flag); // true
}
parent();
/*
1s后我才开始执行
true
*/
# 基础
resolve(函数)
将异步API的执行结果传递出去(then)
reject(函数)
将异步API的失败执行结果传递出去(reject)
then(方法)
获取异步API的执行结果
catch(方法)
获取异步API的失败执行结果
// 同步请求
// 返回一个promise对象
async function fn() {
// await promise对象
// 1.resolve
return Promise.resolve('执行成功');
return '执行成功'; // 默认return为resolve
// 2.reject
return Promise.resolve('执行失败');
throw '执行失败';
throw new Error('执行失败');
}
fn()
.then(
(res) => {console.log(res)}
) //执行成功
.catch(
(err) => {console.log(err)}
); //执行失败
链式调用
https://gitee.com/myaijarvis/vue_study/blob/master/18-Promise/18-promise.md
二者配合使用
<script>
/*
返回json参数示例
{"code":"0","data":{"id":1,"password":"123456","username":"张三","role_id":"001"},"msg":"操作成功!"}
*/
let getRole= async function(name) {
//这里的user相当于该请求返回的参数 即 user= 请求返回的参数中的data数据
const { data: user } = await $.ajax(`user.php?name=${name}`);
/*
const p = new Promise((resolve,reject)=>{
$.ajax(
url:`user.php?name=${name}`,
success:function(res){
resolve(res)
},error:function(err){
reject(err)
}
)
})
p.then(res=>{ // await只能拿到resolve的值
const user=res.data
}).catch(err=>{
...
})
*/
// 当上一个请求为reslove才会执行下面这个,为reject时会停止执行下面的语句,否则一直等待
const { data: role } = await $.ajax(`user.php?name=${user.role_id}`);
//后续操作
return role;
}
getRole('Jack').then(res=>{
console.log(res);
})
</script>
return
https://blog.csdn.net/funkstill/article/details/103521985
function p() {
return new Promise((resolve, reject) => {
// console.log(222);
setTimeout(() => {
console.log("async in p");
reject("err in p");
return; // 下面的不会执行
console.log("content after p reject");
}, 200);
});
}
function p1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("async in p1");
resolve("resolev in p1");
return; // 下面的不会执行
console.log("content after p1 resolve");
}, 250);
});
}
p()
.then((result) => {
console.log(`p result:${result}`);
})
.catch((err) => {
console.log(`p err :${err}`);
});
p1()
.then((result) => {
console.log(`p1 result:${result}`);
})
.catch((err) => {
console.log(`p1 err :${err}`);
});
/*
async in p
p err :err in p
async in p1
p1 result:resolev in p1
*/
错误处理
try {
await post(post_data) // resolve
} catch (err) { // 放置的是出现异常后处理异常的代码块
console.log(err) // reject
}
封装
//封装ajax请求 (同步)
async function getData(url, data = {}){
return new Promise((resolve, reject) => {
$.ajax({
//发送请求类型
type: "GET",
url: url,
data: data,
success: function (res) {
// 修改Promise状态为成功, 修改Promise的结果res
resolve(res)
return //终止运行 下面的不会执行
},
error:function (res) {
// 修改Promise的状态为失败,修改Promise的结果res
reject(res)
}
})
}
}
// 某个函数内
async function demo1(){
...
let res= await getData('参数1','参数2') // resolve(res)
}
callback
这个是js中异步的经典用法,callback称为回调,指在调用异步方法的时候传一个回调方法,等异步任务执行完毕后,自动调用这个回调方法。
function a(callback) {
console.log("A:执行完再其他函数");
callback();
}
function b(callback) {
console.log("B:执行完再其他函数");
callback()
}
function c(callback) {
console.log("C:执行完再其他函数");
callback()
}
function test() {
a(() => {
console.log('A:执行完了,进入回调')
b(() => {
console.log('B:执行完了,进入回调')
c(() => {
console.log('C:执行完了,进入回调')
})
})
})
}
test()
输出顺序为
A:执行完再其他函数
A:执行完了,进入回调
B:执行完再其他函数
B:执行完了,进入回调
C:执行完再其他函数
C:执行完了,进入回调
正则表达式
Regular Expression
export **
exports、module.exports和export、export default到底是咋回事
https://segmentfault.com/a/1190000010426778
总结:
require: node 和 es6 都支持的引入
export
/ import : 只有es6 支持的导出引入(没有s)
module.exports
/ exports: 只有 node 支持的导出
ES中的模块导出导入
testEs6Export.js
//导出变量
export const a = '100';
export const b = true;
//导出方法
export const dogSay = function(){
console.log('wang wang');
}
//导出方法第二种
function catSay(){
console.log('miao miao');
}
export { catSay };
//export default导出
const m = 100;
export default m;
//export defult const m = 100;// 这里不能写这种格式。
index.js
import { dogSay, catSay } from './testEs6Export'; //导出了 export 方法
import m from './testEs6Export'; //导出了 export default
import * as testModule from './testEs6Export'; //as 集合成对象导出
Js模块化导入导出
CommonJS、AMD、CMD、ES6
链接:https://www.cnblogs.com/WindrunnerMax/p/12674943.html
区别:
- CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
- CommonJS是同步加载,AMD是异步加载
export、export default主要有以下区别:
- export能按需导入,export default不行。
- export可以有多个,export default仅有一个。
- export能直接导出变量表达式,export default不行。
- export方式导出,在导入时要加{},export default则不需要
ES6
// 1.js
var a = 1;
var b = function(){
console.log(a);
}
var c = 3;
var d = a + c;
var obj = { a,b,c }
export {a,b};
export {c,d};
export default obj;
// index.html
<!-- 3.html 由于浏览器限制,需要启动一个server服务 -->
<!DOCTYPE html>
<html>
<head>
<title>ES6</title>
</head>
<body>
</body>
<script type="module">
import {a,b} from "./1.js"; // 导入export
import m1 from "./1.js"; // 不加 {} 即导入export default
import {c} from "./1.js"; // 导入export 按需导入
console.log(a); // 1
console.log(b); // ƒ (){ console.log(a); }
console.log(m1); // {a: 1, c: 3, b: ƒ}
console.log(c); // 3
</script>
</html>
常用函数封装
urlSearchParams
不兼容IE,但使用起来非常方便
官方文档:https://developer.mozilla.org/zh-CN/docs/Web/API/URLSearchParams
URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串。
获取url上的参数
/*
获取url上的参数
xxx?id=1
let id = window.getQueryString('id'); // 1
*/
function getQueryString (name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null)
return decodeURIComponent(r[2]);// 返回utf-8编码的字符串 %2%3 => 中文
return null;
}
// 最新写法
const urlSearchParams = new URLSearchParams(window.location.search);
const value = urlSearchParams.get("id"); // ?id=xxx
console.log(value);
修改地址栏URL参数但不跳转
/*
* changeURLStatic 修改地址栏URL参数 但不跳转
* @param name 参数名
* @param value 参数值
* 当前页面地址
* index.php?m=p&a=index&classify_id=225&search=123
* 执行修改
* changeURLStatic('search', '99999');
* 修改后页面地址
* index.php?m=p&a=index&classify_id=225&search=99999
*/
function changeURLStatic(name, value) {
var url = location.href;
var reg = eval('/([\?|&]' + name + '=)[^&]*/gi');
value = value.toString().replace(/(^\s*)|(\s*$)/g, ""); //移除首尾空格
if (!value) {
var url2 = url.replace(reg, ''); //正则替换
} else {
if (url.match(reg)) {
var url2 = url.replace(reg, '$1' + value); //正则替换
} else {
var url2 = url + (url.indexOf('?') > -1 ? '&' : '?') + name + '=' + value; //没有参数添加参数
}
}
history.replaceState(null, null, url2); //替换地址栏
}
删除地址栏URL参数 但不跳转
/*
* urlDelParams 删除地址栏URL参数 但不跳转
* @param name 参数名
* xxx?id=1&str=abc
* urlDelParams('id')
* xxx?str=abc
* 没有删除也不会报错
*/
function urlDelParams(name) {
var loca = window.location
var baseUrl = loca.origin + loca.pathname + '?'
var query = loca.search.substr(1)
if (query.indexOf(name) > -1) {
var obj = {}
var arr = query.split('&')
for (var i = 0; i < arr.length; i++) {
arr[i] = arr[i].split('=')
obj[arr[i][0]] = arr[i][1]
}
delete obj[name]
var url =
baseUrl +
JSON.stringify(obj)
.replace(/[\"\{\}]/g, '')
.replace(/\:/g, '=')
.replace(/\,/g, '&')
// return url
history.replaceState(null, null, url); //替换地址栏
}
}
Storage
使用localStorage/sessionStorage时
localStorage/sessionStorage默认只能存储字符串,而实际开发中,我们往往需要存储对象类型,那么此时我们需要在存储时利用json.stringify()将对象转为字符串,在取本地缓存时,使用json.parse()转回对象即可。
function setStorage(name, content) {
if (!name) return;
if (typeof content !== 'string') {
content = JSON.stringify(content);
}
window.localStorage.setItem(name, content);
}
function getStorage(name) {
if (!name) return;
return window.localStorage.getItem(name);
}
function removeStorage(name) {
if (!name) return;
window.localStorage.removeItem(name);
}
复制链接到剪切板
https://blog.csdn.net/piaoliangj/article/details/109480254
步骤:
- 创建input / textarea 标签 ,其value 为想要复制的内容,比如这篇文章的本页面url
- 添加input / textarea 标签到页面的任何一个地方(如果不想看见就可以display:none;)
- 使用element.select()方法选择input/textarea 标签
- 使用Document.execCommand(“copy”);方法复制value的内容到剪切板
- 把添加的input / textarea 标签移除
document.execCommand()
https://developer.mozilla.org/zh-CN/docs/Web/API/Document/execCommand
//1.原生js
let element= document.createElement("input");
let body = document.body;
body.appendChild(input);
element.value = window.location.href; // 本页面的地址
element.style.display= none
element.select(); // 选取文本域内容;
// 执行浏览器复制命令
// 复制命令会将当前选中的内容复制到剪切板中(这里就是创建的input标签)
/*
input标签要在正常的编辑状态下原生复制方法才会生效
input框不能有disabled属性
根据第一条扩展,input的width || height 不能为0;
input框不能有hidden属性
*/
document.execCommand("copy") // 复制
element.remove()
// body.removeChild(element);
// jq
let element = $(`<input value='${window.location.href}'>`);
$("body").append(element);
element.select();
document.execCommand("copy") // 复制
element.remove();
替换键名
如果需要替换多个键名或者键值的话请用map
/**
* 替换数组对象(一层)的键 res=[{},{}]
*/
// 替换数组对象的键名 newKey oldKey
// this.authorList = this.handleReplaceArrObjKey(res, 'value', 'nickName')
handleReplaceArrObjKey(arr, key, replaceKey) {
let newArr = [];
arr.forEach((item, index) => {
for (var i = 0; i < key.length; i++) {
item[key] = item[replaceKey];
}
newArr.push(item);
});
return newArr;
},
浏览器模块化
静态html ***
import ***
https://blog.csdn.net/cc18868876837/article/details/113915176
// js/common.js
let obj = {
click: function () {
console.log("click me");
},
name: "jane",
};
export { obj };
// index.html
<script type="module" src="js/common.js"></script>
// js/index.js
import { obj } from "/js/common.js";
obj.click();
console.log(obj.name);
必须要本地开启一个服务器进行访问,比如VSCode的Live Server
插件,webstorm
自带服务器端口访问,否则浏览器会报错
fetch
原生js异步请求API
MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch
https://www.ruanyifeng.com/blog/2020/12/fetch-tutorial.html
fetch() 方法必须接受一个参数——资源的路径。无论请求成功与否,它都返回一个 Promise 对象,resolve 对应请求的 Response。基本语法如下:
fetch(url)
.then(...)
.catch(...)
async function getData() {
// 获取 response流 异步
const response = await fetch("https://jsonplaceholder.typicode.com/posts");
// 把响应流变成 JSON 异步
const posts = await response.json();
// 打印结果
console.log(posts);
}
// 调用函数
getData();
MDN
fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
// Example POST method implementation:
postData('http://example.com/answer', {answer: 42})
.then(data => console.log(data)) // JSON from `response.json()` call
.catch(error => console.error(error))
function postData(url, data) {
// Default options are marked with *
return fetch(url, {
body: JSON.stringify(data), // must match 'Content-Type' header
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, same-origin, *omit
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json'
},
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // *client, no-referrer
})
.then(response => response.json()) // parses response to JSON
.catch(error => console.error('Error:', error))
}