Compare commits

..

1 Commits

Author SHA1 Message Date
猿恋
4d836229aa
Merge 7539722960 into e9a48dd823 2024-05-25 16:56:56 +08:00
7 changed files with 63 additions and 197 deletions

View File

@ -30,7 +30,7 @@ CSS3中的 flex 属性,在布局方面做了非常大的改进,使得我们
但你如果用 float 来做布局float 属性的元素会脱离文档流,而且会涉及到各种 BFC、清除浮动的问题。浮动相关的问题比较麻烦所以也成了面试必问的经典题目。但有了 flex 布局之后,这些问题都不存在的。
2、**flex 是一种现代的布局方式,是 W3C 第一次提供真正用于布局的 CSS 规范**。 flex 提供了非常丰富的属性,非常灵活,让布局的实现更佳多样化,且方便易用。
2、**flex 是一种现代的布局方式,是 W3C 第一次提供真正用于布局的 CSS 规范**。 flex 非常提供了丰富的属性,非常灵活,让布局的实现更佳多样化,且方便易用。
flex 唯一的缺点就在于,它不支持低版本的 IE 浏览器。

View File

@ -5,8 +5,12 @@ publish: true
<ArticleTopAd></ArticleTopAd>
![](http://img.smyhvae.com/20191108_2130.png)
## 前言
老板的手机收到一个红包,为什么红包没居中?
@ -88,6 +92,7 @@ publish: true
```
上面的代码中,父元素和子元素都是定宽高的,即便在这种情况下,我给子元素设置 `margin: auto`,子元素依然没有垂直居中。
那还有没有比较好的通用的做法呢?
@ -135,12 +140,14 @@ publish: true
```
**代码解释**:我们先让子元素的左上角居中,然后向上移动宽度的一半(50px),就达到了垂直居中的效果;水平居中的原理类似。
**不足之处**:要求指定子元素的宽高,才能写出 `margin-top``margin-left` 的属性值。
但是,在通常情况下,对那些需要居中的元素来说,其宽高往往是由其内容来决定的,不建议固定宽高。
### 方式2绝对定位 + translate
> 无需指定子元素的宽高,推荐。
@ -315,7 +322,7 @@ publish: true
background: rgba(0, 0, 0, 0.7);
}
/* 弹窗的内容区域(正文内容 + close自适应宽高,且严格居中 */
/* 弹窗区域(内容 + close严格居中 */
.popup_content {
position: absolute;
top: 50%;
@ -323,7 +330,7 @@ publish: true
transform: translate(-50%, -50%);
}
/* 弹窗的正文部分 */
/* 弹窗的内容部分 */
.content_box {
width: 15.45rem;
height: 19.32rem;
@ -379,6 +386,10 @@ publish: true
- [margin:auto实现绝对定位元素的水平垂直居中](http://www.zhangxinxu.com/wordpress/2013/11/margin-auto-absolute-%E7%BB%9D%E5%AF%B9%E5%AE%9A%E4%BD%8D-%E6%B0%B4%E5%B9%B3%E5%9E%82%E7%9B%B4%E5%B1%85%E4%B8%AD/)
## 我的公众号
想学习**更多技能**?不妨关注我的微信公众号:**千古壹号**id`qianguyihao`)。
@ -386,3 +397,4 @@ publish: true
扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外:
![](http://img.smyhvae.com/20190101.png)

View File

@ -22,7 +22,7 @@ title: 09-数据类型转换
- 转换为布尔型
我需要专门把某个数据类型转换成 null 或者 undefined 吗?因为这样做没有意义。
你会专门把某个数据类型转换成 null 或者 undefined 吗?不会,因为这样做没有意义。
## 变量的类型转换的分类
@ -80,8 +80,6 @@ var result = 变量.toString();
该方法**不会影响到原变量**,它会将转换的结果返回。当然我们还可以直接写成`a = a.toString()`,这样的话,就是直接修改原变量。
当我们对一个字符串字面量调用 toString() 方法时,它实际上是调用了 String 构造函数,并将字符串字面量转换为一个 String 对象,然后调用该对象的 toString() 方法。String 对象的 toString() 方法返回调用它的原始字符串值。
举例:
```js
@ -154,25 +152,22 @@ const num4 = 0.10000001;
console.log(num4.toString()); // 打印结果:"0.10000001"
```
4常量可以直接调用 toString() 方法,但这里的常量,不允许直接写数。举例如下:
4常量可以直接调用 toString() 方法,但这里的常量,不允许直接写数。举例如下:
```js
1.toString(); // 注意,会报错
1..toString(); // 合法。得到的结果是字符串"1"
1.2.toString(); // 合法。得到的结果是字符串"1.2"
(1).toString(); // 合法。得到的结果是字符串"1"
'1'.toString(); // 合法。得到的结果是字符串"1"
```
上方代码中,为何出现这样的打印结果?这是因为:
- 第一行代码JS引擎认为`1.toString()`中的`.`是小数点,**是数字字面量的一部分,而不是方法调用的分隔符**。小数点后面的字符是非法的。
- 第一行代码JS引擎认为`1.toString()`中的`.`是小数点,小数点后面的字符是非法的。
- 第二行、第三行代码JS引擎认为第一个`.`是小数点,第二个`.`是属性访问的语法,所以能正常解释实行。
- 第四行代码:用`()`排除了`.`被视为小数点的语法解释,所以这种写法也能正常解释执行。
小结:因为点号(.)被解释为数字字面量的一部分,而不是方法调用的分隔符。为了正确调用 toString 方法,可以使用括号或额外的点号。
如果想让数字调 toString() 方法,更推荐的做法是先把数字放到变量中存起来,然后通过变量调用 toString()。举例:
如果想让数字调 toString() 方法,推荐的做法是先把数字放到变量中存起来,然后通过变量调用 toString()。举例:
```js
const a = 1;
@ -245,12 +240,12 @@ const result = Number(变量/常量);
使用 Number() 函数转为数字的规则如下:
| 原始值 | 转换后的值 |
| --------- | ------------------------------------------------------------ |
| 字符串 | 1字符串去掉首尾空格后剩余字符串的内容如果是纯数字则直接将其转换为数字。<br/>2字符串去掉首尾空格后剩余字符串包的内容只要含了其他非数字的内容`小数点`按数字来算),则转换为 NaN。怎么理解这里的 **NaN** 呢?可以这样理解,使用 Number() 函数之后,**如果无法转换为数字,就会转换为 NaN**。<br />3如果字符串是一个**空串**或者是一个**全是空格**的字符串,则转换为 0。<br/> |
| 布尔值 | true 转成 1false 转成 0 |
| undefined | NaN |
| null | 0 |
| 原始值 | 转换后的值 |
| ------------------- | ------------------------------------------------------------ |
| 字符串 | 1字符串去掉首尾空格后剩余字符串的内容如果是纯数字则直接将其转换为数字。<br/>2)如果字符串是一个**空串**或者是一个**全是空格**的字符串,则转换为 0。<br/>3)字符串去掉首尾空格后,剩余字符串包的内容只要含了其他非数字的内容(`小数点`按数字来算),则转换为 NaN。怎么理解这里的 **NaN** 呢?可以这样理解,使用 Number() 函数之后,**如果无法转换为数字,就会转换为 NaN**。 |
| 布尔值true、false | true 转成 1false 转成 0 |
| undefined | NaN |
| null | 0 |
### 2、隐式类型转换——运算符加号 `+`
@ -488,7 +483,7 @@ parseFloat() 的几个特性,可以参照 parseInt()。
其他的数据类型都可以转换为 Boolean 类型。无论是隐式转换,还是显示转换,转换结果都是一样的。有下面几种情况:
转换为 Boolean 类型的规则如下:
使用 Number() 函数转为数字的规则如下:
| 原始值 | 转换后的值 |
| --------- | ------------------------------------------------------------ |
@ -502,7 +497,7 @@ parseFloat() 的几个特性,可以参照 parseInt()。
**重中之重来了:**
转换为 Boolean 的上面这几种情况,**极其重要**项目开发中会频繁用到。比如说,我们在项目开发中,经常需要对一些**非布尔值**做**逻辑判断或者逻辑运算**,符合条件后,才做下一步的事情。这个逻辑判断就是依据上面的四种情况。
转换为 Boolean 的上面这几种情况,**极其重要**,开发中会频繁用到。比如说,我们在项目开发中,经常需要对一些**非布尔值**做**逻辑判断或者逻辑运算**,符合条件后,才做下一步的事情。这个逻辑判断就是依据上面的四种情况。
举例:(接口返回的内容不为空,前端才做进一步的事情)

View File

@ -4,28 +4,22 @@ title: 10-运算符
<ArticleTopAd></ArticleTopAd>
我们在前面讲过变量,本文讲一下**运算符**和表达式。
## 运算符的定义和分类
### 运算符的定义
运算符和表达式形影不离,先来介绍一下概念。
**运算符**:也叫操作符,是一种符号。通过运算符可以对一个或多个值进行运算,并获取运算结果。
**表达式**:数字、运算符、变量的组合(组成的式子)。
表达式最终都会有一个运算结果,我们将这个结果称为表达式的**返回值**。
如:`+`、`*`、`/`、`()` 都是**运算符**,而`3+5/2`则是**表达式**。
如:`+`、`*`、`/`、`()` 都是**运算符**,而`3+5/2`则是**表达式**。
比如typeof 就是运算符,可以获得一个值的类型。它会将该值的类型以**字符串**的形式返回,返回值可以是 number、string、boolean、undefined、object。
**运算元**:参与运算的对象。这个对象一般是数值或者变量。
例如:在加法运算中,运算元就是加法操作符两侧的值或变量。在逻辑运算中,运算元是指用于计算逻辑表达式的操作数。
如果一个运算符(比如加法运算符)拥有两个运算元,那么它是二元运算符。一元运算符、三元运算符的概念同理。
### 运算符的分类
JS 中的运算符,分类如下:
@ -48,14 +42,13 @@ JS 中的运算符,分类如下:
常见的算数运算符有以下几种:
| 运算符 | 描述 |
| :----- | :---------------------: |
| + | 加、字符串连接 |
| - | 减 |
| \* | 乘 |
| / | 除 |
| % | 获取余数(取余/取模) |
| ** | 幂运算,是 ES7 新增特性 |
| 运算符 | 描述 |
| :----- | :--------------------: |
| + | 加、字符串连接 |
| - | 减 |
| \* | 乘 |
| / | 除 |
| % | 获取余数(取余、取模) |
**求余的举例**
@ -98,7 +91,7 @@ var a = 1 + ((2 * 3) % 4) / 3;
原式 = 1 + 6 % 4 / 3 = 1 + 2 / 3 = 1.66666666666666
### 取余(取模)运算
### 取模(取余)运算
格式:
@ -106,8 +99,6 @@ var a = 1 + ((2 * 3) % 4) / 3;
余数 = m % n;
```
`%`符号在这里并不是用来做百分号的计算,和百分号计算没有关系。
计算结果注意:
- 取余运算结果的正负性,取决于 m而不是 n。比如`10 % -3`的运算结果是 1。`-10 % 3`的运算结果是-1。
@ -119,23 +110,6 @@ var a = 1 + ((2 * 3) % 4) / 3;
- 如果 m>=n那就正常取余。
- 如果 m<n那结果就是 m
### 幂运算
`**`这个符号在JS中是幂运算符是ES7中新增的特性。比如2的3次方可以表示为 `2**3`
除了`**`运 算符之外JavaScript 还提供了`Math.pow()方法,也可以进行幂运算。
下面两行代码是等价的2的3次方
```
2**3;
Math.pow(2, 3);
```
此外,需要注意,`** `运算符的优先级高于乘法和除法运算符。
### 浮点数运算的精度问题
浮点数值的最高精度是 17 位小数,但在进行算术计算时,会丢失精度,导致计算不够准确。比如:
@ -148,12 +122,6 @@ console.log(0.07 * 100); // 运算结果不是 7而是 7.000000000000001
因此,**不要直接判断两个浮点数是否相等**。前面的文章《JavaScript 基础基本数据类型Number》有详细介绍。
实际项目中,涉及数字计算的这部分,比较麻烦,且非常严谨;尤其是交易、金钱相关的业务,则一定不能出错。
如果你直接把两个数字进行加减乘除,很容易丢失精度,导致计算不准确。实战中,往往需要把计算相关的代码封装成公共方法,提供给业务侧调用。
我们也可以在开源网站找到一些已经封装好的工具类,比较知名的是 [big.js](https://github.com/MikeMcl/big.js)。
## 自增和自减运算符
### 自增运算符 `++`
@ -547,51 +515,31 @@ if (result.retCode == 0) {
### 赋值运算符包括哪些
| 运算符 | 运算规则 | 举例 |
| ------ | ------------ | --------------------------- |
| = | 直接赋值 | let a = 5 |
| += | 加后赋值 | a += 5 等价于 a = a + 5 |
| -= | 减后赋值 | a -= 5 等价于 a = a - 5 |
| *= | 乘后赋值 | a *= 5 等价于 a = a * 5 |
| /= | 除后赋值 | a /= 5 等价于 a = a / 5 |
| %= | 取余数后赋值 | a %= 5 等价于 a = a % 5 |
| **= | 幂运算后赋值 | `a **= 5` 等价于 `a = a**5` |
- `=` 直接赋值。比如 `var a = 5`。意思是,把 5 这个值,往 a 里面存一份。简称:把 5 赋值给 a。
1、直接赋值
- `+=`:比如 a += 5 等价于 a = a + 5。
`=` 运算符是直接赋值,很容易理解。比如 `let a = 5`。意思是把 5 这个值,往 a 里面存一份。简称:把 5 赋值给 a
- `-=`:比如 a -= 5 等价于 a = a - 5。
2、优先级算数运算符的优先级高于赋值运算符。举例
- `*=`:比如 a _ = 5 等价于 a = a -5。
- `/=`:比如 a /= 5 等价于 a = a / 5。
- `%=`:比如 a %= 5 等价于 a = a % 5。
### 注意事项
1算数运算符的优先级高于赋值运算符。举例
```js
const result = 1 + 2; // 先计算 1 + 2再把计算结果赋值给 result。因为算数运算符的优先级高于赋值运算符。
```
3、**原地修改**Modify-in-place
“原地修改”是数据结构中比较常见的概念。定义是:直接在数据原有的存储位置上进行修改,而不是创建一个新的副本(即新的存储空间)来存储修改后的结果。这种方式可以减少内存的使用,因为不需要额外的存储空间来保存修改后的数据。
通俗理解:对一个变量进行运算,并将新的运算结果存储在原有变量中。
上面列出的赋值运算符中,`=`符号是直接赋值,其他的赋值运算都是属于原地修改。
### 链式赋值chaining assignments
举例:
2赋值运算符的结合性是右结合性从右至左的顺序计算。举例
```js
const a = b = c = 2;
```
解释:把 a、b、c 都赋值为2。
注意:链式赋值的结合性是右结合性(从右至左的顺序进行计算)。举例:
```js
const a, b;
a = b = 3; // 先将 3 复制给 b再将 b 的值赋值给 a
const a1, a2;
a1 = a2 = 3; // 先将 3 复制给 a2再将 a2 的值赋值给 a1
```

View File

@ -46,11 +46,6 @@ console.log(typeof num2); // string
上方代码中,`num2`的结果是3.46,但是请注意,`num`的类型Number型而`num2`的类型却是String型。
另外需要注意的是,数字常量不能直接调 toFixed 方法。比如 `1.toFixed(2)`在 JS 中会引发语法错误。因为点号(.)被解释为数字字面量的一部分,而不是方法调用的分隔符。为了正确调用 toFixed 方法,可以使用括号或额外的点号。
toFixed()在这一点上,跟前面讲的 toString() 是类似的,推荐的做法是先把数字放到变量中存起来,然后通过变量调用 toFixed()。
## 内置对象 Math 的常见方法

View File

@ -1476,9 +1476,7 @@ console.log(arr2);
## filter()
### 语法
语法:
```js
const newArr = arr.filter((currentItem, currentIndex, currentArray) => {
@ -1490,8 +1488,6 @@ const newArr = arr.filter((currentItem, currentIndex, currentArray) => {
作用:对数组进行过滤。
### 举例
**举例 1**:找出数组 arr1 中大于 4 的元素,返回一个新的数组。代码如下:
```javascript
@ -1525,12 +1521,12 @@ console.log(JSON.stringify(arr2)); // 打印结果:[6,5,6]
```javascript
const arr1 = [
{ name: '许嵩', type: '一线' },
{ name: '周杰伦', type: '退居二线' },
{ name: '邓紫棋', type: '一线' },
{ name: '许嵩', type: '一线' },
{ name: '周杰伦', type: '退居二线' },
{ name: '邓紫棋', type: '一线' },
];
const arr2 = arr1.filter(item => item.type == '一线'); // 筛选出一线歌手
const arr2 = arr1.filter((item) => item.type == '一线'); // 筛选出一线歌手
console.log(JSON.stringify(arr2));
```
@ -1544,65 +1540,6 @@ console.log(JSON.stringify(arr2));
];
```
### 两端代码对比
仔细看看下面这两段代码,有什么区别。数组 arr2的打印结果是不一样的。
第一段代码:
```js
const arr1 = [
{
name: 'a',
num: 1,
},
{
name: 'b',
num: 2,
},
];
const arr2 = [];
const arr3 = dataList.filter(item => {
return item.num === 1;
arr2.push(item);
});
console.log(arr2);
```
第二段代码:
```js
const arr1 = [
{
name: 'a',
num: 1,
},
{
name: 'b',
num: 2,
},
];
const arr2 = [];
const arr3 = dataList.filter(item => {
if (item.num === 1) return item;
arr2.push(item);
});
console.log('smyhvae arr2:', arr2);
```
分析:
- 第一段代码的打印结果是 空数组 `[]`。因为`return` 语句位于回调函数的第一行,所以一旦执行就直接返回,导致后面的 `arr2.push(item);` 永远不会被执行,因此 `arr2` 始终为空。
- 第二段代码的打印结果是` [{ name: 'b', num: 2 }]`。由于 `return` 语句位于 `if` 语句内部,只有在特定条件下(`item.num === 1`)才会终止回调函数,否则 `arr2.push(item);` 仍然会被执行,因此 `arr2` 中会有值。
## reduce()
### reduce() 语法

View File

@ -1,36 +1,12 @@
---
title: 31-对象的高级操作
title: 31_1-对象的高级操作(待更新)
publish: false
---
<ArticleTopAd></ArticleTopAd>
## hasOwnProperty():判断对象中是否包含某个属性
hasOwnProperty() 是 Object 对象的一个方法,用于判断对象自身(即不包括从原型链继承来的属性)是否具有某个特定的属性。
语法:
```js
obj.hasOwnProperty(prop);
```
解释:
- obj 是要检查的对象。
- prop 是一个字符串,表示要检查的属性名。
返回值:如果对象 obj 自身包含名为 prop 的属性,则返回 true。否则返回 false。
举例:
```js
const obj = {a: undefined, b: 2, c: 3};
console.log(obj.hasOwnProperty('a')); // true
console.log(obj.hasOwnProperty('b')); // true
console.log(obj.hasOwnProperty('d')); // false
```
## Object.freeze() 冻结对象
@ -51,3 +27,6 @@ params.port = '8080';// 修改无效
```
上方代码中,把 params 对象冻结后,如果想再改变 params 里面的属性值,是无效的。