JavaScript学习笔记

js截取数组slice(),splice()两种方法
理清JS中的深拷贝与浅拷贝

(1).浅拷贝是对对象地址的复制,并没有开辟新的栈,也就是复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会改变

(2).深拷贝则是开辟新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。

实现深拷贝:

  • Object.assign() 只可以处理第一层的深拷贝。
  • var objectIsNew = JSON.parse(JSON.stringify(objectIsOld));
  • jQuery.extend(true, {}, objectIsOld);
reduces函数里面的return为什么要加上…state

(1)…state防止覆盖其他reducers函数返回的state
(2)…state属于浅拷贝

es6之扩展运算符 三个点(…)

我们知道javascript中有两种数据类型,分别是基础数据类型和引用数据类型。
基础数据类型 是按值访问的,常见的基础数据类型有NumberStringBooleanNullUndefined,这类变量的拷贝的时候会完整的复制一份;
引用数据类型比如Array,在拷贝的时候拷贝的是对象的引用,当原对象发生变化的时候,拷贝对象也跟着变化

为Object对象动态添加属性和值
var obj = {}; //或者 var obj=new Object();
var key = "name";
var value = "张三丰"
obj[key] = value;
console.info(obj);
从一道题浅说 JavaScript 的事件循环
//请写出输出内容
async function async1() {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}
async function async2() {
	console.log('async2');
}

console.log('script start');

setTimeout(function() {
    console.log('setTimeout');
}, 0)

async1();

new Promise(function(resolve) {
    console.log('promise1');
    resolve();
}).then(function() {
    console.log('promise2');
});
console.log('script end');


/*
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
*/

在这里插入图片描述

宏任务

(macro)task(又称之为宏任务),可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。

浏览器为了能够使得JS内部(macro)task与DOM任务能够有序的执行,会在一个(macro)task执行结束后,在下一个(macro)task 执行开始前,对页面进行重新渲染,流程如下:

(macro)task->渲染->(macro)task->…
(macro)task主要包含:script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChannel、setImmediate(Node.js 环境)

微任务

microtask(又称为微任务),可以理解是在当前 task 执行结束后立即执行的任务。也就是说,在当前task任务后,下一个task之前,在渲染之前。

所以它的响应速度相比setTimeout(setTimeout是task)会更快,因为无需等渲染。也就是说,在某一个macrotask执行完后,就会将在它执行期间产生的所有microtask都执行完毕(在渲染前)。

microtask主要包含:Promise.then、MutaionObserver、process.nextTick(Node.js 环境)

运行机制

1.执行一个宏任务(栈中没有就从事件队列中获取)
2.执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
3.宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
4.当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
5.渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
在这里插入图片描述

async function async1() {
	console.log('async1 start');
	await async2();
	console.log('async1 end');
}

等价于

async function async1() {
	console.log('async1 start');
	Promise.resolve(async2()).then(() => {
                console.log('async1 end');
        })
}
Promise.resolve(()=>{console.log('立即执行');}).then(() => {
                console.log('加入微任务队列之后运行');
        })
理解 JavaScript 的 async/await
async function testAsync() {
    return "hello async";
}

const result = testAsync();
console.log(result);
// log 输出:Promise { 'hello async' }

async 函数返回的是一个 Promise 对象。从文档中也可以得到这个信息。async 函数(包含函数语句、函数表达式、Lambda表达式)会返回一个 Promise 对象,如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。

async 函数返回的是一个 Promise 对象,所以在最外层不能用 await 获取其返回值的情况下,我们当然应该用原来的方式:then() 链来处理这个 Promise 对象,就像这样

testAsync().then(v => {
    console.log(v);    // 输出 hello async
});

现在回过头来想下,如果 async 函数没有返回值,又该如何?很容易想到,它会返回 Promise.resolve(undefined)。

在没有 await 的情况下执行 async 函数,它会立即执行,返回一个 Promise 对象,并且,绝不会阻塞后面的语句,等到async 函数执行完成之后将结果传递到then()链。

await

  • 如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。
  • 如果它等到的是一个 Promise 对象,await 会阻塞后面的代码,等着 Promise 对象 resolve,然后得到
    resolve 的值,作为 await 表达式的运算结果。
JS中的async/await的用法和理解
this

箭头函数的this总是指向定义时所在的对象,而不是调用时。

js如何将小数保留一位且不实现四舍五入!
1 function avg(a,b){
2     var res= parseInt((a/b)*10)/10;//保留两位、三位小数 同理
3     return res;
4 }
5 console.log(avg(2,3));//输出结果为0.6
js 中编码(encode)和解码(decode)的三种方法
module.exports中引用内部函数
module.exports = {
  getCursor: (rec) => Buffer.from(rec.toString()).toString("base64"),
  getOffsetCustom: (data, afterCursor) => {
    const offsetBasedOnFind = data.findIndex(rec =>
      module.exports.getCursor(rec.id) === afterCursor
//    ^^^^^^^^^^^^^^^
    );
    return offsetBasedOnFind === -1 ? 0 : offsetBasedOnFind + 1;
  },
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值