面向切面编程
Function.prototype.before = function (beforeFn) {
let _self = this; //保存原函数引用
return () => { //返回包含了原函数和新函数的"代理函数"
beforeFn.apply(this, arguments); //执行新函数,修正this
return _self.apply(this, arguments) //执行原函数
}
}
Function.prototype.after = function (afterFn) {
let _self = this;
return () => {
let set = _self.apply(this, arguments);
afterFn.apply(this, arguments);
return set
}
}
//测试
let func = function () {
console.log('func')
};
func = func.before(() => {
console.log("============before============")
}).after(() => {
console.log("============after==============")
})
func();
//结果
============before============
func
============after==============
斐波那契数列
斐波那契数列从第三项开始,每一项都等于前两项之和,指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55......
//方案1 递归
function fib(n) {
if (n === 1 || n === 2) return n - 1;
return fib(n - 1) + fib( n - 2)
}
时间复杂度为o(2 ^ n)
//方案2 非递归
function fib1(n) {
let a = 0;
let b = 1;
let c = a + b;
for (let i = 3; i < n; i++) {
a = b;
b = c;
c = a + b
}
return c;
}
时间复杂度为o(n)
console.log(fib(10))
在一个数组中,找出里面其中两项相加后和为num同,如果存在返回这两个索引位置,否则为false
function fn(num = 0, ary = []) {
for(let i = 0; i < ary.length; i++) {
let diff = num - ary[i];
let diffIndex = ary.indexOf(diff);
if (diffIndex !== -1) {
return [i, diffIndex]
}
}
return false;
}
let num = 5;
let arr = [-1, 4, 6, 2];
console.log(fn(num, arr)) // [0, 2]
将两个有序数组合并为一个排好序的大数组
function meraeAry(left = [], right = []) {
let result = [];
while(left.length && right.length) {
result.push(left[0] <= right[0] ? left.shift() : right.shift())
}
return result.concat(left, right)
}
console.log(meraeAry([1, 2, 3], [1, 3, 4, 9]))
//[ 1, 1, 2, 3, 3, 4, 9 ]
字符串repeat的实现
//原生repeat
'ni'.repeat(3) //ninini
//方法1
String.prototype.repeat1 = function (n) {
return Array(n + 1).join(this)
}
console.log('ni'.repeat1(2))//ninini
//方法2
String.prototype.repeat2 = function (n) {
return Array(n).fill(this).join('')
}
console.log('ni'.repeat2(2))//ninini
实现函数CodingMan,此函数可以按照如下调用
CodingMan('Peter') 输出: Hi! This is Peter!
CodingMan('Peter').sleep(3).eat('dinner') 输出: Hi! This is Peter! //等待3秒 Wake up after 3 Eat dinner
CodingMan('Peter').eat('dinner').eat('supper'); 输出: Hi! This is Peter! Eat dinner Eat supper
CodingMan('Peter').sleepFirst(5).eat('supper'); 输出: //等待5秒 Wake up after 5 Hi! This is Peter! Eat supper
function CodingMan(name) {
function Man (name) {
setTimeout(() => {
console.log(`Hi! This is ${name}`)
}, 0)
}
Man.prototype.sleep = function (time) {
let curTime = new Date();
let delay = time * 1000;
setTimeout(() => {
while(new Date() - curTime < delay) {}
console.log(`Work up after ${time}`)
}, 0);
return this;
}
Man.prototype.sleepFirst = function (time) {
let curTime = new Date();
let delay = time * 1000;
while(new Date() - curTime < delay) {}
console.log(`Work up after ${time}`);
return this;
}
Man.prototype.eat = function (food) {
setTimeout(() => {
console.log(`Eat ${food}`)
}, 0);
return this;
}
return new Man(name)
}
CodingMan('Peter');
CodingMan('Peter').sleep(3).eat('dinner');
CodingMan('Peter').eat('dinner').eat('supper');
CodingMan('Peter').sleepFirst(5).eat('supper')=
[1, 2, 3].map(parseInt)
[1, 2, 3].map(parseInt)
参数
string 要解析的值。如果string参数不是字符串,则将其转换为字符串(使用ToString抽象操作)。字符串参数中的前导空格将被忽略。 radix 2到36之间的整数(进制),表示上述字符串的基数,以这个进制去转化。如果是0是以10进制
返回值
从给定字符串解析的整数。如果第一个字符无法转换为数字,NaN则返回
[1, 2, 3].map(parseInt) //1 NaN NaN
['10','10','10','10','10'].map(parseInt); //10, NaN 2 3 4
['10','10','111','210','310'].map(parseInt); //[10, NaN, 7, 21, 52]
要求写出这样一个函数,给的数字r,经过此函数处理之后能够输出所有连续数字和为r的情况
例如,给定数字15,则最终输出三个组合:[7,8],[4,5,6],[1,2,3,4,5]
function findArray(r) {
//结果数组,存放连续数字的起始数字和结尾数字
var resArr = [];
//q带表连续数字的个数
for (var q = 2; 2 * r / q - q >= 1; q++) {
//n为起始位置数字
//n+q-1 结束位置数字
var n = (2 * r / q - q + 1) / 2;
//如果n为整数则存放此次结果
n === ~~n && resArr.push([n, n + q - 1]);
}
return resArr;
}