数据结构
Tree
Binary Tree Traversal
排序
冒泡排序refer
JavaScript
JS 函数
reduce
1.求和
function sum(arr) {
return arr.reduce(function(prev, sum){
return prev + sum;
}, 0);
map
不改变原数组,返回新数组
arr.map(function(item)
{return item*item})
loop
1.for … in:对数组/enumerable 对象/string
得到index/key: ele/val
var A = {a:1,b:2,c:3,d:"hello world"};
for(let k in A) {
console.log(k,A[k]);
}
2.forEach
forEach 的缺点:不能中断(break)。
var array = [1,2,3,4,5,6,7];
array.forEach(v=>{
console.log(v);
});
3.for … of : 数组/string/map/set等有Iterator遍历器接口,但是不能是object
函数的arguments 功能
arguments能获得函数对象传入的参数组,类似与一个数组,能够通过length获取参数个数,能通过下标获取该位置的参数,但是它不能使用forEach等方法。
1.实现函数 partialUsingArguments,调用之后满足如下条件:
1、返回一个函数 result
2、调用 result 之后,返回的结果与调用函数 fn 的结果一致
3、fn 的调用参数为 partialUsingArguments 的第一个参数之后的全部参数以及 result 的调用参数
function partialUsingArguments(fn) {
//partial's arguments convert to array
let args = Array.prototype.slice.call(arguments, 1);
let result = function(){
//result's arguments
let selfarg = Array.prototype.slice.call(arguments);
args = args.concat(selfarg);
return fn.apply(null, args)
}
return result
}
call() apply() bind()用于重定义this这个对象,调用函数/对象
1.apply:函数名.apply(对象, 参数数组)…
这三个函数第一个参数都是this指向的对象,第二参数,call是直接放入, 逗号隔开;apply放入一个数组;bind返回是一个函数,参数和call一样。
/*
input:function (greeting, name, punctuation) {return greeting + ', ' + name + (punctuation || '!');}, ['Hello', 'Ellie', '!']
*/
function argsAsArray(fn, arr) {
return fn.call(this, arr[0], arr[1], arr[2])
//or
return fn.apply(this,arr)
return fn.apply(fn,arr)
//or
return fn(arr[0],arr[1],arr[2])
}
2.将函数 fn 的执行上下文改为 obj 对象
在JavaScript中,函数是一种对象,其上下文是可以变化的,对应的,函数内的this也是可以变化的,函数可以作为一个对象的方法,也可以同时作为另一个对象的方法,可以通过Function对象中的call或者apply方法来修改函数的上下文,函数中的this指针将被替换为call或者apply的第一个参数。将函数 fn 的执行上下文改为 obj 对象,只需要将obj作为call或者apply的第一个参数传入即可。
/*
function () {return this.greeting + ', ' + this.name + '!!!';}, {greeting: 'Hello', name: 'Rebecca'}
*/
function speak(fn, obj) {
return fn.bind(obj)()
//or
return fn.apply(obj)
//or
return fn.call(obj)
}
3.二次封装函数
/**
var sayIt = function(greeting, name, punctuation) { return greeting + ', ' + name + (punctuation || '!'); }; partial(sayIt, 'Hello', 'Ellie')('!!!');
**/
function partial(fn, str1, str2) {
var inner = function(punc){
return fn.bind(this, str1, str2)(punc)
}
return inner
}
实现函数 callIt,调用之后满足如下条件
1、返回的结果为调用 fn 之后的结果
2、fn 的调用参数为 callIt 的第一个参数之后的全部参数
/**
因为arguments并非真正的数组,因此要获得callIt的第一个参数之后的所有参数,不能直接使用slice方法截取,需要先将arguments转换为真正的数组才行。
**/
function callIt(fn) {
//1way, traverse all arguments create new array
const args = [];
//parameters starting after fn
for (let i = 1; i < arguments.length;i++){
args.push(arguments[i]);
}
return fn.apply(null, args);
//2way slice
let args = Array.prototype.slice.call(arguments, 1);
return fn.apply(null, args);
}
判断Number
第一种方法:isNaN(n)
第二种方法:typeof(num) != “number”
函数声明 vs 函数表达式
Function name(){} --> 函数可提升,可以在此函数之前执行和解析
var name = function(){} --> 函数后执行和解析,用于同个函数被不同if else block重写
是否在原数组进行操作 refer
- 数组上除掉duplicate
不改变原数组:建立新数组 /slice[has return]
在原数组操作:splice(index, deletecount, addele, addele) [no return] / shift - 原数组添加:
不改变:slice/ [].concat(item) :属于浅拷贝,共用地址,但是值不连带
改变:unshift
计时器
setInterval / clearInterval(timeId)
实现一个打点计时器,要求
1、从 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一个数字,每次数字增幅为 1
2、返回的对象中需要包含一个 cancel 方法,用于停止定时操作
function count(start, end) {
let timeId = setInterval(function () {
if (start <= end) {
console.log(start++)
}
else clearInterval(timeId); //if haven't ifinite loop
}, 100);
return {
cancel: function () {
clearInterval(timeId)
}
}
}