0%

问题

优化下面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
function filterCategories(list = [], name) {
return list.filter((data) => {
let { extensions } = data;
if (extensions == undefined) {
return false;
}
let { appName } = extensions;
if (appName == undefined) {
return false;
}
return appName == name;
});
}

为了容错,每次获取对象下面属性都会先判断一下。但是代码看上去不优雅

比如还有这种写法,更难看了

1
2
3
4
5
6
7
8
9
10
11
function filterCategories(list = [], name) {
return list.filter((data) => {
try {
let { extensions } = data;
let { appName } = extensions;
return appName == name;
} catch (error) {
return false;
}
});
}

群里的也有群友说用 lodash 里的_.has _.get方法

解决

用**MDN - 可选链操作符**,优雅的一行解决问题。

1
2
3
function filterCategories(list = [], name) {
return list.filter((data) => data?.extensions?.appName == name);
}

后记

IE:小老弟,你写的什么东西?我看不懂

一声不吭直接 babel.io 转码安排上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function filterCategories(list = [], name) {
return list.filter((data) => {
var _data$extensions;

return (
(data === null || data === void 0
? void 0
: (_data$extensions = data.extensions) === null ||
_data$extensions === void 0
? void 0
: _data$extensions.appName) == name
);
});
}

问题

有一段字符串 let string = 'let a = 123;console.log(a)',需要运行这段字符串。

我第一个想到的就是是 eval

但是 MDN 提到了:**永远不要使用 eval!**

使用 eval 的糟糕代码:

1
2
3
4
function looseJsonParse(obj) {
return eval('(' + obj + ')');
}
console.log(looseJsonParse('{a:(4-1), b:function(){}, c:new Date()}'));

不用 eval 的更好的代码:

1
2
3
4
function looseJsonParse(obj) {
return Function('"use strict";return (' + obj + ')')();
}
console.log(looseJsonParse('{a:(4-1), b:function(){}, c:new Date()}'));

解决

1
Function(`let string = 'let a = 123;console.log(a)`)();

后记

真香

被问到 BFC 了,讲真,我有时候怀疑自己是不是前端,以前没有注意到这类问题。现在都是组件化开发,平时我自己用到的都是基本的 flex 一把梭,平时页面可能也对细节要求不低,但是讲真,确实没有注意到 BFC,难道是我是写功能太多,切页面太少的缘故?还是说现在浏览器越来越新,我们不需要再考虑这样的问题了?类似于 js 的 varlet

既然碰到了那就学习一下吧。

文档与教程

MDN 的标准文档,读起来可能艰涩一些,可以看一下其他的文章教程后再回过头来看这个文档:

优秀教程文章,可以看了这三篇文章再去看官方文档:

个人理解

先引用一下 MDN 文档,毕竟是标准,当然直接这么看你可能还是有点楞逼,不知道 BFC 是干嘛的?反正我是楞逼的

阅读全文 »

需求

鼠标悬停变小手,mark 一下以后不用查资料了

实现

1
cursor:pointer;
  • cursor 其他取值
  • auto 标准光标
  • default 标准箭头
  • pointer, hand 手形光标
  • wait 等待光标
  • textI 形光标
  • vertical-text 水平I形光标
  • no-drop 不可拖动光标
  • not-allowed 无效光标
  • help 帮助光标
  • all-scroll 三角方向标
  • move 移动标
  • crosshair 十字标
  • e-resize
  • n-resize
  • nw-resize
  • w-resize
  • s-resize
  • se-resize
  • sw-resize

问题

1
['1', '2', '3'].map(parseInt);

求上面的返回值

翻车

控制台一敲结果是 [1, NaN, NaN]

这车翻的太丢人了?Mark 一下

竟然还有人问为啥

熟读文档:

补充一下:

实际上这是对 map 方法回调函数的第二个参数和 parseInt 的第二个参数是进制

1
['1', '2', '3'].map(parseInt);

的执行过程是

