这是我参与【第四届青训营】笔记创作活动的第5天。
1、函数对象
1、call()和apply()
call()和apply()着两个方法都是函数对象的方法,需要通过函数对象来调用,当对函数调用call()和apply()都会调用函数执行,在调用call()和apply()可以将一个对象指定为第一个参数,此时着哥对象会成为函数执行时的this,call() 方法可以将实参在对象之后依次传递,apply() 方法需要将实参封装到一个数组中统一传递。
- call()
function fun(a, b) {
console.log("a = " + a);
console.log("b = " + b);
console.log("fun = " + this);
}
var obj = {
name: "obj",
sayName: function () {
console.log("obj--");
console.log(this.name);
},
};
fun(2, 3);
console.log("===============");
fun.call(obj, 2, 3);
console.log("===============");
obj.sayName();
注意:默认fun()函数调用,this指向的是window对象,你可以使用call()调用函数,在调用的时候传入一个对象,这个对象就是this所指向的对象,也就是说,可以自己指定this的指向,然后从第二个参数开始,实参将会依次传递。
function fun(a, b) {
console.log("a = " + a);
console.log("b = " + b);
console.log("fun = " + this);
}
var obj = {
name: "obj",
sayName: function () {
console.log(this.name);
},
};
fun(2, 3);
console.log("===============");
fun.apply(obj, [2, 3]);
注意:默认fun()函数调用,this指向的是window对象,你可以使用apply()调用函数,在调用的时候传入一个对象,这个对象就是this所指向的对象,也就是说,可以自己指定this的指向,然后从第二个参数开始,需要制定一个实参数组进行参数传递。
2、深拷贝和浅拷贝:
深拷贝:可以看成两个人拥有自己独自的房间,当a改变了自己房间的风格,b的房间还是b原来的风格,不受a的影响;
浅拷贝:a,b两人共用一个卧室
promise.all:当所有的异步都执行完之后才执行回调
promise.race:谁先执行完就以谁为准执行回调
Promise的执行顺序
Promise是宏任务(同步执行),但Promise的回调函数属于异步任务,会在同步任务之后执行(比如说:then,catch,finally)。
Promise的回调函数不是正常的异步任务,而是微任务(microtask)。它们的区别在于,正常任务追加到下一轮事件循环,微任务追加到本轮事件循。这意味着,微任务的执行事件一定早于正常任务。
3、什么是回调函数?
回调函数是指用一个函数作为参数传入另一个函数,这个函数会在某个时机被调用。
比如settimeout()等等
4、闭包
1、什么是闭包?
- 函数和对其周围状态(语法环境)的引用捆绑在一起构成闭包(closure)
2、闭包的三大特性
- 函数嵌套函数
- 函数内部可以引用函数外部的参数和变量
- 参数和变量不会被垃圾回收机制回收
也可以近似看成Java中的类的继承,外部函数看成父亲,内部嵌套的函数看成儿子,儿子可以继承父亲的属性,而且当儿子外出时,自己的东西就会消失,但是从父亲那继承而来的东西不会改变,回来以后还是外出前的状态,但儿子自身的东西就是刚出生的样子了
闭包的好处和坏处
好处:
- 保护函数内的变量安全,实现封装,防止变量流入其他环境发生命名冲突;
- 在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存);
- 匿名函数自执行函数可以减少内存消耗;
坏处:
- 其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法时可以在使用完成量后手动为它赋值为null;
- 其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨域作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响。