A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

JavaScript 函数的组成,函数的递归、立即执行函数、call/appaly/bind、caller/callee
函数的意义
  • 数学中的函数
    <span class="MathJax" id="MathJax-Element-1-Frame" tabindex="0" data-mathml="y=f(x)" role="presentation" style="box-sizing: border-box; display: inline; line-height: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; position: relative;">y=f(x)y=f(x),对于一个 x 变量有唯一一个 y 与之对应
  • 编程中的函数
    即函数式编程 -> 模块的单一责任制
    一个功能或程序段被封装的过程
    好处:低耦合,高类聚,易复用
    var test = function(){    // ...     return;}
  • JavaScript 函数的组成
    函数名、参数、返回值

函数的声明
  • 声明方式
    // 第一种,一般声明式funtion test1(){}// 第二种,函数字面量赋值式var test2 = function(){}
    注意:
    var test = function test1(){    // ...    test1()// 内部可调用}console.log(test.name); // 打印出 test1test(); // 可以执行test1(); // 外部不可见,报错
  • 函数命名
    • 以字母、$、下划线开头,可包含数字
    • 小驼峰命名,myTestFunction
    • 工具方法可以使用下划线连接多单词

函数的参数
  • 形式参数
    // 未传入的形式参数,默认 undefinedfunction test(a, b, c) { console.log(a, b, c);}test(1,2); // 1 2 undefined
  • 实际参数
    通过 arguments 可以获取传入的实际参数数组
    function test(a, b) {    console.log(arguments.length); // 3    console.log(arguments); // [1,2,3]}test(1,2,3);
    在函数内部可以更改实际参数数组的内容
    function test(a, b) {a = 10; // 可以更改b = 11; // 不能更改,没有传入该参数,默认 undefinedconsole.log(arguments[0]); // 10console.log(arguments[1]); // undefined}test(1);
    arguments 是数组,存在堆内存中
    形式参数和 arguments 成员是具有映射关系的
  • 参数默认值
    // es6 语法// es2015 支持,不兼容低版本浏览器function test(a = 1, b = 2) {    console.log(a,b);}test(); // 打印 1 2,相当于 test(undefined,undefined)test(NaN); // 打印 NaN,2// es5 语法function test(a, b) {    var a = arguments[0] === undefined || 1;    var b = arguments[0] === undefined || 2;    console.log(a,b);}test(); // 打印 1 2,相当于 test(undefined,undefined)test(NaN); // 打印 NaN,2
函数的返回值
终止函数执行,返回一个值
  • 不写 return,默认返回 undefined
    // 默认 return undefined 即 retuen;function test(){    // ...}console.log(test); // undefined
  • 可以返回任何值
    return 1;return false;// 返回数组return [1,2,3];// 返回方法return funtion(){}
全局变量
  • 函数体内部可以访问外部声明的变量
    var a = 1; // 全局变量function test1() { var b = 2; // 局部变量 console.log(a); // 1 funtion test2() {     var c = 3; // 局部变量     console.log(b); // 2 } test2(); console.log(c); // 报错}test1();
  • 同级函数内部的局部变量不能相互访问
    function test1() {    var a = 1;}function test2() {    console.log(a);}test2(); // 报错
函数的递归
  • 递归算法
    大问题可以划分小问题
    大问题与小问题解决思路一致
    写出递推公式
    找出终止条件
    实现递归代码
  • 递归示例
    求 n 的阶层
    function fact(n) {    return n === 0 || n === 1 ? 1 : n * fact(n - 1);}
```
斐波那契数列
function fb(n) {    n <= 0 : return 0 :"";    n <= 2 : return 1 : "";    return fb(n - 1) + fb(n - 2);}立即执行函数
  • IIFE
    IIFE,immediately-invoked funtion,也叫自执行函数
  • 特点
    立即执行,自动销毁
  • 写法
    函数声明式 -> 表达式 -> () -> 执行
    常用写法
    (function(){})(); // 常用写法(function(){}()); // w3c 建议写法
    其他写法
    !function(){}();+function(){}();-function(){}();0 || function(){}();1 && funtion(){}()
    需要递归可以命名,但是外部访问不到
    (function test(){    test();})(); // 需要递归可以命名,但是外部访问不到test(); // 报错
    注意:
    function test(a) {    console.log(a);}(); // 报错function test(a) {    console.log(a);}(1); // 不报错,也不打印// 因为浏览器将 (1) 解析成表达式,前面解析成函数声明式
  • 返回值
    var test = (function() {    return 1; // 用外部变量接收})
call、apply 与 bind
改变函数的 this 指向
  • call
    function test() {}test(); // 浏览器隐式执行为 test.call()
    改变 this 指向
    function Car(color, price){    this.color = color;    this.price = price;}var myCar = {};Car.call(myCar, "black", "20 万");Car.apply(myCar, ["black", "20 万"]);console.log(myCar); // {color : "black", price : "20 万"}
  • apply
    function Car(color, price){    this.color = color;    this.price = price;}var myCar = {};Car.apply(myCar, ["black", "20 万"]); // 用数组装参数console.log(myCar); // {color : "black", price : "20 万"}
  • bind
    与 call、apply 不同的是,bind 改变指向后不会执行,可以加 () 执行
    function Car(color, price){    this.color = color;    this.price = price;}var myCar = {};Car.bind(myCar)("black", "20 万"); // 用数组装参数console.log(myCar); // {color : "black", price : "20 万"}
caller 和 callee
  • callee
    返回 arguments 对应的函数
    function test(a, b, c){    console.log(arguments.callee.length); // 函数有 length 属性,返回形参列表长度}test(1, 2, 3);
    自执行函数中使用递归
    // 计算 1 + 2 + ... + 100(function(n) {    if(n <= 1) {        return 1;    }    return n + arguments.callee(n - 1);})(100);
  • caller
    返回调用当前函数的函数
    function test1() {    test2();}function test2() { console.log(test2.caller);}test1(); // 打印出 test1

作者: pgjett
出处: https://pgjett.cnblogs.com


1 个回复

倒序浏览
以上文章转载自网络
有问题联系学姐:DKA-2018
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马