JavaScript学习之函数

Posted rissa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript学习之函数相关的知识,希望对你有一定的参考价值。

描述

在JavaScript中,每个函数其实都是一个Function对象。如果一个函数中没有使用return语句,则它默认返回undefined。要想返回一个特定的值,则函数必须使用return语句来指定一个要返回的值。

调用函数时,传递给函数的值被称为函数的实参(值传递),对应位置的函数参数名叫作形参。

在函数执行时,this关键字并不会指向正在运行的函数本身,而是指向调用该函数的对象。

函数定义

  • 函数声明
    【语法】
    function funcName([param[, param[, ... param]]]) { 
        statements 
    }

    funcName:函数名称
    param:传递给函数的参数
    statements:构成函数体的语句
    【注意】  
    JavaScript 中的函数声明被提升到了函数定义。可以在函数声明之前使用该函数。

  • 函数表达式
    【语法】
    var funcExp = function [name]([param[, param[, ... param]]]){
        statements
    }

    name:函数名称,被省略,省略后改函数为匿名函数。 函数名称只是函数体中的一个本地变量。
    param:传递给函数的参数
    statements:构成函数体的语句
    【注意】
    函数表达式不存在函数提升,定义函数表达式之前不能使用函数表达式。
    被函数表达式赋值的那个变量会有一个name属性,如果你把这个变量赋值给另一个变量的话,这个name属性的值也不会改变。如果函数是一个匿名函数,那name属性的值就是被赋值的变量的名称(隐藏值);如果函数不是匿名的话,那name属性的值就是这个函数的名称(显性值)

    var funcExp1 = function exp1(){
        console.log("11111");
    }
    var funcExp2 = function(){
        console.log("22222");
    }
    console.log(funcExp1.name);     // exp1
    console.log(funcExp2.name);     // funcExp2
  • 函数生成器声明

    【语法】

    function* funcName([param[, param[, ... param]]]) { 
        statements 
    }

    【描述】
    function*这种声明方式(function关键字后跟一个星号)会定义一个生成器函数 (generator function),它返回一个 Generator对象。

    生成器函数能在执行时暂停,后面又能从暂停处继续执行。

    调用一个生成器函数并不会马上执行它里面的语句,而是返回一个这个生成器的迭代对象,当这个迭代器的 next()方法被首次(后续)调用时,其内的语句会执行到第一个(后续)出现yield的位置为止,yield 后紧跟迭代器要返回的值。或者如果用的是yield*(多了个星号),则表示将执行权移交给另一个生成器函数(当前生成器暂停执行)

    next()
    方法返回一个对象,这个对象包含两个属性:value 和 done,value 属性表示本次 yield 表达式的返回值,done 属性为布尔类型,表示生成器后续是否还有 yield 语句,即生成器函数是否已经执行完毕并返回。


    【函数声明简单示例】

    function* testDemo(i) {
        yield i;
        yield i + 10;
        yield i + 20;
    }
    let res = testDemo(10);
    console.log(res.next());    // { value: 10, done: false }
    console.log(res.next());    // { value: 20, done: false }
    console.log(res.next());    // { value: 30, done: false }
    console.log(res.next());    // { value: undefined, done: true }

    【生成器函数接收参数】

    function* idMaker(){
        var index = arguments[0] || 0;
        while(true)
            yield index++;
    }
    
    var gen = idMaker(5);
    console.log(gen.next().value); // 5
    console.log(gen.next().value); // 6

    【传递参数】
      调用 next()方法时,如果传入了参数,那么这个参数会传给上一条执行的 yield语句左边的变量

    function *createIterator() {
        let first = yield 1;
        let second = yield first + 2; // 4 + 2
                                      // first =4 是next(4)将参数赋给上一条的
        yield second + 3;             // 5 + 3
    }
    
    let iterator = createIterator();
    
    console.log(iterator.next());    // "{ value: 1, done: false }"
    console.log(iterator.next(4));   // "{ value: 6, done: false }"
    console.log(iterator.next(5));   // "{ value: 8, done: false }"
    console.log(iterator.next());    // "{ value: undefined, done: true }"

    【yield*使用】

    function* anGenerator(i) {
        yield i + 1;
        yield i + 2;
        yield i + 3;
    }
    
    function* generator(i) {
        yield i;
        yield* anGenerator(i); 
        yield i + 10;
    }
    
    let gen = generator(10);
    
    console.log(gen.next().value); // 10
    console.log(gen.next().value); // 11
    console.log(gen.next().value); // 12
    console.log(gen.next().value); // 13
    console.log(gen.next().value); // 20

    【return显示返回】
    当在生成器函数中显式 return时,会导致生成器立即变为完成状态,即调用 next() 方法返回的对象的 done为 true。如果 return后面跟了一个值,那么这个值会作为当前调用 next() 方法返回的 value 值。

    function* testDemo2(i) {
        yield i;
        yield i + 10;
        return i;
        yield i + 20;   // 不会被执行了
    }
    let res2 = testDemo2(10);
    console.log(res.next());    // { value: 10, done: false }
    console.log(res.next());    // { value: 20, done: false }
    console.log(res.next());    // { value: 10, done: true }
    console.log(res.next());    // { value: undefined, done: true }
  • 函数生成器表达式
    【语法】
    var funcExp = function* [name]([param] [, param] [..., param]) {         
                statements 
    }

    【示例】

    let foo = function* () {
        yield \'a\';
        yield \'b\';
        yield \'c\';
    };
    
    console.log(foo().next());  //{ value: \'a\', done: false }
    
    let str = \'\';
    for (const val of foo()) {
        str = str + val;
    }
    console.log(str);   // abc
  • 箭头函数表达式

    箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
    【基础语法】

    (param1, param2, …, paramN) => { statements }
    (param1, param2, …, paramN) => expression
    //相当于:(param1, param2, …, paramN) =>{ return expression; }
    
    // 当只有一个参数时,圆括号是可选的:
    (singleParam) => { statements }
    singleParam => { statements }
    
    // 没有参数的函数应该写成一对圆括号。
    () => { statements }
    【高级语法】
    //加括号的函数体返回对象字面量表达式:
    params => ({foo: bar})
    
    //支持剩余参数和默认参数
    (param1, param2, ...rest) => { statements }
    (param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
    statements }
    
    //同样支持参数列表解构
    let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
    f();  // 6
  • Function构造函数
    【语法】
    new Function ([arg1[, arg2[, ...argN]],] functionBody)

    arg1, arg2, ... argN:被函数使用的参数的名称必须是合法命名的。
    functionBody:一个含有包括函数定义的 JavaScript 语句的字符串。
    【简单示例】

    let adder = new Function("a", "b", "return a + b");
    console.log(adder(2, 6));   // 8
  • 生成器函数的构造函数
    【语法】

    new GeneratorFunction ([arg1[, arg2[, ...argN]],] functionBody)

    【简单示例】

    var GeneratorFunction = Object.getPrototypeOf(function*(){}).constructor
    var g = new GeneratorFunction("a", "yield a * 2");
    var iterator = g(10);
    console.log(iterator.next().value); // 20

以上是关于JavaScript学习之函数的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript入门学习之二——函数

javascript设计模式学习之二——this

Javascript学习之Map和Filter函数实现方法详解

Python面向对象学习之八,装饰器

Javascript学习之数组详解

机器学习之Javascript篇::遗传算法介绍