软件研究之华夏ERP

标签: 无 分类: 未分类 创建时间:2022-12-15 13:27:44 更新时间:2023-10-20 11:23:28

1.前言

我使用华夏ERP进行部署和开发的时候,遇到的第一个问题就是this.getOption不是一个函数的问题,我降级了less等等操作,都不合适,最后我直接到就升级了package.json相关组件。

  • nodejs v16.15.0
  • npm v8.5.5
  • nvm v0.39.1
  • pnpm v7.14.0
  • @vue/cli v5.0.6
  • yarn v1.22.19

默认超管账户:admin,默认密码均为:123456

2.修改package.json

经过不断的错误尝试,版本升级、降级还有添加,最后形成的可用的配置文件 package.json 如下,这样就没有:this.getOptions is not a function 问题了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
{
"name": "test",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@antv/data-set": "^0.11.8",
"ant-design-vue": "1.7.6",
"area-data": "^5.0.6",
"axios": "^1.2.1",
"clipboard": "^2.0.11",
"codemirror": "5.46.0",
"core-js": "^3.26.1",
"dayjs": "^1.11.7",
"enquire.js": "^2.1.6",
"intro.js": "^6.0.0",
"jquery": "^3.6.2",
"js-cookie": "^3.0.1",
"lodash.get": "^4.4.2",
"lodash.pick": "^4.4.0",
"md5": "^2.3.0",
"moment": "^2.29.4",
"nprogress": "^0.2.0",
"viser-vue": "^2.4.8",
"vue": "^2.6.14",
"vue-area-linkage": "^5.1.0",
"vue-cropper": "^0.5.8",
"vue-i18n": "8.7.0",
"vue-loader": "15.7.0",
"vue-ls": "3.2.0",
"vue-photo-preview": "^1.1.3",
"vue-print-nb-jeecg": "^1.0.11",
"vue-router": "3.6.5",
"vue-splitpane": "^1.0.6",
"vuedraggable": "^2.24.3",
"vuex": "3.1.0",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/babel-helper-vue-jsx-merge-props": "^1.4.0",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"@vue/eslint-config-standard": "^8.0.1",
"babel-eslint": "^10.1.0",
"babel-loader": "^9.1.0",
"cache-loader": "^4.1.0",
"compression-webpack-plugin": "3.1.0",
"css-loader": "^6.7.3",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3",
"html-webpack-plugin": "^5.5.0",
"less": "3.9.0",
"less-loader": "4.1.0",
"null-loader": "^4.0.1",
"sass": "^1.56.2",
"sass-loader": "^13.2.0",
"vue-template-compiler": "^2.6.14"
},
"eslintConfig": {
"vue/max-attributes-per-line": [
2,
{
"singleline": 5,
"multiline": {
"max": 1,
"allowFirstLine": false
}
}
],
"vue/attribute-hyphenation": 0,
"vue/html-self-closing": 0,
"vue/component-name-in-template-casing": 0,
"vue/html-closing-bracket-spacing": 0,
"vue/singleline-html-element-content-newline": 0,
"vue/no-unused-components": 0,
"vue/multiline-html-element-content-newline": 0,
"vue/no-use-v-if-with-v-for": 0,
"vue/html-closing-bracket-newline": 0,
"vue/no-parsing-error": 0,
"no-console": 0,
"no-tabs": 0,
"indent": [
1,
4
]
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}

3.配置文件vue.config.js

根据测试和修改结果,将vue.config.js的配置修改为如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
const path = require('path')
const CompressionPlugin = require('compression-webpack-plugin')

function resolve (dir) {
return path.join(__dirname, dir)
}

// vue.config.js
module.exports = {
// 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
productionSourceMap: false,
configureWebpack: config => {
// 生产环境取消 console.log
if (process.env.NODE_ENV === 'production') {
config.optimization.minimizer[0].options.minimizer.options.compress.drop_console = true
}
},
chainWebpack: (config) => {
config.resolve.alias
.set('@$', resolve('src'))
.set('@api', resolve('src/api'))
.set('@assets', resolve('src/assets'))
.set('@comp', resolve('src/components'))
.set('@views', resolve('src/views'))
// 生产环境,开启js\css压缩
if (process.env.NODE_ENV === 'production') {
config.plugin('compressionPlugin').use(new CompressionPlugin({
test: /\.(js|css|less)$/, // 匹配文件名
threshold: 10240, // 对超过10k的数据压缩
deleteOriginalAssets: false // 删除源文件
}))
}
// 忽略md文件
config.module
.rule('markdown')
.test(/\.md$/)
.use('null-loader')
.loader('null-loader')
},
css: {
loaderOptions: {
less: {
modifyVars: {
/* less 变量覆盖,用于自定义 ant design 主题 */
'primary-color': '#1890FF',
'link-color': '#1890FF',
'border-radius-base': '4px'
},
javascriptEnabled: true
}


}
},
devServer: {
port: 3000,
proxy: {
'/jshERP-boot': {
target: 'http://localhost:9999', // 请求本地 需要jshERP-boot后台项目
ws: false,
changeOrigin: true
}
}
},
lintOnSave: false
}

