JS权威指南读书笔记(二)

第八章 函数

函数的实参和形参

当调用函数的时候传入的实参比函数声明时指定的形参个数要少,剩下的形参将设置为undefined值。所以比较好的做法是赋予一个默认值。在ES5中可以通过短路运算赋予一个默认值,比如a = a || [],当然这个a是一个形参。在ES6中的做法是直接给函数参数声明默认值:

let a = function (page = 1,pageLimit = 10) {
  //
}

当调用函数的时候传入实参的个数超过定义时的形参个数时,没有办法直接获得未命名值得引用。可以使用arguments来获得所有传入的参数。因为实参对象是一个类数组对象,可以通过下标访问传入函数的实参。在ES6中可以使用剩余参数...来获取所有的参数。

作为值的函数

在JS中,函数不仅是一种语法,也是值。可以将函数赋值给变量,存储在对象的属性或数组的元素中,作为参数传入另一个函数。
function square(x) {return x * x;}
这个定义创建一个新的函数对象,并将其赋值给变量square。函数的名字实际上是看不见的,square仅仅是变量的名字,这个变量指代函数对象。函数还可以赋值给其他的变量,并正常工作:

var s = square;   // s和square指代同一个函数
square(4);       //  => 16
s(4);            //  => 16

函数同样可以赋值给对象的属性。当函数作为对象的属性调用时,函数就称为方法。
函数甚至不需要名字,当把他们赋值给数组元素时:

var a = [function(x) {return x * x},20];
a[0](a[1]);   //  => 400

上式虽然看起来怪怪的,但是是合法的函数调用表达式!

自定义函数属性

如果需要写一个依赖函数自身返回值的函数,最好的办法就是给函数对象添加一个属性,而不是把这个信息放到全局变量中去污染环境。举个例子:

function sum () {
    return sum.counter++;//  先返回计数器的值,然后计数器自增1
}
sum.counter = 0;

闭包

JS采用词法作用域,也就是说,函数的执行依赖于变量作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的。为了实现这种词法作用域,JS函数对象的内部状态不仅包含函数的代码逻辑,还必须引用当前的作用域链。函数对象可以通过作用域链相互关联起来,函数体内部的变量都可以保存在函数作用域内,这种特性在计算机科学中称为“闭包”
来看一个官方示例:

var scope = "global scope";  //全局变量
function checkscope() {
    var scope = "local scope";  //局部变量
    function f() {return scope;}  //返回scope
    return f;
}
checkscope()()  //  返回???

回想一下词法作用域的基本规则:JS函数的执行用到了作用域链,这个作用域链是函数定义的时候创建的。嵌套的函数f()定义在这个作用域里,其中的变量scope一定是局部变量,不管在何时何地执行函数f()。所以返回local scope,而不是global scope

函数属性、方法和构造函数

bind()方法

这个方法的作用就是将函数绑定至某个对象。例如:

function f(y) {return this.x + y}
var o = {x : 1};
var g = f.bind(o); //通过调用g(x)来调用o.f(x)
g(2)  // => 3

不仅如此,还附带一些其他应用:除了第一个实参之外,传入bind()的实参也会绑定至this.举个例子:

var sum = function(x,y) {return x + y};
var succ = sum.bind(null,1);
// this的值绑定到null,并且第一个参数绑定到1
succ(2) // 3;x绑定到1,并传入2作为实参y

function f(y,z) {return this.x + y + z};
var g = f.bind({x:1},2);
g(3) // 6;this.x绑定到1,y绑定到2,z绑定到3

Function()构造函数

Function()构造函数可以传入任意数量的字符串实参,最后一个实参表示的文本就是函数体;它可以包含任意的JS语句,每两条语句之间用分号分隔。如果不包含任何参数,只需传入函数体字符串即可。

注意:Function()构造函数不需要通过传入实参指定函数名,也就是创建的是一个匿名函数。

关于Function()构造函数有几点需要注意:

  • Function()构造函数允许JS在运行时动态地创建并编译函数。
  • 每次调用Function()构造函数都会解析函数体,并创建新的函数对象。如果是在一个循环或者多次调用的函数中执行这个构造函数,效率会受影响。而循环中的嵌套函数和函数定义表达式不会每次执行都重新编译。
  • Function()构造函数所创建的函数并不是使用词法作用域,函数体代码的编译总是会在顶层函数执行。 如下所示:
var scope = "global";
function cons() {
    var scope = 'local';
    return new Function("return scope");
    //Function()构造函数只传入一个字符串表示该匿名函数没有参数,只有返回体。
    //上面说到并不是使用词法作用域,所以此时会去顶层函数所处作用域的变量scope,所以结果返回“global”
}

可以将Function()构造函数认为是在全局作用域执行的eval()。eval()可以在自己的私有作用域内定义新变量和函数。在很多JS编码规范里是不建议使用eval()和Function构造函数。具体可参考Airbnb的编码规范

函数式编程

高阶函数

所谓高阶函数就是操作函数的函数,它接收一个或多个函数作为参数,并返回一个新函数。举个🌰:

function mapper(f) {
    return function(a) {return map(a,f);};
}
var increment = function(x) {return x + 1};
var incrementer = mapper(increment);
incrementer([1,2,3]) //  [2,3,4]

// 调用mapper会传入一个map()方法里的回调函数,然后会返回一个函数,这个函数的参数就是需要处理的数组。
//可以理解为mapper(increment)([1,2,3])
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容