回顾1516年的函数封装
1 //1> hasOwnProperty 2 function _has(prop,obj){ 3 return Object.prototype.hasOwnProperty.call(obj,prop); 4 }; 5 6 //2> propEq 属性相等比较方法返回boolean 比较属性, 7 //String → a → Object → Boolean 8 //R.propEq('hair', 'brown')({a:1,"hair":"brown"}); //true 9 var cars={ 10 rollsroyce:"8add", 11 bmw : 1, 12 benz :2, 13 maserati :3, 14 lincoln:4, 15 jaguar:5, 16 landrover:6, 17 porsche:7, 18 rollsroyce:"8add", 19 rollsroyce:"8add" 20 }; 21 22 function propEq(key,val,obj){ 23 //obj[key] == val ? {key,val} : {} 24 for(i in obj){ 25 if(obj.hasOwnProperty(i)){//过滤 26 if(i == key && cars[i] == val){ 27 var newObj = {}; 28 newObj[i] = cars[i] 29 return newObj; 30 //console.info(i+"---"+cars[i]); 31 } 32 //console.log(i,":",cars[i]); 33 } 34 } 35 }; 36 propEq("rollsroyce","8add",cars);//只匹配出来一个相等的值对 37 38 39 // 增加属性,String → a → {k: v} → {k: v} 40 //3> 41 function assoc(key,val,obj){ 42 var objnew = {}; 43 objnew.key == val; 44 var o = $.extend(obj,objnew); 45 return o; 46 }; 47 assoc("dfas","7777",cars); 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 /**高阶函数封装 特殊参数边界待处理**/ 91 //原则1:保证每次输出的不变性(函数的不变性) 原生slice的可变性使用时注意 92 //原则2: 93 //ifn 条件函数 (fn,fn1,fn2)->fn==true->fn1 fn==false -> fn2; ifn([{fn,fn1},{fn,fn1},{fn,fn1}]); ifn({[fn,fn1],[fn,fn1]}) 94 function ifn(fn,fn1,fn2){ 95 96 }; 97 //Y set function 98 //1> isEmpty 99 function isEmpty(a){ 100 if(a == null) return false; 101 if(a.length == 0 ) return true; 102 if(a == "") return true; 103 return false; 104 }; 105 var a=[]; 106 isEmpty(a); 107 isEmpty(""); 108 //2> 判断是否是string 109 function isString(x){ 110 return Object.prototype.toString.call(x) == '[object String]'; 111 }; 112 //isString("212afaf");//true 113 //isString("");//true 114 //isString(" ");//true 115 //3> 取字符串 或者 数组的 某个位置{字符串或者数组的下标}的值 116 //charAt() 方法可返回指定位置的字符character 117 function nth(offset, list) { 118 var idx = offset < 0 ? list.length + offset : offset;debugger; 119 return isString(list) ? list.charAt(idx) : list[idx]; 120 }; 121 //nth(-6,[1,2,3,4,5,6]);//1 122 //nth(2,[1,2,3,4,"dfd5",6,7]); 123 //nth(-1,[1,2,3]) 124 //nth(-7,[1,2,3,4,5,6]);//undefined 125 //nth(2,"abcdef"); 126 //nth(7,"abcdef");//"" 127 //4.1> 返回除了第一个的剩余的集合 tail [1,2,3] -> [2,3] "abc" -> "bc" 128 //init 相反 返回除了最后一个的剩余的集合 [1,2,3] -> [1,2] "abc" -> "ab" 129 function tail(list){ 130 return list.slice(1,list.length); 131 }; 132 tail([1,2,3]); 133 tail("abcdef"); 134 function init(list){ 135 return list.slice(0,list.length-1); 136 }; 137 init("abcdef");//"abcde" 138 init([1,2,3]);//[1, 2] 139 //4> 获取数组/字符串 第一个,最后一个的值 head and last 140 141 function head(list){ 142 return nth(0,list); 143 }; 144 //head 无需辅助函数写法 145 function head(list){ 146 return list.slice(0,1); 147 }; 148 //head("abc"); 149 //head(["aa","bb","ccc"]); 150 151 function last(list){ 152 return nth(-1,list); 153 }; 154 //last 无需辅助函数写法 155 function last(list){ 156 //return list.slice(list.length-1,list.length);//js原生slice的第二个参数是可选的,默认是切分从start到数组或者字符串结束的所有元素 157 return list.slice(list.length-1); 158 }; 159 last("hello");//"o" 160 last(["aa","bb","ccc"]);//["ccc"] 161 //[a] =>a || str =>first chart 162 function head(arr){//直接通过下标取比较方便 163 return arr==null?null:arr[0]; 164 } 165 //head("a1b2c3"); 166 //head("");//undefined 167 //head(['1aa',2,3]); 168 function last(arr){//直接通过下标取比较方便 169 return arr == null ? null : arr[arr.length-1]; 170 }; 171 last("hello");//"o" 172 last(["aa","bb","ccc"]);//["ccc"] 173 //5> 排序比较逻辑 174 //第一个和第二个比,和第三个比, 175 //或者第一个和第二个比,小的放前面,重点是每一个之间都的比较 176 //[2,1,5] 177 //6.1 判断是不是数组 178 function isArray(x){ 179 return Object.prototype.toString.call(x) == '[object Array]'; 180 }; 181 //6.2 判断是不是对象 182 function isObj(x){ 183 return Object.prototype.toString.call(x) == '[object Object]'; 184 }; 185 //6.3 数据类型判断 (constructor,val) -> boolean 186 function is(Ctor,val){ 187 return val != null && val.constructor === Ctor && val instanceof Ctor; 188 }; 189 //6.4>数字转字符串 190 function numToStr(x){ 191 return isNum(x)?(x+""):x; 192 }; 193 sumToStr(111);//"111" 194 //6> 判断是否是数字 195 function isNum(x){ 196 return Object.prototype.toString.call(x) == '[object Number]'; 197 }; 198 isNum(111); 199 //字符串反转 "abc" -> "cba" 数组反转 [a,b,c] -> [c,b,a] 200 function reverse(list){ 201 var r=[]; 202 var lens = list.length; 203 for(var i=lens-1;i>=0;i--){ 204 r.push(list[i]); 205 } 206 return r=isString(list)?r.join(""):r; 207 }; 208 reverse("abcdef");//fedcba 209 reverse([1,2,3]);//[3,2,1] 210 211 //7> 截取字符串 (2,"abc") -> "ab" 截取数组 (3,[1,2,3,4,5]) -> [1,2,3] 数字截取 (1,123) -> 1 212 function take(cut,list){ 213 var list=numToStr(list); 214 var newList = list.slice(0,cut); 215 return newList; 216 }; 217 take(3,"abcdef");//"abc" 218 take(1,[1,2,3]);//[1] 219 take(3,123456);//123 220 221 //8> 字符串转数组 'abc' -> ["a","b","c"] 数组转字符串 ["a","b","c"] -> 'abc' 实现ats join 和 sta split的功能 222 function staats(list){ 223 var lens = list.length; 224 var r=[]; 225 var s=[]; 226 for(var i=0;i<lens;i++){ 227 r.push(list[i]); 228 s = s+list[i]; 229 } 230 return isArray(list)?s:r; 231 }; 232 staats([1,2,3]);//"123" 233 staats("abcdef");//["a", "b", "c", "d", "e", "f"] 234 235 //9> 对象转数组 {a:1,b:2,c:3} -> [1,2,3],数组转对象 [1,2,3] -> {a:1,b:2,c:3} 236 function otaato(list){ 237 var lens = list.length; 238 var args = arguments.length; 239 240 }; 241 242 243 244 245 //1> []+[] => [] 数组连接 246 function push(array, var_args){//把第二个参数的值 放到第一个参数数组里面 247 for (var i = 1; i < arguments.length; ++i){ 248 array[array.length] = arguments[i]; 249 } 250 }; 251 function concat(array1, array2){ 252 var result = []; 253 for (var i = 0; i < array1.length; ++i){ 254 push(result, array1[i]); 255 } 256 /* for (var i = 0; i < array2.length; ++i){ 257 push(result, array2[i]); 258 }*/ 259 return result; 260 }; 261 concat([1,2,3]);/* 262 concat([1,2,3],[4,5]); 263 */ 264 //2> 实现concat 字符串连接 265 function ss(str1,str2){ 266 for(var i=0;i<str.length;i++){ 267 return str; 268 } 269 } 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 //Y1》Y岳系列函数 (()()()) 286 //辅助函数 287 function a(){ 288 console.log("a"); 289 }; 290 function b(){ 291 console.log("b"); 292 }; 293 function c(){ 294 console.log("c"); 295 }; 296 //主函数 297 function pipeY(){ 298 var args = arguments; 299 return function(){ 300 for(var i=0;i<args.length;i++){ 301 //if(typeof args[i] == "function"){ 302 args[i](); 303 /*}else{ 304 throw new TypeError("The arguments must be function"); 305 } */ 306 } 307 } 308 }; 309 pipeY(a,b,c); 310 311 //Y2》Y岳系列函数 [1,2,3] ==> 实现数组累加 一个for循环搞定 312 313 //主函数 314 function sumList(){ //[]==>num 315 var r=0;//必须赋值为数字 316 return function(list){ 317 for(var i=0;i<list.length;i++){ 318 //r +=list[i]; 319 r=r+list[i]; 320 } 321 return r; 322 } 323 } 324 325 sumList()([1,2,3]); 326 327 //这个是错误的 Y3》Y岳系列函数 [1,2,3] ==> 实现 俩个 数组累加===>for循环嵌套有问题 结果不对 328 function sumTwoList(list1){ // []+[]==>num 329 var r1=0;//必须赋值为数字 330 var r2=0;//必须赋值为数字 331 return function(list2){ 332 for(var i=0;i<list1.length;i++){ 333 for(var j=0;j<list2.length;j++){ 334 r1 +=list1[i]; 335 r2 +=list2[j]; 336 } 337 } 338 console.info(r1); 339 console.info(r2); 340 return r1+r2; 341 } 342 } 343 344 sumTwoList([2,2,0])([1,2,3]); 345 346 //字符串 数组 累加 与 连接 优化修复后 347 //1> list str num 累加 [1,2]+[3,4] ->10 && "12"+"35" ->47 && 12+37 ->49 348 function addList(list1,list2){ 349 var r1=Number(""),r2=Number([]); 350 if(isString(list1) || isString(list2)){//处理字符串参数情况 (true||true)->true (false||true)->true (true||false)->true 351 return Number(list1)+Number(list2); 352 } 353 if(isNum(list1) || isNum(list2)){//处理数字参数情况 354 return list1+list2; 355 } 356 for(var i=0;i<list1.length;i++){ 357 r1 += list1[i]; 358 } 359 for(var i=0;i<list2.length;i++){ 360 r2 += list2[i]; 361 } 362 return r1+r2; 363 } 364 addList([1,2,100],[1,2,7]);//113 365 addList("12","10");//22 366 addList(12,10);//22 367 368 //2> 369 //3> 不限定参数个数的累加与连接 ??如何实现,不限定参数个数,又可以处理所有传入的不限制个数的参数 ?? 370 function alwaysAdd(list){ 371 372 } 373 374 375 376 377 378 //下面是数组累加优化修复前 379 //Y4》Y岳系列函数 [1,2,3] ==> 实现 俩个 数组累加+=, 俩个for循环搞定 []+[]==>num 380 function sumTwoList(list1){ 381 var r1=0; 382 var r2=0; 383 for(var j=0;j<list1.length;j++){ 384 r1 +=list1[j]; 385 } 386 return function(list2){ 387 for(var i=0;i<list2.length;i++){ 388 r2 +=list2[i]; 389 } 390 return r1+r2; 391 } 392 } 393 394 sumTwoList([2,2,0,100,200])([1,2,3]);//310 395 sumTwoList("121")("456");//"01210456" 396 397 //Y5》Y岳系列函数 [1,2,3] ==> 实现 俩个 或者多个 数组累加 []+[]+[]==>num 改写成reduce??? 398 function sumTreeList(list1,list2,list3){ 399 var r1=0; 400 var r2=0; 401 var r3=0; 402 for(var j=0;j<list1.length;j++){ 403 r1 +=list1[j]; 404 } 405 for(var i=0;i<list2.length;i++){ 406 r2 +=list2[i]; 407 } 408 for(var i=0;i<list3.length;i++){ 409 r3 +=list3[i]; 410 } 411 412 return r1+r2+r3; 413 } 414 415 sumTwoList([2,2,0,100,200],[1,2,3],[1,2]); 416 //Y6 {}+{}=num 求俩个对象的和 417 //俩个for in搞定 for是不行的 418 function sumTwoObj(list1,list2){ 419 var r1=0; 420 var r2=0; 421 for( ele in list1){ 422 r1 +=list1[ele]; 423 } 424 for( ele in list2){ 425 r2 +=list2[ele]; 426 } 427 return r1+r2; 428 } 429 sumTwoObj({a:2,b:2},{c:1,d:2,e:3}); 430 //Y7 用es5的 reduce来处理 []+[]=num 431 function(){ 432 433 }; 434 //Y8 (num,num)=[num...num] ---ramda range 435 function numToArr(num1,num2){//先处理传入的参数,容错并转为数字 436 var arr=[]; 437 return function(){ 438 for(var i=num1;i<num2;i++){ 439 num1++; 440 if(num1==num2){ 441 arr.push(num1++); 442 } 443 } 444 } 445 return arr; 446 }; 447 numToArr(1,5)(); 448 //Y9 num==>[] 数字区间转成一个数组 (1,3)=>[1,2,3] 449 function range(from,to){ 450 if(!(isNum(from) && isNum(to))){ 451 throw new TypeError("the arguments to arr must be number"); 452 } 453 var r=[]; 454 while(from < to){ 455 r.push(from); 456 r=r+1; 457 } 458 return r; 459 }; 460 range(1,3); 461 // 辅助函数 判断是否是数字 462 function isNum(x){ 463 return Object.prototype.toString.call(x) === '[object Number]'; 464 }; 465 //7》这个是未完成的 求俩个数组的和 []+[]=>num 466 function addArr(fn,list1,list2){ 467 var r; 468 469 for(var i=0;i<list1.length;i++){ 470 return (function(i){ 471 for(var j=0;j<list2.length;j++){ 472 return (function(j){ 473 r=list1[i]+list2[j]; 474 })(j) 475 } 476 })(i) 477 } 478 return r; 479 }; 480 function add(){return a+b}; 481 482 addArr(add,[2,1],[3,4]) 483 484 485 486 //6》简易reduce 487 //主要看第一个传入的函数实现什么功能呢 488 //辅助函数 489 function plus(a,b){return a+b}; 490 function _reduce(fn,list){ 491 var r; 492 for(var i=0;i<list.length;i++){ 493 r=fn(list[i]); 494 } 495 return r; 496 }; 497 498 //5》简易pipe 499 function pipe(){ 500 var args=arguments; 501 return function(){ 502 var newargs=toArray(arguments); 503 return reduce(function(a){ 504 return a.apply(null,newargs); 505 },args); 506 } 507 } 508 509 510 //4》??第3个,让每一个函数调用的时候,对应到自己的参数 511 function f(_call){ //_call [] 512 return function(_param){//param [] 513 return function(_num){ 514 for (var i =0; i<_num; i++) { 515 _call(_param); 516 }; 517 } 518 } 519 } 520 521 //3》第一个参数是被调用的函数,第二个参数是被调用函数的参数 522 function f(_call){ 523 return function(param){ 524 return _call(param); 525 } 526 }; 527 528 //2》only call once 529 var foo = (function() { 530 var init = false; 531 return function(_call) { 532 return function(e) { 533 if (!init) { 534 _call(e); 535 init = true; 536 } 537 }; 538 }; 539 })(); 540 //foo(function(){console.log("aaa")})(console.log(22)) 541 //1》封一函数,参数是Num 是当前函数的调用次数 542 function f(num){ 543 return function(_call){ 544 for(var i=0;i<num;i++){ 545 _call(); 546 } 547 } 548 }; 549 550 f(3)(function(){console.log(11)}); 551 552 553 554 555 // min expression 556 //1> 557 var a=3,b=2,c=1,d=5,e=7 558 e==d?"e":d==a?"d":a==b?"a":b<c?"c":"last" 559 "last" 560 //2>数据类型判断 issues 561 562 var type = (function () { 563 564 var r = {}, 565 types = ['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Null', 'Array','Object']; 566 for (var i = 0, t; t = types[i++];) { 567 ! function (t) { 568 r['is' + t] = function (obj) { 569 return Object.prototype.toString.call(obj) === '[object ' + t + ']'; 570 } 571 }(t) 572 } 573 return r; 574 })(); 575 576 //---------- 577 function type(obj){ 578 var r = {}; 579 var types = ['Arguments','Function','String','Number','Date','RegExp','Error','Null','Array','Object']; 580 for(var i=0,t;t = types[i++]){ 581 !function(t){ 582 r['is'+t] = function(obj){ 583 return Object.prototype.toString.call(obj) === '[object'+t+']'; 584 } 585 }(t) 586 } 587 }; 588 589 590 591 //3> {} -> boolean 592 function isEmpty(obj){ 593 for(var key in obj)return false; 594 return true; 595 };
相信才会最好