js的中的函数(三)
2023-07-08 00:56:38 来源:博客园
方法
什么是js的方法?简单讲,绑定到对象的函数就是方法。
(资料图片仅供参考)
this
在对象的方法中,我们常常使用this关键字。this关键字代表方法所绑定的对象。
var wangqiang = { name : "wangqiang", age : 18, city : "guangzhou", address : "tianhe", //绑定到对象的函数叫方法 getBirth:function(){ let now = new Date(); return now.getFullYear() - this.age; } } wangqiang.getBirth(); //2005 var birth = wangqiang.getBirth; birth(); //NaN,脱离了绑定的对象。
上述代码所示,在方法getBirth()内部,我们用到了一个this关键字。这个关键字指向了绑定的对象,要正确执行方法,需要按照 obj.xxx()的方式才能正确地调用方法,保证方法绑定的对象,this的指向才能正确。
再看如下代码:
var lili = { name : "lili", age : 12, city : "beijing", address : "chaoyang", getBirth : function(){ let diff = function(year){ //超出了this的作用范围,this为undefined return year-this.age; } let now = new Date(); console.log(diff(2022)); return now.getFullYear() - this.age; } }
在getBirth方法中,我们有定义了一个匿名函数。在匿名函数不能再使用this,因为这时的this是undefined。我们可以在匿名函数外部用一个 变量接收this,在匿名函数内部再使用这个变量。也就是this对象不能跨越两层函数进行使用。
var lili = { name : "lili", age : 12, city : "beijing", address : "chaoyang", //方法的简写 getBirth(){ let that = this; let diff = function(year){ return year-that.age; } let now = new Date(); console.log(diff(2022)); return now.getFullYear() - this.age; } }
为此,可以在第一次函数里用一个变量that接收this,在第二层函数里再使用that,从而避免this变量不能跨越两层的障碍。
apply
函数通过apply方法,应用到对象上。
var xiaoli = { name : "xiaoli", age : 12, city : "beijing", address : "chaoyang", birth : getBirth } function getBirth(){ let now = new Date(); return now.getFullYear() - this.age; } xiaoli.birth(); getBirth.apply(xiaoli,[]);//应用到xiaoli对象上,参数数组为[] getBirth(); // Uncaught TypeError
另一个与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
闭包
在JavaScript中,一个函数可以作为另外一个函数的参数进行传递。同样地,一个函数也可以作为另外一个函数的返回值。例如:
function lazy_sum(...rest){ return function sum(){ let reduce = rest.reduce(function(s,x){ return s += x; },6); return reduce; } } var lazy_sum1 = lazy_sum(1,2,4,6); var lazy_sum2 = lazy_sum(1,2,4,6); lazy_sum1(); //调用sum()函数,返回13 lazy_sum2(); //调用sum()函数,返回13 typeof lazy_sum1(); // 返回function typeof lazy_sum2(); // 返回function lazy_sum1 == lazy_sum2 // false
上述代码所示,调用lazy_sum1和lazy_sum2函数,它们都返回一个sum()函数。虽然返回的名称相同,但不同于数值的相等比较,它们并不相等。
看起来作用不大,只是可以延迟调用而已。再看下边的例子:
//闭包可以在函数内部封装一个变量 function wrap(initial){ initial = initial || 0; return function inc(){ initial += 1; return initial; } } var w = wrap(2); w(); //返回3 w(); //返回4 w(); //返回5
上述代码所示,wrap()是一个函数,它接收一个initial作为参数,这个函数的返回值也是一个函数,它是inc()。我们将inc()函数赋值给变量w, w函数调用一次返回3。接下来再调用一次,其内部的变量initial已经保留了3这个值,所以这时的返回值就是4。接下来的每次调用逻辑都是一致的。 这种在函数中封装了一个变量的函数形成了闭包。这种在函数中封装既封装了变量,又封装了方法的闭包,是不是有点像Java中的类呢?
闭包
ES6标准新增了一种新的函数:Arrow Function(箭头函数)。为什么叫Arrow Function?因为它的定义用的就是一个箭头:
x => x * x
使用规则
上面的箭头函数相相当于一个匿名函数:
function (x) { return x * x; }
箭头函数简化了函数定义。箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ ... }和return都省略掉了。 还有一种可以包含多条语句,这时候就不能省略{ ... }和return:
x => { if (x>0){ return x; }else{ return -x; } }
如果函数有多个参数,需使用括号,参数之间以逗号隔开
// 两个参数: (x, y) => x * x + y * y // 无参数: () => 3.14 // 可变参数: (x, y, ...rest) => { var i, sum = x + y; for (i=0; i < rest.length; i++) { sum += rest[i]; } return sum; }
如果要返回一个对象,就要注意,如果是单表达式,这么写的话会报错:
// SyntaxError: x => { foo: x }
表达式的对象和函数体的{...}相冲突,需在对象外加上括号:
x => ({foo:x});
前面章节指出了对象方法上,this使用的注意事项:
var lili = { name : "lili", age : 12, city : "beijing", address : "chaoyang", getBirth(){ let diff = function(year){ return year-this.age; // this指向window或undefined }; let now = new Date(); return now.getFullYear() - this.age; } }
现在,箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj:
var lili = { name : "lili", age : 12, city : "beijing", address : "chaoyang", getBirth(){ let diff = (year)=>year-this.age; // this指向lili let now = new Date(); return now.getFullYear() - this.age; } }
文章同时发表在:码农编程网欢迎访问
本节重点:
- 什么是方法,方法的调用;
- 注意对象方法内部的this指向,避免指向错误;
- apply,call的使用和区别;
- 定义一个返回类型为函数的函数;
- 如何形成闭包,闭包的使用;
- 什么是箭头函数,箭头函数的使用;
- 箭头函数修复了对象方法中的this指向。
关键词:
[责任编辑:]
相关阅读
- (2023-07-08)js的中的函数(三)
- (2023-07-08)5名基金经理离职,融通基金上半年离职数量最多,发生了啥?
- (2023-07-08)全国各地纪念馆同步举行纪念全民族抗战爆发86周年活动
- (2023-07-08)北京市经济和信息化局“数字人”局长现身2023全球数字经济大会闭幕式
- (2023-07-08)央行发布《中央银行存款账户管理办法》 加强关键环节风险管控
- (2023-07-08)陕西组建工作专班 全链条打击犯罪
- (2023-07-08)“宝藏解放碑”第二季网络主题宣传启动
- (2023-07-08)中概股走强 阿里巴巴涨超4%
- (2023-07-08)华为云重磅发布盘古大模型3.0
- (2023-07-08)支付宝、财付通收央行巨额罚单!
- (2023-07-08)物业管理费纠纷应该怎样样处理
- (2023-07-08)预算培训ppt模板
- (2023-07-08)7月7日财通资管科技创新一年定开混合净值下跌1.81%
- (2023-07-08)普京召开俄罗斯联邦安全会议常务委员会议
- (2023-07-08)出行没有七天无理由退货 聚合平台不能罔顾安全
- (2023-07-08)*ST美尚(300495)7月7日主力资金净买入67.94万元
- (2023-07-08)刚满月的小柴犬怎么喂养(一个月大的小柴狗怎么喂养)
- (2023-07-08)飞力达拟定增募资不超2.94亿元
- (2023-07-08)广东肇庆创新推出专利许可收益权质押融资模式
- (2023-07-08)“男子掏警官证让交警放行”,警方通报
- (2023-07-08)蚂蚁集团被罚没71.23亿元,发布公告回应:诚恳接受、坚决服从
- (2023-07-08)大河路街道绿源社区开展“爱的号码牌”DIY活动
- (2023-07-08)易普力(002096.SZ)子公司联合体中标有关石英砂岩矿开采施工项目 合同总金额约93亿元
- (2023-07-08)因占压财政存款或资金等违法行为,平安银行合计被罚超3400万元
- (2023-07-08)2023年7月总票房破20亿
- (2023-07-08)一加首款折叠手机曝光 OnePlus Open下月发布
- (2023-07-08)恒力石化上市以来直接融资超300亿元 重启分拆康辉新材上市意欲何为?
- (2023-07-08)蚂蚁科技集团被国家金融监督管理总局罚没37.62亿余元
- (2023-07-08)玩把大的 极氪001“产品力免费升级”权益出炉
- (2023-07-08)湖南第一师范学院学生团队在沅江开展暑期“三下乡”社会实践