前言
这篇文章的总结和学习的内容,讲从第三章开始的;整本书学习时间大概是一星期的时间,利用零散的时间其实就可以学习完。
基础知识,是需要不断学习和补充的,如果总用不到的知识,我们就会忘记;加上我不是计算机专业的,所以也一直在努力💪弥补。
学习的方式
有句古话,“光说不做假把式”;这样就没意思了。
所以还是要敲代码和自己实践,这都是很重要的。
我挺推荐这个微信读书
因为你可以在闲暇时,用手机翻阅,还有读书朗诵
的功能;有的时候,我们在看技术书的时候总是在走神。就可以用app的朗诵功能让你更加集中注意力。
一定要敲代码!!!!
一定要自己学会总结;这也很重要。好记性不如烂笔头,就是这个道理。
JavaScript忍者秘籍第二版的电子版
是epub的版本;《JavaScript忍者秘籍第二版.epub》;阅读电子版是为了更方便 我在电脑上去操作事例的时候更加容易,直接复制出来,打断点。
如果你需要,那么下面就是文档。
链接: https://pan.baidu.com/s/1L30_... 密码: n56j
下面就开始我们今天的总结和概况内容。我标题也说,这是重点内容总结
,是方便你快速的记忆和回忆知识点
,更好的方式还是系统的阅读一遍。
接下来的有些内容,我会直接引入文章的句子,请见怪不怪。
我会按照目录的顺序进行梳理
第3章 新手的第一堂函数课:定义与参数
对象能做的任何一件事,函数也都能做。
函数也是对象,唯一的特殊之处在于它是可调用的(invokable),即函数会被调用以便执行某项动作。
回调函数
function useless(ninjaCallback) {
return ninjaCallback();
}
这个函数可能没什么用,但它反映了函数的一种能力,即将函数作为另一个函数的参数,随后通过参数来调用该函数。
存储函数
var store = {
nextId: 1, //⇽--- 跟踪下一个要被复制的函数
cache: {}, //⇽--- 使用一个对象作为缓存,我们可以在其中存储函数
add: function(fn) {
if (!fn.id) {
fn.id = this.nextId++;
this.cache[fn.id] = fn;
return true;
}
} //⇽--- 仅当函数唯一时,将该函数加入缓存
};
function ninja(){}
assert(store.add(ninja),
"Function was safely added.");
assert(!store.add(ninja),
"But it was only added once."); //⇽--- 测试上面的代码按预期工作
fn.id将会是,传进来fn的唯一标示;如果在传进来相同的函数时,我们会发现这个id是存在的,就不会添加进来。
相当于修改了这个fn函数属性,添加了一个唯一标示ID;
如果是没有加进来的fn,那么就没有这个ID标示。
fn.id = this.nextId++;
函数定义
JavaScript提供了几种定义函数的方式,可以分为5类。
函数声明
function myFun(){ return 1;}
每个函数声明以强制性的function开头
,其后紧接着强制性的函数名
,以及括号和括号内一列以逗号分隔的可选参数名。
函数声明必须具有函数名
是因为它们是独立语句。一个函数的基本要求是它应该能够被调用,所以它必须具有一种被引用方式,于是唯一的方式就是通过它的名字
。
函数表达式
var myFun = function (){ return 1;}
JavaScript中的函数是第一类对象,除此以外也就意味着它们可以通过字面量创建
,可以赋值给变量和属性
,可以作为传递给其他函数的参数或函数的返回值。
注意⚠️:
函数声明和函数表达式除了在代码中的位置不同以外,还有一个`更重要的不同点`是:
* 函数声明来说,函数名是强制性的;
* 函数表达式来说,函数名则完全是可选的。
区分函数声明和函数表达式⚠️
《你不知道的JavaScript(上卷)》中,p27页,是这样写的
区分函数声明和函数表达式最简单的方法是看function关键字出现在声明的位置(不仅仅是一行代码,而是整个声明的位置)。 如果function是声明中第一个词,那么就是函数声明,否则就是函数表达式
立即函数
标准函数的调用和函数表达式的立即调用的对比
注意⚠️:加括号的函数表达式
函数表达式被包裹在一对括号内。为什么这样做呢?
其原因是纯语法层面的。JavaScript解析器必须能够轻易区分函数声明和函数表达式
之间的区别如果去掉包
裹函数表达式的括号,把立即调用作为一个独立语句function() {}(3),JavaScript开始解析时便会结束
,因为这个独立语句以function开头,那么解析器就会认为它在处理一个函数声明。每个函数声明必须有一个名字
(然而这里并没有指定名字),所以程序执行到这里会报错
。为了避免错误
,函数表达式要放在括号内,为JavaScript解析器指明它正在处理一个函数表达式而不是语句。
funciton(){33}
会直接报错,因为这个函数声明是错误的表现形式。
如果加上括号,或者是一元操作符
函数表达式要放在括号内,为JavaScript解析器指明它正在处理一个函数表达式而不是语句。
还有一种相对简单的替代方案(function(){}(33))也能达到相同目标(然而这种方案有些奇怪,故不常使用)。把立即函数的定义和调用都放在括号内,同样可以为JavaScript解析器指明它正在处理函数表达式。
不同于用加括号的方式区分函数表达式和函数声明,这里我们使用一元操作符+、-、!和~。这种做法也是用于向JavaScript引擎指明它处理的是表达式,而不是语句。
箭头函数
const myFun =()=>{ return 1;}
or
var greet = name => "Greetings " + name; //⇽--- 定义箭头函数”
注意这个新操作符——胖箭头符号=>(等号后面跟着大于号)是定义箭头函数的核心。
函数构造函数
new Function('a', 'b', 'return a + b')
生成器函数
function* myGen(){ yield 1; }
函数的实参和形参
- 形参是我们定义函数时所列举的变量。
- 实参是我们调用函数时所传递给函数的值。
函数形参是在函数定义时指定的,而且所有类型的函数都能有形参。
摘录来自: [美] John Resig Bear Bibeault Josip Maras. “JavaScript忍者秘籍(第2版)。” iBooks.
- 函数声明(skulk函数的ninja形参)。
- 函数表达式 (performAction函数的person和action形参)。
- 箭头函数 (形参daimyo)。
从另一方面说,实参则与函数的调用相联系。它们是函数调用时所传给函数的值。
- 字符串Hattori以函数实参的形式传递给函数skulk。
- 字符串Oda Nobunaga以函数实参的形式传递给函数rule。
- skulk函数的形参ninja作为实参传递给函数performAction。
可以这样理解哈:
函数声明和函数表达式,箭头函数,在声明的时候在括号里面的是形参,
函数调用时,传递给函数的是实参
剩余参数
function multiMax(first, ...remainingNumbers) { ⇽--- 剩余参数以…作前缀
var sorted = remainingNumbers.sort(function(a, b) {
return b – a; ⇽--- 以降序排序余下参数
});
return first * sorted[0];
}
assert(multiMax(3, 1, 2, 3) == 9, ⇽--- 函数调用方式和其他函数类似
"3*3=9 (First arg, by largest.)")
为函数的最后一个命名参数前加上省略号(...)前缀,这个参数就变成了一个叫作剩余参数的数组,数组内包含着传入的剩余的参数。
注意⚠️:只有函数的最后一个参数才能是剩余参数。
ES6中处理默认参数的方式
function performAction(ninja, action = "skulking"){ ⇽--- ES6中可以为函数的形参赋值
return ninja + " " + action;
}
assert(performAction("Fuma") === "Fuma skulking",
"The default value is used for Fuma");
assert(performAction("Yoshi") === "Yoshi skulking",
"The default value is used for Yoshi");
assert(performAction("Hattori") === "Hattori skulking",
"The default value is used for Hattori"); ⇽--- 若没传入值,则使用默认参数
assert(performAction("Yagyu", "sneaking") === "Yagyu sneaking",
"Yagyu can do whatever he pleases, even sneak!"); ⇽--- 使用了传入的参数
小结
- 把JavaScript看作函数式语言你就能书写复杂代码。
- 作为第一类对象,函数和JavaScript中其他对象一样。类似于其他对象类型,函数具有以下功能。
- 通过字面量创建。
- 赋值给变量或属性。
- 作为函数参数传递。
- 作为函数的结果返回。
- 赋值给属性和方法。
- 回调函数是被代码随后“回来调用”的函数,它是一种很常用的函数,特别是在事件处理场景下。
- 函数具有属性,而且这些属性能够被存储任何信息,我们可以利用这个特性来做很多事情;例如:
- 可以在函数属性中存储另一个函数用于之后的引用和调用。
- 可以用函数属性创建一个缓存(记忆),用于减少不必要的计算。
- 有很多不同类型的函数:函数声明、函数表达式、箭头函数以及函数生成器等。
- 函数声明和函数表达式是两种最主要的函数类型。函数声明必须具有函数名,在代码中它也必须作为一个独立的语句存在。函数表达式可以不必有函数名,但此时它就必须作为其他语句的一部分。
- 箭头函数是JavaScript的一个新增特性,“这个特性让我们可以使用更简洁的方式来定义函数。
- 形参是函数定义时列出的变量,而实参是函数调用时传递给函数的值。
- 函数的形参列表和实参列表长度可以不同。
- 未赋值的形参求值得到undefined。
- 传入的额外实参不会被赋给任何一个命名形参。
- 剩余参数和默认参数是JavaScript的新特性。
- 剩余参数——不与任何形参名相匹配的额外实参可以通过剩余参数来引用。
- 默认参数——函数调用时,若没传入参数,默认参数可以给函数提供缺省的参数值。
摘录来自: [美] John Resig Bear Bibeault Josip Maras. “JavaScript忍者秘籍(第2版)。” iBooks.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。