关于JavaScript的函数总结
function sum(num){ return num + 100 } function sum(num){ return num + 200 } let totle = sum(100) console.log(totle,'totle') // 300 "totle" 在 ECMAScript 中定义了两个同名函数,则后定义的会覆盖先定义的 var test = function(){ console.log(111) } function test(){ console.log(222) } test() // 111 // 只要在函数定义中的参数后面用=就可以为参数赋一个默认值 function getName(name = 'bob'){ return name } console.log(getName()) // bob // 收集参数的前面如果还有命名参数,则只会收集其余的参数;如果没有则会得到空数组。因为收集 // 参数的结果可变,所以只能把它作为最后一个参数, 箭头函数虽然不支持 arguments 对象,但支持收集参数的定义方式 // 不可以 // function fn(...values, lastValue) { // } // 可以 function fn(firstValue, ...values) { console.log(values); } // 函数声明与函数表达式 // JavaScript 引擎在任何代码执行之前,会先读取函数声明,并在执行上下文中 // 生成函数定义。而函数表达式必须等到代码执行到它那一行,才会在执行上下文中生成函数定义 // 函数声明会在任何代码执行之前先被读取并添加到执行上下文。这个过程叫作函数声明提升 // 没问题 console.log(sum(10, 10)); function sum(num1, num2) { return num1 + num2; } // 会出错 console.log(sum(10, 10)); let sum = function(num1, num2) { return num1 + num2; }; // 在 ECMAScript 5 中,函数内部存在两个特殊的对象:arguments 和 this。ECMAScript 6 又新增了 new.target 属性 // 如果函数是正常调用的,则 new.target 的值是 undefined;如果是使用 new 关键字调用的,则 new.target 将引用被调用的构造函数 // arguments 它是一个类数组对象,包含调用函数时传入的所有参数 // 在标准函数中,this 引用的是把函数当成方法调用的上下文对象,这时候通常称其为 this 值(在网页的全局上下文中调用函数时,this 指向 windows)。 // 在箭头函数中,this引用的是定义箭头函数的上下文。 // 在 【事件回调】 或 【定时回调】中调用某个函数时,this 值指向的可能并非想要的对象。此时将回调函数写成箭头函数就可以解决问题 // 箭头函数不能使用 arguments、super 和 new.target,也不能用作构造函数。此外,箭头函数也没有 prototype 属性 /* 函数还有两个方法:apply()和 call()。这两个方法都会以指定的 this 值来调用函数,即会设 置调用函数时函数体内 this 对象的值。apply()方法接收两个参数:函数内 this 的值和一个参数数 组。第二个参数可以是 Array 的实例,但也可以是 arguments 对象 */ function sum(num1, num2) { return num1 + num2; } function applySum1(num1, num2) { return sum.apply(this, arguments); // 传入 arguments 对象 } function applySum2(num1, num2) { return sum.apply(this, [num1, num2]); // 传入数组 } console.log(applySum1(10, 10)); // 20 console.log(applySum2(10, 10)); // 20 // 如果使用 call call()方法与 apply()的作用一样,只是传参的形式不同 function sum(num1, num2) { return num1 + num2; } function callSum(num1, num2) { return sum.call(this, num1, num2); } call()方法与 apply()的作用一样,只是传参的形式不同 console.log(callSum(10, 10)); // 20 // bind()方法会创建一个新的函数实例,其 this 值会被绑定到传给 bind()的对象 window.color = 'red'; var o = { color: 'blue' }; function sayColor() { console.log(this.color); } let objectSayColor = sayColor.bind(o); objectSayColor(); // blue // 递归函数通常的形式是一个函数通过名称调用自己 // 递归需要一个 边界条件来打断递归。要不然的话会进入死循环 // 递归调用 求1-100的和 function sum(num) { if(num === 1){ return 1 } return sum(num - 1) + num } sum(100); // 5050 // 立即调用的匿名函数又被称作立即调用的函数表达式 // IIFE (function () { for (var i = 0; i < count; i++) { console.log(i); } })(); // ECMAScript 5.1 及以前,为了防止变量定义外泄,IIFE 是个非常有效的方式 console.log(i); // 抛出错误 // 在 ECMAScript 6 以后,IIFE 就没有那么必要了,因为块级作用域中的变量无须 IIFE 就可以实现同样的隔离 // 内嵌块级作用域 { let i; for (i = 0; i < count; i++) { console.log(i); } } console.log(i); // 抛出错误 // 循环的块级作用域 for (let i = 0; i < count; i++) { console.log(i); } console.log(i); // 抛出错误 // 通常,函数作用域及其中的所有变量在函数执行完毕后都会被销毁。 // 闭包在被函数返回之后,其作用域会一直保存在内存中,直到闭包被销毁。 // 立即调用的函数表达式如果不在包含作用域中将返回值赋给一个变量,则其包含的所有变量都会被销毁 // 任何函数只要使用 new 操作符调用就是构造函数,而不使用 new 操作符调用的函数就是普通函数 // 异步函数 实现 sleep 函数 Promise + setTimeout async function sleep(delay) { return new Promise((resolve) => setTimeout(resolve, delay)); } async function foo() { const t0 = Date.now(); await sleep(1500); // 暂停约 1500 毫秒 console.log(Date.now() - t0); } foo();