JavaScript函数
函数定义
一个函数定义(也称为函数声明,或函数语句)由一系列的函数
关键字组成, 依次为:
- 函数的名称。
- 函数参数列表,包围在括号( )中并由逗号( , )区隔。
- 函数功能,包围在花括号{ }中,用于定义函数功能的一些JavaScript语句。
函数参数传递时,如果是传值则是传形参。如果是传对象,则是传引用(函数内部对对象的改变对外部是可见的)。
函数表达式
虽然上面的函数声明在语法上是一个语句,但函数也可以由函数表达式创建。这样的函数可以是匿名的;它不必有一个名称。例如,函数square
也可这样来定义:
函数表达式可以直接调用:
函数表达式就是把一个函数赋值给变量或者常量
什么时候使用函数表达式?什么时候使用命名方式的函数表达式?
- 当存在递归的时候,应该以命名函数表达式的方式定义函数
- 不存在递归时,习惯使用函数表达式
高阶函数
JavaScript的高阶函数的定义和Python是一样的,只是JavaScript函数的参数可以直接写上函数的实现部分,而Python最多可以写上一个lambda函数。
箭头函数
箭头函数表达式(也称胖箭头函数, fat arrow function)主要作用是是函数表达式更为简洁。
- 箭头函数总是匿名的
- 当箭头函数至少有一个参数时,可以省去小括号
- 当箭头函数只有一条语句时,可以省去大括号和return
函数参数
默认参数
可变参数
参数前加...
表示其是可变参数,可变参数在函数体内,表现为一个数组。
参数结构
而且不能对object做参数解构,因为JavaScript还不支持关键字参数。
JavaScript类
基本使用
- 使用class关键字定义类
- constructor方法是构造方法
- 使用new关键字创建对象,参数为constructor方法的参数
- 实例调用静态方法的时候需要通过constructor属性
代码:下面的代码会定一个点类Point
类表达式
和函数一样,类除了有上面的命名方式的定义之外,还可以有类表达式。
类表达式本质上就是把一个类赋值给一个变量。
类的继承
多继承-MixIn模式
JavaScript中子类的使用有两个原因:
用通俗的话举例子来理解接口继承和实现继承,下面有三个类,分别是:
- Person:人类
- Storage:数据存储类,拥有一个存储数据的方法save
- Validation:数据验证类,拥有一个验证数据的方法validate
代码
现在要定义一个职工类Employee ,那么这个职工类肯定是要继承自Person类的(难道你敢说职工不是人?),同时这个职工还需要有两个能力:一个是存储数据的能力,一个是验证数据的能力。那么就又需要继承自Storage类和Validation类。那么Employee 类从Person类继承就是接口继承,因为超类和子类的行为类似。Employee 类从Storage继承或者从Validation继承都是实现继承,因为超类只是将功能传递给子类。
如果我们想实现这样的一个Employee类,那么一个很自然的写法就是多继承,下面的这种写法虽然很自然,但是多数语言都是不支持的,因为多重继承的时候会出现继承冲突。关于多重继承的冲突举一个简单的例子:定义一个动物(类)既是狗(父类1)也是猫(父类2),两个父类都有“叫”这个方法。那么当我们调用“叫”这个方法时,它就不知道是狗叫还是猫叫了,这就是多重继承的冲突。
为了实现多继承,ES6中有自己独特的MinIn技术:将实现继承的类视作一个函数,输入是超类,输出是扩展该超类的子类
通过这样的MixIn技术给Person类混入了Storage类的save方法和Validation类的validate方法,成功的变相的实现了多继承。
下面再举一个例子
- Point类
- 可序列化类Serializable
- Point3D类:需要继承自Point类,然后还需要混入可序列化的功能
代码
Serializable 在语义上变成一种装饰,用来装饰Person类,即 Employee 是一种可序列化的 Person。这种MixIn的思想就是Python装饰器在JavaScript里面的应用了,只是JavaScript没有像Python一样用语法糖的形式来实现。
参考:
- MDN-函数
- MDN-类
- simple-mixins
- 月影大神-类的装饰器:ES6 中优雅的 mixin 式继承
- ECMAScript 6 Class
- ECMAScript 6入门