1、filter高级函数的使用(使用函数进行过滤)
请尝试用filter()
筛选出素数:
'use strict'; function get_primes(arr) {
1 return (arr.filter(function(x){
2 if(x <= 1){ return false;}else{ 3 for(var i = 2;i <= x / 2;i++){ 4 if(x % i == 0) return false; 5 } 6 return true; 7 } 8 }) 9 );//余数为不为0
} // 测试: var x, r, arr = []; for (x = 1; x < 100; x++) { arr.push(x); } r = get_primes(arr); if (r.toString() === [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97].toString()) { alert('测试通过!'); } else { alert('测试失败: ' + r.toString()); }
2、sort排序函数:通常规定,对于两个元素x
和y
,如果认为x < y
,则返回-1
,如果认为x == y
,则返回0
,如果认为x > y
,则返回1。
1 var arr = [10, 20, 1, 2]; 2 arr.sort(function (x, y) { 3 if (x < y) { 4 return -1; 5 } 6 if (x > y) { 7 return 1; 8 } 9 return 0; 10 }); // [1, 2, 10, 20]
1 var arr = ['Google', 'apple', 'Microsoft']; 2 arr.sort(function (s1, s2) { 3 x1 = s1.toUpperCase(); 4 x2 = s2.toUpperCase(); 5 if (x1 < x2) { 6 return -1; 7 } 8 if (x1 > x2) { 9 return 1; 10 } 11 return 0; 12 }); // ['apple', 'Google', 'Microsoft']
sort()
方法会直接对Array
进行修改,它返回的结果仍是当前Array
3、闭包
例:
1 function lazy_sum(arr) { 2 var sum = function () { 3 return arr.reduce(function (x, y) { 4 return x + y; 5 }); 6 } 7 return sum; 8 } 9 10 var f = lazy_sum([1, 2, 3, 4, 5]); // 返回function sum([1, 2, 3, 4, 5])函数 11 12 f(); // 返回函数值15
在这个例子中,我们在函数lazy_sum
中又定义了函数sum
,并且,内部函数sum
可以引用外部函数lazy_sum
的参数和局部变量,当lazy_sum
返回函数sum
时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
而要注意的一点是当我们调用lazy_sum()
时,每次调用都会返回一个新的函数,即使传入相同的参数,即
1 var f1 = lazy_sum([1, 2, 3, 4, 5]); 2 var f2 = lazy_sum([1, 2, 3, 4, 5]); 3 f1 === f2; // false
f1()和f2()的调用结果互不影响,(意思是两个函数分配到不同的指针上了吧??)
深入理解:
1 function count() { 2 var arr = []; 3 for (var i=1; i<=3; i++) { 4 arr.push(function () { 5 return i * i; 6 }); 7 } 8 return arr; 9 } 10 11 var results = count(); 12 var f1 = results[0]; 13 var f2 = results[1]; 14 var f3 = results[2]; 15 16 f1(); // 16 17 f2(); // 16 18 f3(); // 16 三个结果相同..
首先,count()函数返回的是一个函数数组,当count函数运行时,它会一直运行,直到产生三个函数元素,“arr[0],arr[1],arr[2]",而此时i的值已经成为4(i++)了,于是当这三个元素函数继续调用时,值都是16。而解决方法是不用或者
1 function count() { 2 var arr = []; 3 for (var i=1; i<=3; i++) { 4 arr.push((function (n) { 5 return function () { 6 return n * n; 7 } 8 })(i)); 9 } 10 return arr; 11 } 12 13 var results = count(); 14 var f1 = results[0]; 15 var f2 = results[1]; 16 var f3 = results[2]; 17 18 f1(); // 1 19 f2(); // 4 20 f3(); // 9 21 22 //注意这里用了一个“创建一个匿名函数并立刻执行”的语法: 23 (function (n) { 24 return function () { 25 return n * n; 26 } 27 })(i) 28 29 (function (x) { 30 return x * x; 31 })(3); // 9
ps:function (x) { return x * x } (3);会报SyntaxError错误,因此需要用括号把整个函数定义括起来
闭包的作用主要体现在模块化的生成,即私有变量,
1 'use strict'; 2 3 function create_counter(initial) { 4 var x = initial || 0; //当initail不为空时,x = initail,否则为0 5 return { 6 inc: function () { 7 x += 1; 8 return x; 9 } 10 } 11 } //计数器 12 13 var c1 = create_counter(); //c1 => { var x ; inc: function () { x +=1; return x; } } 14 c1.inc(); // 1 15 c1.inc(); // 2 16 c1.inc(); // 3 17 18 var c2 = create_counter(10); 19 c2.inc(); // 11 20 c2.inc(); // 12 21 c2.inc(); // 13
在返回的对象中,实现了一个闭包,该闭包携带了局部变量x
,并且,从外部代码根本无法访问到变量x
。换句话说,闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来。
闭包还可以把多参数的函数变成单参数的函数。例如,要计算xy可以用Math.pow(x, y)
函数,不过考虑到经常计算x2或x3,我们可以利用闭包创建新的函数pow2
和pow3
:
1 function make_pow(n) { 2 return function (x) { 3 return Math.pow(x, n); 4 } 5 } 6 7 // 创建两个新函数: 8 var pow2 = make_pow(2); //相当于pow2=>function(x){ return Math.pow(x,2); } 9 var pow3 = make_pow(3); //相当于pow3=>function(x){ return Math.pow(x,3); }
10
11 pow2(5); // 25
12 pow3(7); // 343
理解下面代码
1 'use strict'; 2 3 // 定义数字0: 4 var zero = function (f) { 5 return function (x) { 6 return x; 7 } 8 }; 9 10 // 定义数字1: 11 var one = function (f) { 12 return function (x) { 13 return f(x); 14 } 15 }; 16 17 // 定义加法: 18 function add(n, m) { 19 return function (f) { 20 return function (x) { 21 return m(f)(n(f)(x)); 22 } 23 } 24 } 25 26 // 计算数字2 = 1 + 1: 27 var two = add(one, one); 28 29 // 计算数字3 = 1 + 2: 30 var three = add(one, two); 31 32 // 计算数字5 = 2 + 3: 33 var five = add(two, three); 34 35 // 你说它是3就是3,你说它是5就是5,你怎么证明? 36 37 // 呵呵,看这里: 38 39 // 给3传一个函数,会打印3次: 40 (three(function () { 41 console.log('print 3 times'); 42 }))(); 43 44 // 给5传一个函数,会打印5次: 45 (five(function () { 46 console.log('print 5 times'); 47 }))();