4.修改样式

将 src/components/NumberInfo 文件夹下的index.less中的 :global 去掉,

1
2
3
4
5
6
7
8
:global {
.anticon-caret-up {
color: @red-6;
}
.anticon-caret-down {
color: @green-6;
}
}

改为如下内容:

1
2
3
4
5
6
.anticon-caret-up {
color: @red-6;
}
.anticon-caret-down {
color: @green-6;
}

5.修改路由配置

不知道为什么会有循环引用的问题,需要将 src/config/router.config.js 文件中的 const 改为 var。

1
2
3
4
5
6
7
/**
* 基础路由
* @type { *[] }
*/
export const constantRouterMap = [
....
]

改为

1
2
3
export var constantRouterMap = [
....
]

6.导入数据

这里使用Dbeaver进行数据导入的时候,如果直接倒入数据的话,会出现乱码的问题。
(1) 新建数据库jsh_erp之后,选择utf-8编码,
(2) 右键数据库,选择SQL编辑器,新建sql编辑器,将脚本复制到编辑框中
(3) 然后右键编辑器,选择执行->选择执行脚本。
(4) 导入数据

7.修改mysql依赖

因为我系统里面安装的是mysql8.0,而华夏ERP使用的是mysql5.7,需要修改后端的mysql依赖

1
2
3
4
5
6
7
8
9
10
11
12
13

<!-- <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency> -->

<!-- 修改为 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>

8.修改数据库配置

修改application.properties中的配置

1
2
3
4
spring.datasource.username=root
spring.datasource.password=xxx
## redis配置
spring.redis.password=1234abcd

9.配置nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
listen 3000;
server_name localhost;
gzip on;
gzip_min_length 100;
gzip_types text/plain text/css application/xml application/javascript;
gzip_vary on;
location / {
root /home/jshERP/jshERP-web;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /jshERP-boot/ {
proxy_pass http://localhost:9999/jshERP-boot/;
proxy_set_header Host $host:$server_port;
}
}

10.自动化脚本

