-
flat
- 数组扁平化 就是给里面的数组套数组一层层展开,函数参数传入数组和需要展开的层数
function arrayFlat(arr, depth = 1) { let res = []; for (let i = 0; i < arr.length; i++) { if (Array.isArray(arr[i]) && depth > 0) { res = res.concat(arrayFlat(arr[i], depth - 1)); //concat 不会修改原数组,它会返回一个新数组 } else { res.push(arr[i]); } } return res; }- 对象扁平化 多层对象变成一层:比如
const source = { a: { b: { c: 1, d: 2 }, e: 3 }, f: { g: 2 } } //变成这样。 { "a.b.c": 1, "a.b.d": 2, "a.e": 3, "f.g": 2 }核心思想就一句话:往对象里面递归走,同时把走过的 key 拼起来
function objectFlat(obj) { // 最终结果是对象,不是数组 const res = {}; function flat(item, prefix = "") { // 遍历当前对象的每一个 key 和 value Object.entries(item).forEach(([key, value]) => { // 如果 prefix 有值,就拼成 "a.b" // 如果 prefix 为空,说明是第一层,直接使用 key const newKey = prefix ? `${prefix}.${key}` : key; // value 还是对象,就继续递归 if (value && typeof value === "object") { flat(value, newKey); } else { // 已经是普通值,就保存到结果对象中 res[newKey] = value; } }); } // 从 obj 最外层开始递归 flat(obj); return res; } -
ajax 浏览器不刷新整个页面,也可以偷偷向服务器发请求、拿数据。 Asynchronous JavaScript And XML
// 创建一个网络请求对象
const xhr = new XMLHttpRequest();
// 配置请求
// "GET":向服务器获取数据
// url:请求地址
// true:异步请求,不阻塞 JS进行
xhr.open("GET", url, true);
// 当请求状态发生变化时执行
xhr.onreadystatechange = function () {
// readyState === 4 表示请求已经彻底完成
// 如果还没完成,就直接退出
if (this.readyState !== 4) return;
// status === 200 表示请求成功
if (this.status === 200) {
// response 是服务器返回的数据
console.log(this.response);
//这里也可以用dom修改页面等等
} else {
// 请求失败,抛出错误
// statusText 是错误状态文字
throw new Error(xhr.statusText);
}
};
// 真正发送请求
xhr.send();
- call
Function.prototype.myCall = function (thisArg, ...args) {
const fn = this; //这里的this即为下方调用的say
//因为对象.函数()”的调用方式,会让函数里的 this 指向这个对象
//(此处的say虽然是函数,但也是对象的一种)
thisArg =
thisArg !== undefined && thisArg !== null ? Object(thisArg) : window;
// 创建一个唯一的属性名
// 避免和 thisArg 里面原有的属性重名
const tag = Symbol("call");
thisArg[tag] = fn;
//通过 thisArg 调用这个函数,相当于对象.函数(),this会指向thisArg
const res = thisArg[tag](...args);
delete thisArg[tag];
return res;
};
//调用
const obj = {
name: "Navi",
};
function say(age) {
console.log(this.name, age);
}
say.myCall(obj, 18);
//myCall 里的 this → say
//say 里的 this → thisArg
- 柯里化
把一个“要一次传很多参数的函数”,变成“可以分多次传参数”的函数
比如可以:
function add(a, b, c) {
return a + b + c;
}
add(1, 2, 3); // 6
curry(add)(1)(2)(3); // 6,柯里化调用
curry(add)(1, 2)(3); // 这样也行
两种写法
const curry = (fn, ...args) => {
//...args有两种用法,上方是收集参数为数组args
if (args.length >= fn.length) {
//下面这种是从args数组展开
return fn(...args);
}
//参数不够则继续收参数
return (...rest) => {
return curry(fn, ...args, ...rest);
};
};
//另一种写法
const curry2 = (fn) => {
return function curried(...args) {
if (fn.length <= args.length) {
return fn(...args);
}
return (...rest) => {
return curried(...args, ...rest);
};
};
};
- 千分位逗号隔开
const thousandSeperater = (n) => { n = n.toString(); let res = []; let count = 1; for (let i = n.length - 1; i >= 0; i--) { if (count < 4) { res.push(n[i]); count++; } else { res.push(",", n[i]); count = 1; } } return res.reverse().join(""); };