JavaScript 基础(六) 数组方法 闭包
在一个对象中绑定函数,称为这个对象的方法。 在JavaScript 中,对象的定义是这样的;
var guagua = {
name:'瓜瓜',
birth:1990
};
但是,如果我们给瓜瓜绑定一个函数,就可以做更多的事情。
var guagua = {
name:'瓜瓜',
birth:1990,
age:function(){
var y = new Date().getFullYear();
return y - this.birth;
}
}
guagua.age; // function guagua.age()
xguagua.age(); // 今年调用是25,明年调用就变成26了
apply 虽然在一个独立的函数调用中,根据是否是strict模式,this 指向undefined 或window,不过我们还可以控制this 的指向。 要指定函数的this 指向哪个个对象,可以用函数的本身的apply 方法,他接收两个参数,第一个就是需要绑定的this 变量, 第二个参数是Array,表示函数本身的参数。 用apply 修复getAge() 调用:
function getAge(){
var y = new Date().getFullYear();
return y - this.birth;
}
var guagua = {
name:'小明',
birth:1990,
age:getAge
};
guagua.age(); // 25
getAge.apply(xiaoming,[]); // 25, this 指向xiaoming 参数为空。
另一个与apply()类似的方法是call(),唯一区别是: apply()把参数打包成Array再传入; call()把参数按顺序传入。 比如调用Math.max(3, 5, 4),分别用apply()和call()实现如下 Math.max.apply(null,[3,5,4]); // 5 Math.max.call(null,3,5,4); // 5 对普通函数调用,我们通常把this绑定为null。
map 由于map() fangf dingyi zai JavaScript 的Array 中,我们调用Array 的map() 方法,传入自己的函数,就得到了一个新的Array
function pow(x){
return x * x;
}
var arr = [1,2,3,4,5,6,7,8,9];
arr.map(pow); // [1,4,9,16,25,36,49,64,81]
map() 传入的参数是pow,即函数对象本身。
reduce 在看reduce 的应付,Array 的reduce() 把一个函数作为在这个Array 的[x1,x2,x3....]上,这个函数必须接收两个参数, redyce()把结果继续和序列下个元素做积累计算,其效果就是。 [x1,x2,x3,x4].reduce(f) = f(f(f(x1,x2),x3),x4) 比方说对一个Array求和,就可以用reduce实现:
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x + y;
}); // 25
要把[1, 3, 5, 7, 9]变换成整数13579,reduce()也能派上用场:
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x * 10 + y;
}); // 13579
filter filter 也是一个常用的操作,它用于吧Array的某些元素过滤掉,然后返回剩下的元素。 和map()类似,Array的filter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,
然后根据返回值是true还是false决定保留还是丢弃该元素。 在一个Array中,删掉偶数,只保留奇数,可以这么写:
var arr = [1,2,4,5,6,9,10,15];
var r = arr.filter(function(x){
return x % 2 !==0;
});
r: // [1,5,9,15]
把一个Array中的空字符串删掉,可以这么写:
var arr = ['A','','B',null,undefined,'C',''];
var r = arr.flter(function(s){
return s && s.trim(); // 注意: IE9以下的版本没有trim()方法
})
r: // ['A','B','C']
可见用filter()这个高阶函数,关键在于正确实现一个“筛选”函数。
sort JavaScript的Array的sort()方法就是用于排序的,但是排序结果可能让你大吃一惊:
// 看上去正常 的结果
['Google','Apple','Microsoft'].sort(); // ['Apple','Google','Microsoft'];
// apple 排在了最后
[10,20,1,2].sort(); //[1,10,2,20]
第二个排序把apple排在了最后,是因为字符串根据ASCII码进行排序,而小写字母a的ASCII码在大写字母之后。
要按数字大小排序,我们可以这么写:
var arr = [10,20,1,2]
arr.sort(function(x,y){
if(x < y){
return 1;
}
if(x > y){
return 1;
}
return 0;
}) // [1,2,10,20]
如果要倒序排序,我们可以把大的数放前面:
var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
if (x < y) {
return 1;
}
if (x > y) {
return -1;
}
return 0;
}); // [20, 10, 2, 1]
我们提出排序应该忽略大小写,按照字母序排序
var arr = ['Google','apple','Microsoft'];
arr.sort(function(s1,s2){
x1 = s1.toUpperCase();
x2 = s2.toUpperCase();
if(x1 < x2){
return -1;
}
if(x1 > x2){
return 1;
}
return 0;
}); // ['apple','Google','Microsoft']
忽略大小写来比较两个字符串,实际上就是先把字符串都变成大写(或者都变成小写),再比较。
sort()方法会直接对Array进行修改,它返回的结果仍是当前Array:
var a1 = ['B', 'A', 'C'];
var a2 = a1.sort();
a1; // ['A', 'B', 'C']
a2; // ['A', 'B', 'C']
a1 === a2; // true, a1和a2是同一对象
闭包函数作为返回值 高阶段函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
function sum(arr){
return arr.reduce(function(x,y){
return x + y;
});
}
sum([1,2,3,4,5]); //15
但是,如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数!
function lazy_sum(arr){
var sum = function (){
return arr.reduce(function(x,y){
return x + y;
})
}
return sum;
当我们调用lazy_sum()时,返回的并不是求和结果,而是求和函数:
var f = lazy_sum([1,2,3,4,5]); // function sum();
调用函数f 时,才真正计算求和的结果。
f(); // 15
当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数:
var f1 = lazy_sum([1,2,3,4,5]);
var f2 = lazy_sum([1,2,3,4,5])
f1 === f2; //false
闭包 返回的函数在其定义内部引用了局部变量arr,所有,说以一个函数返回了一个函数,其内部的局部变量还被新幻术引用,所以闭包用起来简单。
function count(){
var arr = [];
for(var i= 1; i <=3; i++ ){
arr.push(function(){
return i * i;
})
}
return arr;
}
var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果是:
f1(); // 16
f2(); //16
f3(); //16
返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
function count(){
var arr = [];
for(var i=1; i <=3; i++){
arr.push((function (n){
return function(){
return n * n;
}
})(i));
}
注意这里用来一个创建一个匿名函数并立刻执行的语法:
(function(x){
return x * x;
})(3); //9
return arr;
}
var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
f1(); //1
f2(); //4
f3();//9
在没有class机制,只有函数的语言里,借助闭包,同样可以封装一个私有变量。我们用JavaScript创建一个计数器:
function create_counter(initial){
var x = inintial || 0;
return {
inc : function(){
x +=1;
return x;
}
}
}
它用起来像这样:
var c1 = create_counter();
c1.inc(); // 1
c1.inc();//2
c1.inc();//3
var c2 = create_counter(10);
c2.inc(); //11
c2.inc(); //12
c2.inc();//13
闭包还可以把多参数的函数变成单参数的函数。
function make_pow(n){
return function(x){
return Math.pow(x,n);
}
}
// 创建两个新函数。
var pow2 = make_pow(2);
var pow3 = make_pow(3);
pow2(5); // 25
pow3(7); //343
- R语言数据抓取实战——RCurl+XML组合与XPath解析
- Python网络数据抓取实战——Xpath解析豆瓣书评
- 左手用R右手Python系列17——CSS表达式与网页解析
- 左手用R右手Python系列16——XPath与网页解析库
- 扒一扒rvest的前世今生!
- RCurl中这么多get函数,是不是一直傻傻分不清!!!
- 机器学习(二)深度学习实战-使用Kera预测人物年龄问题描述引入所需要模块加载数据集创建模型编译模型优化optimize1 使用卷积神经网络optimize2 增加神经网络的层数输出结果结果
- 异步加载的基本逻辑与浏览器抓包一般流程
- 左手用R右手Python系列之——表格数据抓取之道
- XML/HTML/JSON——数据抓取过程中不得不知的几个概念
- R语言网络数据抓取的又一个难题,终于攻破了!
- R语言数据清洗实战——高效list解析方案
- 左手用R右手Python系列——循环中的错误异常规避
- SpringBoot2.x开发案例之整合Quartz任务管理系统
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ASP.NET Core 使用 AutoFac 注入 DbContext
- Python爬虫练习:爬取800多所大学学校排名、星级等
- Python爬取股票信息,并实现可视化数据
- Python爬虫练习:爬取素材网站数据
- 25行代码带你爬取4399小游戏数据,看下童年的游戏是否还在
- 十一假期快到了,不知道该去哪玩?爬取旅游攻略
- 干掉Navicat:正版 MySQL 官方客户端真香!
- WordPress评论插件wpDiscuz任意文件上传复现
- 干货 | 性能提升400%,ClickHouse在携程酒店数仓的实践
- 干货 | 携程如何基于ARIMA时序分析做业务量的预测
- Python爬取王者荣耀全套皮肤
- 怎么搭建直播平台,合理使用验证码工具类
- 再见了SpringMVC,这个框架有点厉害,甚至干掉了Servlet!
- 可以旋转的3D韦恩图你见过吗?
- BFE.dev前端刷题 104. 按层遍历DOM树