说明
入门
入门
例子
文档
核心
配置
链式调用
扩展
序列化
表达式
解析和评估
句法
表达式树
代数
定制
安全
数据类型
数字
大数字
分数
复数
矩阵
单位
参考
类
方法
常量
定制捆绑
命令行界面
历史
扩展 - Math.js文档 - 笔下光年
网站首页
扩展
使用 `import` 函数可以轻松地使用函数和变量扩展该库。 导入函数在 `mathjs` 实例上可用,可以使用 `create` 函数创建。 ```javascript import { create, all } from 'mathjs' const math = create(all) math.import(/* ... */) ``` 函数导入接受带有函数和变量的对象,或带有工厂函数的数组。 它具有以下语法: ```javascript math.import(functions: Object [, options: Object]) ``` Where: - `functions` 是包含要导入的函数和/或值的对象或数组。 import 支持常规值和函数、类型化函数(参见类[型化函数](#Typed functions)部分)和工厂函数(参见[工厂函数](#Factory functions)部分)。 数组仅在包含工厂函数时才适用。 - `options` 是带有选项的可选第二个参数。 可以使用以下选项: - `{boolean} override` If `true`, existing functions will be overwritten. The default value is `false`. - `{boolean} silent` If `true`, the function will not throw errors on duplicates or invalid types. Default value is `false`. - `{boolean}` wrap If `true`, the functions will be wrapped in a wrapper function which converts data types like Matrix to primitive data types like Array. The wrapper is needed when extending math.js with libraries which do not support the math.js data types. The default value is `false`. The following code example shows how to import a function and a value into math.js: ```javascript // define new functions and variables math.import({ myvalue: 42, hello: function (name) { return 'hello, ' + name + '!' } }) // defined functions can be used in both JavaScript as well as the parser math.myvalue * 2 // 84 math.hello('user') // 'hello, user!' const parser = math.parser() parser.evaluate('myvalue + 10') // 52 parser.evaluate('hello("user")') // 'hello, user!' ``` ### Import external libraries External libraries like [numbers.js](https://github.com/numbers/numbers.js "numbers.js") and [numeric.js](https://github.com/sloisel/numeric "numeric.js") can be imported as follows. The libraries must be installed using npm: ```javascript $ npm install numbers $ npm install numeric ``` The libraries can be easily imported into math.js using import. In order to convert math.js specific data types like `Matrix` to primitive types like `Array`, the imported functions can be wrapped by enabling `{wrap: true}`. ```javascript import { create, all } from 'mathjs' import * as numbers from 'numbers' import * as numeric from 'numeric' // create a mathjs instance and import the numbers.js and numeric.js libraries const math = create(all) math.import(numbers, {wrap: true, silent: true}) math.import(numeric, {wrap: true, silent: true}) // use functions from numbers.js math.fibonacci(7) // 13 math.evaluate('fibonacci(7)') // 13 // use functions from numeric.js math.evaluate('eig([1, 2; 4, 3])').lambda.x // [5, -1] ``` ### Typed functions Typed functions can be created using `math.typed`. A typed function is a function which does type checking on the input arguments. It can have multiple signatures. And can automatically convert input types where needed. A typed function can be created like: ```javascript const max = typed('max', { 'number, number': function (a, b) { return Math.max(a, b) }, 'BigNumber, BigNumber': function (a, b) { return a.greaterThan(b) ? a : b } }) ``` Typed functions can be merged as long as there are no conflicts in the signatures. This allows for extending existing functions in math.js with support for new data types. ```javascript // create a new data type function MyType (value) { this.value = value } MyType.prototype.isMyType = true MyType.prototype.toString = function () { return 'MyType:' + this.value } // define a new datatype math.typed.addType({ name: 'MyType', test: function (x) { // test whether x is of type MyType return x && x.isMyType } }) // use the type in a new typed function const add = typed('add', { 'MyType, MyType': function (a, b) { return new MyType(a.value + b.value) } }) // import in math.js, extend the existing function `add` with support for MyType math.import({add: add}) // use the new type const ans = math.add(new MyType(2), new MyType(3)) // returns MyType(5) console.log(ans) // outputs 'MyType:5' ``` Detailed information on typed functions is available here: https://github.com/josdejong/typed-function ### Factory functions Regular JavaScript functions can be imported in math.js using `math.import`: ```javascript math.import({ myFunction: function (a, b) { // ... } }) ``` The function can be stored in a separate file: ```javascript export function myFunction (a, b) { // ... } ``` Which can be imported like: ```javascript import { myFunction } from './myFunction.js' math.import({ myFunction }) ``` An issue arises when `myFunction` needs functionality from math.js: it doesn’t have access to the current instance of math.js when in a separate file. Factory functions can be used to solve this issue. A factory function allows to inject dependencies into a function when creating it. A syntax of factory function is: ```javascript factory(name: string, dependencies: string[], create: function, meta?: Object): function ``` where: - `name` is the name of the created function. - `dependencies` is an array with names of the dependent functions. - `create` is a function which creates the function. An object with the dependencies is passed as first argument. - `meta` An optional object which can contain any meta data you want. This will be attached as a property `meta` on the created function. Known meta data properties used by the mathjs instance are: - `isClass: boolean` If `true`, the created function is supposed to be a class, and for example will not be exposed in the expression parser for security reasons. - `lazy: boolean`. By default, everything is imported lazily by `import`. only as soon as the imported function or constant is actually used, it will be constructed. A function can be forced to be created immediately by setting `lazy: false` in the meta data. - `isTransformFunction: boolean`. If true, the created function is imported as a transform function. It will not be imported in math itself, only in the internal `mathWithTransform` namespace that is used by the expression parser. - `recreateOnConfigChange: boolean`. If true, the imported factory will be created again when there is a change in the configuration. This is for example used for the constants like `pi`, which is different depending on the configsetting `number` which can be numbers or BigNumbers. Here an example of a factory function which depends on `multiply`: ```javascript import { factory, create, all } from 'mathjs' // create a factory function const name = 'negativeSquare' const dependencies = ['multiply', 'unaryMinus'] const createNegativeSquare = factory(name, dependencies, function ({ multiply, unaryMinus }) { return function negativeSquare (x) { return unaryMinus(multiply(x, x)) } }) // create an instance of the function yourself: const multiply = (a, b) => a * b const unaryMinus = (a) => -a const negativeSquare = createNegativeSquare({ multiply, unaryMinus }) console.log(negativeSquare(3)) // -9 // or import the factory in a mathjs instance and use it there const math = create(all) math.import(createNegativeSquare) console.log(math.negativeSquare(4)) // -16 console.log(math.evaluate('negativeSquare(5)')) // -25 ``` You may wonder why you would inject functions `multiply` and `unaryMinus` instead of just doing these calculations inside the function itself. The reason is that this makes the factory function `negativeSquare` work for different implementations: numbers, BigNumbers, units, etc. ```javascript import { Decimal } from 'decimal.js' // create an instance of our negativeSquare supporting BigNumbers instead of numbers const multiply = (a, b) => a.mul(b) const unaryMinus = (a) => new Decimal(0).minus(a) const negativeSquare = createNegativeSquare({ multiply, unaryMinus }) ```
上一篇:
链式调用
下一篇:
序列化