1
2
3
parseInt('1', 0); // 1
parseInt('2', 1); // NaN
parseInt('3', 2); // NaN

还问

  • 为什么 parseInt 第二个参数为 0 返回1
  • 解释一下下面的现象
1
2
parseInt('19', 7); // 1
parseInt('91', 7); // NaN

第一个问题有人回答是0进制,我直接???

答案其实文档中有,我已经分别加粗了

对于 parseInt(string, radix)

如果 radix 是 undefined、0或未指定的,JavaScript会假定以下情况

  1. 如果输入的 string以 “0x”或 “0x”(一个0,后面是小写或大写的X)开头,那么radix被假定为16,字符串的其余部分被当做十六进制数去解析。
  2. 如果输入的 string以 “0”(0)开头, radix被假定为8(八进制)或10(十进制)。具体选择哪一个radix取决于实现。ECMAScript 5 澄清了应该使用 10 (十进制),但不是所有的浏览器都支持。因此,在使用 parseInt 时,一定要指定一个 radix。
  3. 如果输入的 string 以任何其他值开头, radix 是 10 (十进制)。

如果第一个字符不能转换为数字,parseInt会返回 NaN。

群友疑惑

parseInt(4,4) 为啥是 NaN
parseInt(10, 9) 为啥是9 10的9进制是9?

阅读全文 »

问题

需要安装 Jenkins 插件的时候发现插件列表为空。

解决

选择插件管理 - 高级 - 升级站点 - 更改 URL

https 替换为 http

点击提交即可

问题

组件输出的是 html 字符串,期望能直接渲染出来而不是用字符串形式显示

1
2
let a = "<br>123<br>456"
<div>{a}</div>

解决方法

使用 dangerouslySetInnerHTML 方法,见官方文档: dangerouslySetInnerHTML

1
2
let a = "<br>123<br>456"
<div dangerouslySetInnerHTML={{__html: a}} />

后记

翻译一下方法名:危险的设置 InnerHTML,要注意一下

问题

项目引入了一个js文件,这个js文件不符合eslint规范但却很nb,就期望eslint忽略对这个js文件的检查

至于问我为什么不重构?时间不够啊。

解决问题

解法方法很简单,见官方文档:**eslintignore**

在项目文件夹下创建 .eslintignore 文件

1
src/xxxx

需求

React 父组件主动触发子组件的方法

解决方法

主要用到了 useRef useImperativeHandle forwardRef 3 个方法

子组件代码如下,用 useImperativeHandle 将方法暴露出去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, { useState, useImperativeHandle, forwardRef } from 'react';
import { MyComponent } from 'my-component';

const Children = forwardRef((props, ref) => {
const [myState, setMyState] = useState([]);
useImperativeHandle(
ref,
() => ({
myState,
setMyState,
}),
[myState]
);
return <MyComponent {...props} />;
});

export default Children;

父组件代码如下,主要是用 useRef

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
import React, { useState, useRef } from 'react';
import Children from 'children';

const Parent = (props, ref) => {
const [ref] = useRef(null);

const setState = (params) => {
ref.current.setMyState(params);
};

const getState = () => {
console.log('getState :>> ', ref.current.myState);
};

return (
<div>
<div
onClick={() => {
setState(1111);
}}>
setState
</div>
<div
onClick={() => {
getState();
}}>
getState
</div>
<Children ref={ref} />
</div>
);
};

后记

这个最好看一下react官方文档

公司的脚手架竟然没有加载 svg 图标功能?导致我引入 svg 图片失败。

解决方法

webpack 用 file-loader 引入 svg 图标文件

1
2
3
4
5
6
7
8
9
10
module.exports = {
module: {
rules: [
{
test: /\.svg/,
use: ['file-loader'],
},
],
},
};

后记

当然,用 url-loader 应该也有效果。但是由于我不知道公司的脚手架内部的 url-loader 配置是什么样的,所以我没有覆盖 url-loader 的配置。