call与apply bind
同:都是都是function对象原型上的方法,用来改变this指向的
不同:传参形式不同call(obj,10,20,30) allpy(obj,[10,20,30])函数直接执行
还有一个方法bind,bind传参与call相同,但是返回的是一个函数
call的性能更好,尤其是传给函数参数大于三个时
计算数组值出现次数
// 计算数组中每个值出现的次数,找到出现次数最多的值
function getValueCount(arr) {
let countObj = {};
arr.forEach(value => {
if (countObj[value]) {
countObj[value]++;
} else {
countObj[value] = 1
}
});
return countObj
}
console.log(getValueCount(['a', 'b', 'c', 'a', 'b', 'a']));
链式调用
// 实现链式调用:其核心是返回自身
function Class1() {}
Class1.prototype.method = function(param) {
console.log(param);
return this
}
let class1 = new Class1();
class1.method("hello").method("world!")
函数柯里化
//函数柯里化 使用了闭包的概念,将得到的参数统一运算
function add(...args) {
return args.reduce((pre, thevalue) => pre + thevalue)
}
function currying(fn) {
let args = [];
return function temp(...newArgs) {
if (newArgs.length) {
args = [
...args,
...newArgs
]
return temp
} else {
let val = fn.apply(this, args)
args = []; //保证再次调用时清空
return val
}
}
}
console.log(currying(add)(1, 2, 3, 4)(1, 2, 3, 4)());
实现a.b.c.d.e的简单存取
// 考虑数组的情况
function get(source, path, value = undefined) {
if (typeof source != "object") return value
console.log(source);
const paths = path.replace(/\[(\d+)\]/g, ".$1").split(".");
console.log(paths);
paths.forEach(key => {
source = source[key];
console.log(key, source);
if (source == undefined) {
return value
}
});
return source
}
let a = {
a1: {
b1: {
c1: '1'
}
},
c: 'c'
}
console.log(get(a, 'a1.b1.c1'));
数组转树
// 数组转树
let input = [{
id: 1,
val: "学校",
parentId: null
}, {
id: 2,
val: "班级1",
parentId: 1
}, {
id: 3,
val: "班级2",
parentId: 1
}, {
id: 4,
val: "学生1",
parentId: 2
}, {
id: 5,
val: "学生2",
parentId: 3
}, {
id: 6,
val: "学生3",
parentId: 3
}]
let output = {
id: 1,
val: "学校",
children: [{
id: 2,
val: "班级1",
children: [{
id: 4,
val: "学生1",
children: []
}]
}, {
id: 3,
val: "班级2",
children: [{
id: 5,
val: "学生2",
children: []
}, {
id: 6,
val: "学生3",
children: []
}]
}]
}
function obj(item) {
this.id = item.id;
this.val = item.val;
this.children = []
}
function arrToTree(arr) {
let tree = new obj(arr[0]);
arr.shift();
while (arr.length > 0) {
toTree(arr[0], [tree], arr);
}
return tree;
}
function toTree(item, arr, mainarr) {
for (let i = 0; i < arr.length; i++) {
if (item.parentId === arr[i].id) {
arr[i].children.push(new obj(item));
mainarr.shift();
break
} else {
arr[i].children.length > 0 ? toTree(item, arr[i].children, mainarr) : null
}
}
}
console.log(arrToTree(input));
消消乐
给定一个一维的正整数数组,逐次选择其中一个数做消除,消除所获得的分数为当前数字和左右相邻数字的乘积(当左边或者右边没有数字可以认为是1)。
e.g. 输入数组:[3, 1, 5, 8]
step1:消除1 ,获得分数 15 = 3x1x5,数组变为 [3, 5, 8]
step2:消除5,获得分数 120 = 3x5x8,数组变为 [3, 8]
step3:消除3,获得分数 24 = 3x8,数组变为[8]
step4:消除8,获得分数 8 = 8,数组变为[]
最终获得分数:15+120+24+8 = 167
求消除能够获取的最大分数