闭包和IIFE

  • 高阶函数

参数或者返回值为函数的函数

  • 头等函数

当一门编程语言的函数可以被当作变量一样用时,则称这门语言拥有头等函数。在这门语言中,函数可以被当作参数传递给其他函数,可以作为另一个函数的返回值,还可以被赋值给一个变量。也可以将函数理解为编程语言中的一等公民。

https://developer.mozilla.org/zh-CN/docs/Glossary/First-class_Function

  • 回调函数

作为参数传递给另一个函数的函数被称为回调函数

特点

不会立即执行 也要通过()运算符调用才会执行,是个闭包,能够访问到外层定义的变量

回调函数调用时this的执行上下文并不是回调函数定义时的那个上下文,而是调用它的函数所在的上下文。

// 关于回调函数this的指向问题
var obj = {
    sum: 0,
    add: function(num1, num2){
        this.sum = num1 + num2;
    }
};

function add(num1, num2, callback){
    callback(num1, num2);
};

add(1,2, obj.add);
console.log(obj.sum);			//=>0
console.log(window.sum);		//=>3 回调函数add调用是在全局环境下,因此this指向的是window,所以sum的值是赋值给windows的。
// 为上述add函数添加 指向的this对象
function add(num1, num2, callbackObj, callback){
    callback.apply(callbackObj, [ num1, num2 ]);
};

add(1,2, obj, obj.add);
console.log(obj.sum);			//=>3
console.log(window.sum);		//=>undefined

数组原型上的一些方法

Array.prototype.map() 需要进行返回

const arr = [1,2,3,4]
arr.map( (item)=> {
    return item * 2;
})

Array.prototype.filter()

创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter((word) => word.length > 6);

console.log(result);

Array.prototype.forEach()

对数组的每个元素执行一次给定的函数

const array1 = ['a', 'b', 'c'];
array1.forEach((element) => console.log(element));

ps:

这里插入一下js判断数据类型的8中方式

typeof 基本数据类型和引用数据类型 能识别number string boolean undefined function NaN(是number类型),array object null都会识别为object

instanceof 只能判断引用数据 arr instanceof Array

手写foreach函数

// foreach函数手写
// https://juejin.cn/post/7036318714723041310

// 第一步: foreach函数有两个参数 第一个是函数(参数为数组每一项,数组下标,数组本身) 第二个this的指向
// 第二步: 判断是否有this指向的改变
// 第三步: 判断第一个参数是否为函数 不是报错 
// 第四步: 遍历循环数组 使用call改变this的指向 依次传入数组每一项,数组下标,数组本身    
Array.prototype.myforEach = function(fn) {
  let context = arguments[1] || window

  if(typeof fn === 'function') {
    for(let i = 0;i<this.length;i++) &#123;
      fn.call(context, this[i], i, this)
    &#125;
  &#125; else &#123;
    throw new Error('parameter1 is not a function')
  &#125;
&#125;

使用闭包实现数组之间的合并

// 使用闭包实现非递减数组的合并功能
function merge(arr1) &#123;
  // your code here
  return function (arr2) &#123;
    let result = [...arr1,...arr2]
    return result.sort(function(a,b) &#123;return a-b&#125;)
  &#125;
&#125;

//测试用例
console.log(merge([1, 5, 8])([2, 4])); // =>[1,2,4,5,8]
console.log(merge([6, 9])([1, 2])); // =>[1,2,6,9]

CSS自定义属性(变量)

CSS自定义属性(CSS变量)的值可以在整个文档中重复使用,由var来获取值

element{
    --main-bg-color: brown
}
// 获取时
color: var(--mian-bg-color);

详情见MDN

笔试题目总结

提高当前盒子的层级

z-index:默认值为0,越大层级性越高,负数表示降低层级性

有定位比没有定位的盒子的层级性更高

客户端与服务器端渲染区别

客户端渲染和服务端渲染的区别 - 掘金 (juejin.cn)

try… catch捕获错误

setTimeout之类的是宏任务,promise是微任务,微任务在宏任务之前执行,因此先执行promise,之后执行setTimeout。

try catch捕获不到异步任务里面的错误,因为事件循环导致异步代码执行时执行栈与try catch所在的执行栈不一样了,它们的上下文context已经完全不同了。

同理,对于promise的then中的回调函数try catch也是捕获不到的,因此promise机制自己提供了一个catch方法捕获异步回调中的错误。

但是对于async await可以使用try catch进行错误捕获,这里如果需要理解可以参考 深刻理解async/await

JS中的几种模块化规范

CommonJS AMD CMD ESM(ES6 Module)

JS数据类型

Map 简单映射 保存一组键值对,键可以是原始值,也可以是引用值

// 使用 
let map = new Map()
map.set('name','zyyy')
map.has('name') // true
map.get('name') // zyyy
map.delete('name')

Set类型 集合是一组不重复的元素,集合中只有键,没有与键关联的值

// 使用
let set = new Set();
set.add('name');
set.has('name'); // true
set.delete('name');