zoukankan      html  css  js  c++  java
  • 【JavaScript】函数

    No1:

    定义函数

    function abs(x) {
        if (x >= 0) {
            return x;
        } else {
            return -x;
        }
    }
    var abs = function (x) {
        if (x >= 0) {
            return x;
        } else {
            return -x;
        }
    };

    由于JavaScript允许传入任意个参数而不影响调用,因此传入的参数比定义的参数多也没有问题,虽然函数内部并不需要这些参数:

    abs(10, 'blablabla'); // 返回10
    abs(-9, 'haha', 'hehe', null); // 返回9

    传入的参数比定义的少也没有问题:

    abs(); // 返回NaN

    No2:

    【arguments】

    它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数

    function foo(x) {
        console.log('x = ' + x); // 10
        for (var i=0; i<arguments.length; i++) {
            console.log('arg ' + i + ' = ' + arguments[i]); // 10, 20, 30
        }
    }
    foo(10, 20, 30, 40);

    运行结果

    x = 10
    arg 0 = 10
    arg 1 = 20
    arg 2 = 30
    arg 3 = 40

     【rest】额外的参数

    function foo(a, b, ...rest) {
        console.log('a = ' + a);
        console.log('b = ' + b);
        console.log(rest);
    }
    
    foo(1, 2, 3, 4, 5);
    // 结果:
    // a = 1
    // b = 2
    // Array [ 3, 4, 5 ]
    
    foo(1);
    // 结果:
    // a = 1
    // b = undefined
    // Array []

    No3:

    JavaScript引擎在行末自动添加分号的机制

    No4:

    avaScript的函数在查找变量时从自身函数定义开始,从“内”向“外”查找。如果内部函数定义了与外部函数重名的变量,则内部函数的变量将“屏蔽”外部函数的变量

    function foo() {
        var x = 1;
        function bar() {
            var x = 'A';
            console.log('x in bar() = ' + x); // 'A'
        }
        console.log('x in foo() = ' + x); // 1
        bar();
    }
    
    foo();

    运行结果

    x in foo() = 1
    x in bar() = A

    No5:

    【变量提升】

    JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部:

    function foo() {
        var x = 'Hello, ' + y;
        console.log(x);
        var y = 'Bob';
    }
    -------------相当于
    function foo() {
        var y; // 提升变量y的申明,此时y为undefined
        var x = 'Hello, ' + y;
        console.log(x);
        y = 'Bob';
    }

    No6:

    【let】

    JavaScript的变量作用域实际上是函数内部,我们在for循环等语句块中是无法定义具有局部作用域的变量的

    function foo() {
        for (var i=0; i<100; i++) {
            //
        }
        i += 100; // 仍然可以引用变量i
    }
    -----------------修改为
    function foo() {
        var sum = 0;
        for (let i=0; i<100; i++) {
            sum += i;
        }
        // SyntaxError:
        i += 1;
    }

    No7:

    【const】表示常量

    No8:

    【解构赋值】

    var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
    --------
    let [x, [y, z]] = ['hello', ['JavaScript', 'ES6']];
    --------
    let [, , z] = ['hello', 'JavaScript', 'ES6'];
    --------
    var person = {
        name: '小明',
        age: 20,
        gender: 'male',
        passport: 'G-12345678',
        school: 'No.4 middle school'
    };
    var {name, age, passport} = person;
    --------
    var person = {
        name: '小明',
        age: 20,
        gender: 'male',
        passport: 'G-12345678',
        school: 'No.4 middle school',
        address: {
            city: 'Beijing',
            street: 'No.1 Road',
            zipcode: '100001'
        }
    };
    var {name, address: {city, zip}} = person;
    name; // '小明'
    city; // 'Beijing'
    zip; // undefined, 因为属性名是zipcode而不是zip
    // 注意: address不是变量,而是为了让city和zip获得嵌套的address对象的属性:
    address; // Uncaught ReferenceError: address is not defined
    --------
    var person = {
        name: '小明',
        age: 20,
        gender: 'male',
        passport: 'G-12345678',
        school: 'No.4 middle school'
    };
    
    // 把passport属性赋值给变量id:
    let {name, passport:id} = person;
    name; // '小明'
    id; // 'G-12345678'
    // 注意: passport不是变量,而是为了让变量id获得passport属性:
    passport; // Uncaught ReferenceError: passport is not defined
    --------
    var person = {
        name: '小明',
        age: 20,
        gender: 'male',
        passport: 'G-12345678'
    };
    
    // 如果person对象没有single属性,默认赋值为true:
    var {name, single=true} = person;
    name; // '小明'
    single; // true
    --------
    ({x, y} = { name: '小明', x: 100, y: 200});
    --------
    var x=1, y=2;
    [x, y] = [y, x]

    No9:

    【方法】

    var xiaoming = {
        name: '小明',
        birth: 1990,
        age: function () {
            var y = new Date().getFullYear();
            return y - this.birth;
        }
    };

    strict模式下让函数的this指向undefined,所以上面改为

    var xiaoming = {
        name: '小明',
        birth: 1990,
        age: function () {
            var that = this; // 在方法内部一开始就捕获this
            function getAgeFromBirth() {
                var y = new Date().getFullYear();
                return y - that.birth; // 用that而不是this
            }
            return getAgeFromBirth();
        }
    };

    感觉真是吃饱了撑的

    更新:优化如下

    var obj = {
        birth: 1990,
        getAge: function () {
            var b = this.birth; // 1990
            var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
            return fn();
        }
    };
    obj.getAge(); // 25

    No10:

    【高阶函数】

    function add(x, y, f) {
        return f(x) + f(y);
    }

    由于map()方法定义在JavaScript的Array中,我们调用Arraymap()方法,传入我们自己的函数,就得到了一个新的Array作为结果

    function pow(x) {
        return x * x;
    }
    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    var results = arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
    console.log(results);

    运行结果

    1,4,9,16,25,36,49,64,81

    No11:

    【reduce】

    [x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
    var arr = [1, 3, 5, 7, 9];
    arr.reduce(function (x, y) {
        return x + y;
    }); // 25

    No12:

    【filter】

    var arr = [1, 2, 4, 5, 6, 9, 10, 15];
    var r = arr.filter(function (x) {
        return x % 2 !== 0;
    });
    r; // [1, 5, 9, 15]

    去除Array的重复元素

    var
        r,
        arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
    r = arr.filter(function (element, index, self) {
        return self.indexOf(element) === index;
    });
    console.log(r.toString());

    No13:

    【sort】

    Arraysort()方法默认把所有元素先转换为String再排序

    数字大小排序

    var arr = [10, 20, 1, 2];
    arr.sort(function (x, y) {
        if (x < y) {
            return -1;
        }
        if (x > y) {
            return 1;
        }
        return 0;
    });
    console.log(arr); // [1, 2, 10, 20]

    sort()方法会直接对Array进行修改,它返回的结果仍是当前Array

    var a1 = ['B', 'A', 'C'];
    var a2 = a1.sort();
    a1; // ['A', 'B', 'C']
    a2; // ['A', 'B', 'C']
    a1 === a2; // true, a1和a2是同一对象

    No14:

    【函数作为返回值】

    function lazy_sum(arr) {
        var sum = function () {
            return arr.reduce(function (x, y) {
                return x + y;
            });
        }
        return sum;
    }
    
    var f = lazy_sum([1, 2, 3, 4, 5]); 
    
    f(); // 15

    No15:

    匿名函数并立刻执行

    (function (x) { return x * x }) (3);

    常用函数

    function make_pow(n) {
        return function (x) {
            return Math.pow(x, n);
        }
    }
    
    // 创建两个新函数:
    var pow2 = make_pow(2);
    var pow3 = make_pow(3);
    
    console.log(pow2(5)); // 25
    console.log(pow3(7)); // 343

    No16:

    【箭头函数】

    x => x * x
    相当于
    function (x) {
        return x * x;
    }

    箭头函数相当于匿名函数,并且简化了函数定义

    x => {
        if (x > 0) {
            return x * x;
        }
        else {
            return - x * x;
        }
    }
    // 两个参数:
    (x, y) => x * x + y * y
    
    // 无参数:
    () => 3.14
    
    // 可变参数:
    (x, y, ...rest) => {
        var i, sum = x + y;
        for (i=0; i<rest.length; i++) {
            sum += rest[i];
        }
        return sum;
    }
    x => ({ foo: x })

    No17:

    【generator】

    generator由function*定义(注意多出的*号),并且,除了return语句,还可以用yield返回多次

    function* foo(x) {
        yield x + 1;
        yield x + 2;
        return x + 3;
    }

    斐波那契

    function* fib(max) {
        var
            t,
            a = 0,
            b = 1,
            n = 0;
        while (n < max) {
            yield a;
            [a, b] = [b, a + b];
            n ++;
        }
        return;
    }

    调用

    for (var x of fib(10)) {
        console.log(x); // 依次输出0, 1, 1, 2, 3, ...
    }

    学到这里,我感觉js有些知识点还是挺难理解的,不管怎样,先硬着头皮学吧

  • 相关阅读:
    mysql access denied for user root Mysql用户无权限
    远程链接调用sql脚本
    CuteEditor使用详解
    如何设置release模式
    ShardingJDBC不分库,只分表例子
    SpringCloud Stream整合RocketMQ实现消息发送与接收
    Spring Cloud Gateway的PrefixPath及StripPrefix功能
    使用MongoDB的Spring Boot和MongoTemplate教程
    ShardingJDBC读写分离案例
    SpringBoot那些好用的连接池HikariCP
  • 原文地址:https://www.cnblogs.com/anni-qianqian/p/9296030.html
Copyright © 2011-2022 走看看