JavaScript 函数

函数参数

  • arguments(可变参):伪数组(有 index 和 length),存的传入的参数,可以用for 遍历
  • js函数可变参的写法function test(a,b,...rest),rest的本质也就是一个数组
  • 函数可变参(rest参数)实际是es6的新标准,es6还支持参数默认值的设置
  • 函数的参数在声明的时候写不写都可以,写多少个也没有规定,底层是用数组实现的,函数声明的括号里写上形参只是为了函数内部使用的方便;函数在调用的时候要传几个实参都是可以的,反正是传几个接受几个;
  • 由于 js 函数参数的以上特点,所以 js 的函数没有真正意义上的重载,同名的函数会覆盖
  • 函数传参:参数的改变在函数之外是不可见的,对象属性的改变在函数之外是可见的
    在这里插入图片描述
  • 函数声明随意写在什么位置都不影响函数的调用,但是函数表达式必须写在调用之前才不会出错;
//函数表达式
var run = function (v1) {
  alert(v1);
};
//函数声明
function run() {}

函数闭包

函数嵌套

匿名函数

  • 作为其他函数的参数和返回值
  • 作为立即执行函数使用:前面的括号的包裹不可或缺
(function () {
    var x = "Hello!!";
})();

闭包概念

  • 子函数有权访问父作用域的函数,即使在父函数关闭之后,闭包最大的作用是将变量私有
var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();

递归函数


解构赋值

  • 也是ES6的一个特性

一、数组解构

在这里插入图片描述

二、对象解构

  • 下面的代码 address 无法解构,里面的city等可以解构
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, zipcode}} = person;

三、使用场景

  • 解构赋值在很多时候可以大大简化代码,比如两个值的交换
    在这里插入图片描述
  • 方法参数的自动匹配,前提是方法参数接受一个对象
    在这里插入图片描述

对象方法

  • 对象的属性是一个函数

一、关于关键词this

  • this 在对象内部指的就是对象本身
var xiaoming = {
    name: '小明',
    birth: 1990,
    age: function () {
        var y = new Date().getFullYear();
        return y - this.birth;
    }
};
  • 函数中嵌套函数的情况:最外层的函数可以直接使用this,这里的this是指向的对象本身,里层的函数要使用this的话需要通过that进行访问,否则的话实际访问就是window对象,使用严格的模式的话就是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();
    }
};

二、apply 和 call

  • 可以通过函数本身的 apply 和 call 方法指定函数内部的 this 的指向
    在这里插入图片描述
  • apply的方法参数是包装为array传入的,call的参数是直接按位置进行匹配
Math.max.apply(null,[12,34,100,2,5])
100

Math.max.call(null,12,45,100,56,45)
100
  • call和apply一个很大的作用就是实现函数的复用:p1.fullName.apply(p2)

三、简单装饰器的实现

  • 这里实现的方法调用次数的计数功能增强,好像没啥用~~~~
'use strict';

var count = 0;
var oldParseInt = parseInt; // 保存原函数

window.parseInt = function () {
    count += 1;
    return oldParseInt.apply(null, arguments); // 调用原函数
};

高阶函数

  • 高阶函数就是函数作为参数或者返回值的函数

一、map/reduce

  • map函数就是把传入的参数函数作用于数组的每一个元素,然后返回
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);
  • reduce就是一个累积的效果,第一个参数表示上次计算结果,第二参数表示数组的下一个元素
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
    return x + y;
}); // 25
  • map和parseInt一起使用的陷阱?????

二、filter

var arr = ['A', 'B', 'C'];
var r = arr.filter(function (value, index, array) {
    console.log(value);
    console.log(index); 
    console.log(array);
    return true;
});

三、sort

  • sort 方法排序数字要有一个比较函数
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]

四、数组的其他高阶函数

  • every:判断数组中是否所有的元素都满足条件
  • find:找数组中满足条件的第一个元素,返回元素,没找到返回undefined
  • findindex :找数组中满足条件的第一个元素,返回索引,没找到返回-1
  • forEach: 用来遍历数组不会像map一样返回一个数组

箭头函数

  • 就是类似于 python 中 lambda 函数的东西,就是实现一个匿名函数
  • 也是ES6中引入的新东西,为JS提供了函数式编程的支持
  • 简化了函数的定义过程

一、基本用法

  • 最简单的写法
x => x * x
  • 最完整的写法:也就是说如果参数只有一个,函数体的代码只有一句的话,小括号和大括号都是可以省略的
(x, y, ...rest) => {
    var i, sum = x + y;
    for (i=0; i<rest.length; i++) {
        sum += rest[i];
    }
    return sum;
}
  • 如果返回的是一个对象
x => ({ foo: x })

二、箭头函数中的this

  • 示例代码中的this完全可以正常使用了
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

三、使用细节

  • 箭头功能没有自己的 this,它们不适合定义对象方法
  • 箭头功能未被提升,它们必须在使用前进行定义
  • 使用 const 比使用 var 更安全,因为函数表达式始终是常量值
const test12 = function(){console.log('test')}

generator

  • 这个东西也是ES6中引入的,设计者借鉴了python中 generator 的思路设计了这个

一、基本概念

  • 定义的方法就是在函数定义的基础上加上 *作为标记,函数体的内部用 yield 关键字进行值的返回
  • 从测试的代码可以看出,generator 的本质就是一个函数,不过是一个比较特殊的函数而已
  • 调用这个特殊的方法得到的并不是返回的值而是一个generator对象,返回值需要继续调用 next 方法
  • next 方法返回一个 object ,这个对象包含两个属性,done是判断这个generator 是否执行结束,true代表结束返回的value的值就是return的值,false 代表未执行结束,返回的value就是yield 返回的值
    在这里插入图片描述
  • 用 next 对 generator 进行取值要判断是否执行结束,用for--of进行取值的话就不需要
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, ...
}

generator 最大的优势就是可以保存变量的状态,普通函数需要依赖全局变量或者是对象的属性才能实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值