我这里因为给别人安装的是在windows下安装的,所以最好有一个windows的一键启动脚本,涉及到了nginx启动、java程序启动,还有一个网穿云的内网穿透工具的启动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
rem 加入下面的代码,后台启动
if "%1"=="h" goto begin
start mshta vbscript:createobject("wscript.shell").run("""%~nx0"" h",0)(window.close)&&exit
:begin

@echo off
taskkill /f /fi "IMAGENAME eq nginx.exe"
rem 此处放加压目录
SET NGINX_DIR=C:\Soft\nginx-1.23.3
cd %NGINX_DIR%
start nginx.exe

rem 启动java
SET jshERP_DIR=C:\Soft\jshERP
cd %jshERP_DIR%
java -jar jshERP.jar

rem 按任意继续
rem pause
参考文章:
1.windows nginx重启脚本.bat taskkill /f /fi “IMAGENAME eq nginx.exe”
2.Nginx windows下nginx启动bat脚本和安装 SET NGINX_DIR=E:\VMS\nginx-1.8.0\ #此处放加压目录
3.bat中代码注释的几种方法
4.bat脚本启动Java服务 这里还提供了脚本,判断java程序只启动一次的,若jar服务已启动则不启动,没有启动则先查看端口是否被其他进程占用,占用则释放端口后再启动的bat脚本代码。bat脚本双击运行后会出现黑色cmd的终端窗口,若不想出现该窗口,可让其后台启动运行。
5.Windows环境下使用bat脚本后台运行java或springboot项目的jar包

问题

(1) Less Loader has been initialized using an options object that does not match the API schema - options has an unknown property ‘modifyVars’.

原先的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
module.exports = {
// 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
productionSourceMap: false,
configureWebpack: config => {
// 生产环境取消 console.log
if (process.env.NODE_ENV === 'production') {
config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
}
},
chainWebpack: (config) => {
config.resolve.alias
.set('@$', resolve('src'))
.set('@api', resolve('src/api'))
.set('@assets', resolve('src/assets'))
.set('@comp', resolve('src/components'))
.set('@views', resolve('src/views'))
// 生产环境,开启js\css压缩
if (process.env.NODE_ENV === 'production') {
config.plugin('compressionPlugin').use(new CompressionPlugin({
test: /\.(js|css|less)$/, // 匹配文件名
threshold: 10240, // 对超过10k的数据压缩
deleteOriginalAssets: false // 删除源文件
}))
}
},
css: {
loaderOptions: {
less: {
modifyVars: {
/* less 变量覆盖,用于自定义 ant design 主题 */
'primary-color': '#1890FF',
'link-color': '#1890FF',
'border-radius-base': '4px'
},
// javascriptEnabled: true
}
}
},
devServer: {
port: 3000,
proxy: {
'/jshERP-boot': {
target: 'http://localhost:9999', // 请求本地 需要jshERP-boot后台项目
ws: false,
changeOrigin: true
}
}
},
lintOnSave: undefined
}

【解决方法】
经过查找资料,发现了下面的这个配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
css: {
loaderOptions: {
less: {
lessOptions: {
javascriptEnabled: true,
modifyVars: {
'primary-color': '#1890FF',
'link-color': '#1890FF',
'border-radius-base': '4px'
},
},
}

}
},

(2) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
这个问题不知道出现在哪里,因为文件夹里有.md文件,本来应该是忽略的文件,最后还是被webpack处理了,所以就导致了不能识别的问题。Module parse failed: Unexpected character ‘ ‘

【解决方法】
后来我找到了相关的配置方法

1
2
3
4
5
config.module
.rule('markdown')
.test(/\.md$/)
.use('null-loader')
.loader('null-loader')
参考文章:
1.webpack打包项目报错:You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
2.Vue WebPack忽略指定文件或目录方式 1.使用 null-loader;2.使用 url-loader;3.vue.config.js 中设置忽略文件,但是这个地方写的不是很明确。
3.在vue 中配置忽略某些文件或文件夹语法检查 eslint
4.webpack 相关 Vue CLI 内部的 webpack 配置是通过 webpack-chain 维护的。这个库提供了一个 webpack 原始配置的上层抽象,使其可以定义具名的 loader 规则和具名插件,并有机会在后期进入这些规则并对它们的选项进行修改。 process.env.NODE_ENV === ‘production’ 环境不同的配置,这是官方的说明。
5.module.rule(…).loader(…).use is not a function
6.一个超简单的 vue-markdown-loader 这里有rule的配置方法。

(3) Cannot set properties of undefined (setting ‘parent’)
我查看了错误代码,显示这个@import

1
2
3
<style lang="less" scoped>
@import "index";
</style>

【解决方法】
我找到了相关的less配置

1
2
3
4
5
6
7
8
:global {
.anticon-caret-up {
color: @red-6;
}
.anticon-caret-down {
color: @green-6;
}
}

修改为了,也就是去掉了global

1
2
3
4
5
6
7
8
// :global {
.anticon-caret-up {
color: @red-6;
}
.anticon-caret-down {
color: @green-6;
}
// }
参考文章:
1.开发环境报错TypeError: Cannot set properties of undefined 注释 //@import “index”;
2.yarn run build 编译失败 并没有注释,只是把 :global {} 去掉了。去掉后,也不会污染其他CSS,或者被其他CSS污染。。。这两个类只会在 .sub-total 内部生效。

(4) ./mode/swift/swift.js is not exported from package
这个问题出在 codemirror 这个模块中。我找到了这个文件 JCodeEditor.vue 文件,发现里面的代码引入如下,但是在codemirror这个库下面没有mode文件夹,难道是我安装错了吗?

1
2
3
4
5
6
// 需要引入具体的语法高亮库才会有对应的语法高亮效果
// codemirror 官方其实支持通过 /addon/mode/loadmode.js 和 /mode/meta.js 来实现动态加载对应语法高亮库
// 但 vue 貌似没有无法在实例初始化后再动态加载对应 JS ,所以此处才把对应的 JS 提前引入
import 'codemirror/mode/javascript/javascript.js'
import 'codemirror/mode/css/css.js'
import 'codemirror/mode/xml/xml.js'

我发现最新的版本是 “codemirror”: “^6.0.1” 版本,但是老项目中使用的是5.46.0这个版本,这个版本的codemirror目录下,有mode文件夹。

1
"codemirror": "^5.46.0",

(5) Failed to resolve loader: null-loader

参考文章:
1.null-loader One use for this loader is to silence modules imported by a dependency. Say, for example, your project relies on an ES6 library that imports a polyfill you don’t need, so removing it will cause no loss in functionality.

(6) Emitted value instead of an instance of Error

(6) vue__WEBPACK_IMPORTED_MODULE_3__.createVNode is not a function
打开浏览器控制台,出现了这个问题,错误的版本如下:

1
2
"vue": "^2.6.14",
"vuex": "^4.1.0",

【尝试方法】
就是找到和vue匹配的vuex版本。

1
2
"vue": "^2.6.14",
"vuex": "3.1.0",

后来我尝试把所有关于vue的插件的版本都降级,ant-design-vue、vue-i18n、vue-loader、vue-ls、vue-router ,还是会出现这个问题

【解决方法】
经过不断的尝试,删除修改插件的版本,最后 ant-design-vue@1.7.6;”less”: “3.9.0”;”less-loader”: “4.1.0”,但是具体到底是哪一个插件导致的这个问题,我暂时还没有办法找到问题。

(7) Can’t resolve ‘@vue/babel-helper-vue-jsx-merge-props’

【解决方法】
重新安装这个插件就好了

1
pnpm add @vue/babel-helper-vue-jsx-merge-props -D

(8) BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.This is no longer the case. Verify if you need this module and configure a polyfill for it.

(9) Uncaught ReferenceError: can’t access lexical declaration ‘constantRouterMap’ before initialization
初始化前无法访问词法声明。 我查看了问题出现的代码,主要是 src/config/router.config.js 这个文件中的,

1
2
3
4
5
6
7
/**
* 基础路由
* @type { *[] }
*/
export const constantRouterMap = [
....
]

【解决方法】
就是将const改为var,看参考文章中的说明,就是说这里可能是出现了循环依赖的问题。

1
2
3
4
5
6
7
/**
* 基础路由
* @type { *[] }
*/
export var constantRouterMap = [
....
]
参考文章:
1.ReferenceError: can’t access lexical declaration ‘X’ before initialization
2.[Error “ReferenceError: can’t access lexical declaration `XXX’ before initialization” when loading a webpack-ed app](https://github.com/webpack/webpack/issues/9173) By using var instead of const you will receive undefined instead of the TDZ error. This probably lead to other issues. 将const替换为var
3.ReferenceError: can’t access lexical declaration ‘Foo’ before initialization A simple way to understand why this error happens involves understanding hoisting. Before execution, an interpreter (like a browser engine) will move all variables and functions to the top of the file, likely for ease of access. But more modern instances of variables and functions, such as classes and function expressions, might get hoisted to the top but without being initialized. This is why that although the class is found, it has no proper value assigned to it, even if empty, thus an error occurs.

(10) Inline JavaScript is not enabled
这个问题主要是less-loader版本配置不一样导致的问题。

【解决方法】
“less”: “3.9.0”, “less-loader”: “4.1.0” 这个版本配置的vue.config.js如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
 css: {
loaderOptions: {
less: {
modifyVars: {
/* less 变量覆盖,用于自定义 ant design 主题 */
'primary-color': '#1890FF',
'link-color': '#1890FF',
'border-radius-base': '4px'
},
javascriptEnabled: true
}
}
},

最新的版本,比如13版本,vue.config.js 配置内容如下,多加了一个 lessOptions 配置

1
2
3
4
5
6
7
8
9
10
css: {
loaderOptions: {
less: {
lessOptions: {
javascriptEnabled: true,
modifyVars: { '@primary-color': '#1DA57A','link-color': '#1890FF', 'border-radius-base': '4px'},
},
}
}
},

(11) Cannot read properties of undefined (reading ‘compress’)
这是我在解决了上面的问题之后,在执行:pnpm build的时候出现的问题,看看配置文件,主要是下面的问题。

1
2
3
4
5
6
configureWebpack: config => {
// 生产环境取消 console.log
if (process.env.NODE_ENV === 'production') {
config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
}
},

【解决方法】
将 configureWebpack 修改为插件的形式,这样就不会有问题了。

1
2
3
4
5
6
7
8
9
10
11
const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
// 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
productionSourceMap: false,
// 生产环境取消 console.log
configureWebpack: {
optimization: {
minimizer: [new TerserPlugin({ terserOptions: { compress: { drop_console: true } } })]
}
},
}

或者是修改为如下的内容,这样就可以根据不同的环境进行console.log的输出了

1
2
3
4
5
6
configureWebpack: config => {
// 生产环境取消 console.log
if (process.env.NODE_ENV === 'production') {
config.optimization.minimizer[0].options.minimizer.options.compress.drop_console = true
}
},
参考文章:
1.Cannot read property ‘compressed’ of undefined
2.Vue配置vue.config.js打包时删除console.log日志 1.如果需要根据打包环境来判断是否需要删除;2. 通过配置configureWebpack的方式;
3.vue.config.js配置打包删除console和debugger
4.如何在vue.config.js中配置vue-cli3.0打包之后不显示console 如果用 chainWebpack 改配置的话注意我们考虑到兼容性的原因还没有升级 webpack-chain v5,v4 和 v5 唯一的区别就是改 minimizer 的方法。这里还有 configureWebpack: config => { if (process.env.NODE_ENV === ‘production’) { config.optimization.minimizer[0].options.terserOptions.compress[‘drop_console’] = true } } 这种方法,但是我的里面用不上。
5.TerserWebpackPlugin

(12) 中文乱码
在经历了无数的磨难之后,终于算是启动了前端和后端,可是还有一个问题,就是中文乱码的问题。

【解决方法】
这个主要是在导入数据库的时候的问题,具体方法,可以参考Post not found: DBeaver数据库管理工具 DBeaver数据库管理工具

(13) Error in callback for watcher “activePage”: “TypeError: can’t access property “catch”, originalPush.call(…) is undefined
在浏览器上显示这个错误:TypeError: can’t access property “catch”, originalPush.call(…) is undefined,定位到 src/router/index.js 文件,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import Vue from 'vue'
import Router from 'vue-router'
import { constantRouterMap } from '@/config/router.config'

//update-begin-author:taoyan date:20191011 for:TASK #3214 【优化】访问online功能测试 浏览器控制台抛出异常
try {
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
} catch (e) {
}
//update-end-author:taoyan date:20191011 for:TASK #3214 【优化】访问online功能测试 浏览器控制台抛出异常

Vue.use(Router)

export default new Router({
mode: 'history',
base: process.env.BASE_URL,
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap
})

【解决方法】
在vue-router在3.1.0版本之后,push和replace方法会返回一个promise对象,如果跳转到相同的路由,就报promise uncaught异常,我通过安装高版本的vue-router解决了这个问题。

1
2
3
4
## 卸载
pnpm remove vue-router
## 安装
pnpm add vue-router@3.6.5

注意:要新启动server,这个比较重要

参考文章:
1.关于js的call方法的返回值问题
2.vue-router重写push方法,解决相同路径跳转报错 这里就是上面的代码,基本上一致
3.const originalPush = VueRouter.prototype.push // 重写了原型上的push方法,统一的处理了错误信息 VueRouter.prototype.pus… 在vue项目中,如果使用$router.push跳转到一个相同的路由,就会遇到以下错误。方案01-降版本;方案2-使用catch捕获异常;方案3-修改push方法
4.vue-router重写Router.prototype.push,解决相同路径跳转的报错问题 在router的index.js里面写,在use之前,如果加上以下代码,报错‘Cannot read properties of undefined (reading ‘catch’) at VueRouter.push ’那就是vue-router的版本问题,安装高一点的版本即可3.1.6以上

(14) Public Key Retrieval is not allowed
这里的主要场景就是:禁用 SSL/TLS 协议传输切当前用户在服务器端没有登录缓存的情况下,客户端没有办法拿到服务器的公钥。

【解决方法】

  • 1.在 JDBC 连接串中加入 allowPublicKeyRetrieval=true 参数;
  • 2.在 CLI 客户端连接时加入–get-server-public-key 参数;
  • 3.在 CLI 客户端连接时加入–server-public-key-path=file_name 参数,指定存放在本地的公钥文件。
参考文章:
1.Public Key Retrieval is not allowed解决 在 JDBC 连接串中加入 allowPublicKeyRetrieval=true 参数
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。