【前端】JavaScript(包括ES6)学习笔记(重要)

本人收藏来自互联网的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 太多了

所以常用encodeURIComponentdecodeURIComponent

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”表示冒号(百分号“%”是转义符, 相当于正则当中的反斜杠”/”)

encodeURIComponentdecodeURIComponent 容易理解, 前者是转义字符串, 后者是解析字符串

所以当遇到上面的字符串时, 那就可以用 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))
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值