// [1] 斐波那契数列
// [2] 杨辉三角
// [3] 防抖节流
// [4] call、apply、bind
// [5] Promise.all和Promise.race
// [6] 函数柯里化
// [7] 深拷贝
// [8] 类型判断函数
// [9] 订阅发布模式
// [10] 数组去重
// [11] 数组降维
// [12] new
// 斐波那契数列 fn(n-2) + fn(n-1)
function fb(n) {
if (n < 2) {
return 1
} else {
return fb(n - 2) + fb(n - 1)
}
}
function testFbFn(n) {
var arr = [];
for (var i = 0; i < n; i++) {
arr.push(fb(i))
}
return arr;
}
console.log(testFbFn(10))
// 杨辉三角 fn(m-1,n-1) + fn(m-1, n)
function yhsj(m, n) {
if (n == 0) {
return 1;
} else if (m == n) {
return 1
} else {
return yhsj(m - 1, n - 1) + yhsj(m - 1, n);
}
}
function testYhsjFn(n) {
for (var i = 0; i < n; i++) {
var arr = [];
for (var j = 0; j <= i; j++) {
arr.push(yhsj(i, j));
}
console.log(arr)
}
}
testYhsjFn(10);
// 防抖节流
// 防抖1:延时执行
function debunce1(fn, wait) {
let timer;
return function () {
let _this = this;
let args = [...arguments]
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(() => {
fn.apply(_this, args)
}, wait)
}
}
// 防抖2:立即执行
function debunce2(fn, wait) {
let timer;
return function () {
let _this = this;
let args = [...arguments]
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
timer = null
}, wait)
let applyNow = !timer;
if (applyNow) {
fn.apply(_this, args)
}
}
}
// 节流1:定时器
function throttle1(fn, wait) {
let timer;
return function () {
let _this = this;
let args = [...arguments];
if (!timer) {
timer = setTimeout(() => {
fn.apply(_this, args)
timer = null;
clearTimeout(timer)
}, wait)
}
}
}
// 节流2:时间间隔
function throttle2(fn, delay) {
let curTime = Date.now();
return function () {
let _this = this;
let args = [...arguments];
let now = Date.now();
if (now - curTime >= delay) {
curTime = Date.now();
fn.apply(_this, args)
}
}
}
// call、apply、bind
Function.prototype.myApply = function (context) {
if (typeof this !== "function") {
return;
}
return function () {
let result;
context = context || window;
context.fn = this;
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn();
}
delete context.fn;
return result
}
}
Function.prototype.myCall = function (context) {
if (typeof this !== "function") {
return;
}
return function () {
let result;
context = context || window;
context.fn = this;
let args = [...arguments].slice(1);
result = context.fn(args)
delete context.fn;
return result
}
}
Function.prototype.myBind = function (context) {
if (typeof this !== "function") {
return;
}
let args = [...arguments].slice(1);
let fn = this;
return function Fn() {
return fn.apply(this instanceof Fn ? this : context, args.cancat(arguments))
}
}
// Promise.all和Promise.race
function PromiseAll(promises) {
return new Promise((resolve, reject) => {
let result = [];
let n = 0;
promises.forEach(item => {
Promise(item).then(res => {
n++;
result.push(res)
if (n === promises.length) {
resolve(result)
}
}).catch(err => {
reject(err)
})
})
})
}
function PromiseRace(promises) {
return new Promise((resolve, reject) => {
promises.forEach((item, index) => {
Promise(item).then(res => {
resolve(res)
})
}).catch(err => {
reject(err)
})
})
}
// 函数柯里化
function curry(fn, args) {
let length = fn.length;
args = args || [];
return function () {
let subArgs = args.concat([...arguments]);
if (subArgs.length >= length) {
return fn.apply(this, subArgs)
} else {
return curry.call(this, fn, subArgs)
}
}
}
// 深拷贝
function deepClone(obj) {
var newObj = {};
Object.keys(obj).forEach(key => {
let value = obj[key];
let type = Object.prototype.toString.call(value).slice(8, -1);
if (type === "Object") {
deepClone(value);
} else if (type === "Array") {
newObj[key] = value.map(e => e);
} else {
newObj[key] = value;
}
})
return newObj;
}
// 类型判断函数
function getValueType(value) {
if (typeof value === null) {
return "null";
}
let type = Object.prototype.toString.call(value).slice(8, -1);
if (type === "Object") {
return 'object'
} else if (type === "Array") {
return 'array'
} else {
return type
}
}
// 订阅发布模式
function Listener() {
this.listeners = {};
this.add = function (type, fn) {
this.listeners[type] = fn;
}
this.on = function (type) {
if (this.listeners[type]) {
this.listeners[type]()
}
}
this.off = function (type) {
if (this.listeners[type]) {
delete this.listeners[type]
}
}
}
let listener = new Listener();
let fn = function () {
console.log("click")
}
listener.add("click", fn)
listener.on("click")
listener.off("click")
listener.on("click")
// 数组去重
var arr = [1, 2, 3, 4, 4, 3, 2, 1];
function resetArr1(arr) {
return Array.from(new Set(arr));
}
console.log(resetArr1(arr));
function resetArr2(arr) {
let newArr = [];
for (var i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i])
}
}
return newArr;
}
console.log(resetArr2(arr));
// 数组降维
// 1.递归
var arr = [1, 2, [3, 4, [5], 6], 7, [8]];
(function myFlat(arr) {
var newArr = [];
function flat(arr) {
arr.forEach(item => {
if (Array.isArray(item)) {
flat(item)
} else {
newArr.push(item)
}
})
}
flat(arr);
console.log(newArr)
return newArr;
})(arr);
// 2.reduce
function myFlat2(arr) {
return arr.reduce((prev, next) => prev.concat(Array.isArray(next) ? myFlat2(next) : [next]), [])
}
console.log(myFlat2(arr));
// new
function New(func) {
var res = {};
if (func.prototype !== null) {
res.__proto__ = func.prototype;
}
var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
return ret;
}
return res;
}
console