JS学习笔记(五)
本系列更多文章,可以查看专栏 JS学习笔记
文章目录
JS学习笔记(五)一、函数1. 函数定义2. 方法( 对象 + 函数 ) 二、函数参数及返回值1. 传递原始类型参数2. 传递对象类型参数3. 函数返回值4. 箭头函数5. arguments对象 三、函数的调用1. 调用方式2. 标签函数(ES6新增)(1)如何调用标签函数(2)原始字符串 结尾一、函数
函数也是一种对象,也是一种引用类型,函数的( )
内是参数,[ ]
内部代表可以省略的部分。
1. 函数定义
(1)函数声明
function 函数名([参数]){语句...}
(2)函数表达式
const 变量名 = function([参数]){语句...}
(3)箭头函数
([参数]) => {语句...}
箭头函数也可以类似于(2),用变量来接收函数返回值
2. 方法( 对象 + 函数 )
对象内可以定义属性,当某一个属性值不是简单的原始类型等,而是一个函数时,此时的函数可以称为对象的方法。
其中,sayHello()就是一个方法,可以通过 对象.方法名() ,对方法进行调用
let obj = {name:"张三", sayHello(){alert("你好,我是张三");}}obj.sayHello();
二、函数参数及返回值
函数声明时的参数为形参(形式参数),函数调用时的参数为实参(实际参数)。
ECMAScript中的所有参数都是按值传递的,不可能按引用传递参数。如果把对象作为参数传递,那么传递的值就是这个对象的引用。。
1. 传递原始类型参数
函数中的形式参数,在没有接受实参的赋值时,相当于对于每次调用此函数时,都会对重新声明形参变量。因此函数内部,也不能使用 let 或 const 对形参再次声明。
形参和实参个数相同时,实参一一对应赋值给形参 形参个数大于实参个数时,未被赋值的形参的值为undefined 形参个数小于实参个数时,多余的实参无意义,不被传递给形参
// 函数声明function sum(a, b) {console.log(a + b);}sum(20, 30); // 相当于在调用函数的同时,a=20,b=50
可以为形参设置初值(ES6)
// 函数声明function sum(a, b=5) {console.log(a + b);}sum(20); // 由于未给b没有实参,故b使用默认值sum(20,20); // 如果已经赋值,会使b=20,不再使用默认值
2. 传递对象类型参数
如果形参是对象,调用函数传递实参后,形参和实参会指向同一个变量
let obj = {name:'张三'};function test(o){alert(o.name) // 输出'张三'o.name = '李四'; alert(o.name) // 输出'李四'}alert(obj.name) //输出'李四'
因为o=obj,o.name修改时,obj对象的name也被修改
3. 函数返回值
使用 return 来接收函数的返回值
// 函数声明function sum(a, b) {return a + b;}// 相当于在调用函数的同时,a=20,b=50let result = sum(20, 30); //后续可以使用函数的返回值进行其它操作console.log(result);
函数也可以作为参数
// 接此部分上方代码let result2 = sum(sum(20,30),50);console.log(result2); // 结果为100
4. 箭头函数
(1)此时,add
并不是 接收箭头函数返回值的变量 ,而是表示 整个箭头函数
const add = (a, b) =>{return a + b;}// 输出箭头函数console.log(add);// 输出调用箭头函数后的返回值console.log(add(10,20));
输出结果,如下图所示:
(2)如果箭头函数形参只有一个,可以省略()
// 省略括号const test1 = a => {alert(a)}test1(5)// 不省略括号const test2 = (a) => {alert(a)}test2(10)
(3)箭头函数返回值可以省略return;且,若{ }
内部 只有一行代码,可以省略{}
。
const test = (a, b) => a + b;console.log(test(10, 20));// 30
若对象字面量作为返回值时,想要省略return时,需要为返回字面量加上()
const test = () => ({name: "王五" });console.log(test()); // { name: "王五" }console.log(test().name); // '王五'
5. arguments对象
ES6中可以用...
运算符和变量名来代替此对象;箭头函数没有arguments
对象。
(1)在function
定义的 (非箭头)函数时,可以在函数内部访问arguments
对象,从中获取传进来的每个参数值。(2)arguments
对象是一个类数组对象,但不是Array的实例,可以使用数组中括号方式访问其中的元素。(3)函数声明时,可以不定义形参;但是调用函数时传入实参后,也可通过arguments
访问参数(4)arguments
对象可以和命名参数同时使用,arguments
对象的length
值与传入参数个数有关,与定义参数个数无关
function sayHello() {// 可以使用模板字符串插值console.log(`Hello,I'm ${arguments[0]}!`);// 可以使用普通字符串拼接console.log("I'm " + arguments[1] + " years old.");}sayHello("Jack", 19);
function sum(a, b, c) {// 值同步console.log(a); // 5console.log(arguments[0]); // 5// 修改第二个参数值arguments[1] = 100;console.log(b); // b的值也被修改为100// 试图通过arguments对象,为c赋值arguments[2] = 20;console.log(c); // undefinedconsole.log(arguments[2]); // 20}sum(5, 10);
注:arguments
对象的值,始终与对应的命名参数同步。但是不可以通过修改arguments,来为未在调用时传入的命名参数赋值。
三、函数的调用
1. 调用方式
不考虑传参情况时:
(1)函数名()
(2)函数名.call(调用对象)
(3)函数名.apply(调用对象)
(4)new 函数名()
(5)对象.方法()
2. 标签函数(ES6新增)
(1)如何调用标签函数
通常,以函数名作为模板字面量前缀,来应用自定义行为。
let a = 6,b = 9;// 参数分别为模板字符串数组 和 可变个数的表达式function simpleTag(strings, ...expressions) {console.log(strings); for (let expression of expressions) {console.log(expression);}return "test";}// 定义普通模板字符串let untaggedResult = `${a}+${b}=${a + b}`;console.log(untaggedResult); // 6+9=15// 定义标签函数let taggedResult = simpleTag`${a}+${b}=${a + b}`;// ['', '+', '=', '', raw: Array(4)]// 6// 9// 15console.log(taggedResult); // test
代码运行效果,如下所示:
注:若模板字符串有n
个插值(${}
),则标签函数的参数个数一定为n+1
个,第一个为模板字符串数组,后面n
个参数为传入的值或者表达式计算得到的值;标签函数的返回值为原函数的返回值
(2)原始字符串
使用String.raw
标签函数,可以直接获取原始的模板字面量。
console.log(`\u00A9`); // ©console.log(String.raw`\u00A9`); // \u00A9
结尾
部分内容参考《ECMAScript 6 入门》《JavaScript权威指南》《JavaScript高级程序设计》,如有错误,欢迎评论区指正。