Skip to content

Commit

Permalink
feat: 变更daily目录README历史为倒叙排列,添加2019-08-26 每日一题
Browse files Browse the repository at this point in the history
feat: 变更daily目录README历史为倒叙排列,添加2019-08-26 每日一题
  • Loading branch information
azl397985856 authored Sep 10, 2019
2 parents 346b004 + 099439f commit 5cc13f6
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 36 deletions.
133 changes: 133 additions & 0 deletions docs/daily/2019-08-26.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# 每日一题 - 如何令a == 1 && a == 2 && a == 3 返回true?

### 信息卡片

- 时间:2019-08-26
- tag:`开放问题` `值比较`

### 问题描述

在 JavaScript 中, (a == 1 && a == 2 && a == 3) 是否有可能为 true ?

### 参考实现

参考解决思路:a是一个对象或函数,每次调用取值都不一样,以有序的规律变化就能实现多等

###### 方案一

使用getter存储器

``` js
var temp = 1;
Object.defineProperty(window, 'a', {
get: function() { // 每次取值,temp+1
return this.temp++
}
});
(a == 1 && a == 2 && a == 3); // true
(a === 1 && a === 2 && a === 3); // true
```

> 这个是使用`getter存储器`的方式,也就是以全局变量`temp`存储一个值,每次调用的时候都`++`1使得调用a每次都递增1
###### 方案二

重写valueOf() / toString()

``` js
var a = {
value: 1,
valueOf: function() {
return this.value++;
}
}
(a == 1 && a == 2 && a == 3); // true
```

**方案说明**

从表面看,应该是valueOf()每次都被调用了,但是为什么会这样?我们又没有调用它。

?> 这里的valueOf为什么会被调用?

* 原因参考`==转换规则`

1. 如果一个是null,一个是undefined,则它们相等

2. 如果一个是数字,一个是字符串,先将字符串转换成数字,然后使用转换后的值进行比较

3. 如果其中的一个值为true,则转换成1再进行比较;如果其中一个值为false,这转换成0再进行比较

4. 如果一个值是对象,另一个值是数字或者字符串,则将对象转换成原始值再进行比较。转换成字符串时,会先调用toString(),如果没有toString()方法或者返回的不是一个原始值,则再调用valueOf(),如果还是不存在或者返回不是原始值,则会抛出一个类型错误的异常。返回的原始值会被转换成字符串;如果转换成数字时,也是类似的,不过是会先调用valueOf(),再调用toString(),返回的原始值会被转换成数字

5. 其他不同类型之间的比较均不相等

> 所以在这里使用a与这些字符进行比较时会被转换成数字,此时会默认调用字符串的valueOf()方法,我们将这个方法进行重写,用于拦截处理a的值
* 同理可以使用toString方法处理,因为字符串转数字类型时会涉及到valueOf()和toString(),道理一样

``` js
let a = {
value: 1,
toString: function () {
return a.value++; // 这里为什么不用this而已a?因为this作用域可变
}
}
console.log(a == 1 && a == 2 && a == 3); // true
```

> 只要符合递增规则的,a就可以实现多等,因为此`a`非彼`a`
###### 方案三

ES6 Proxy

``` js
var a = new Proxy({ i: 0 }, {
get: (target, name) => name === Symbol.toPrimitive ? () => ++target.i : target[name],
});
console.log(a == 1 && a == 2 && a == 3); // true
```

###### 方案四

数字变量名

``` js
var a = 1;
var1 = a;
var2 = a;
var3 = a;
console.log( a ==1 && a ==2 && a ==3 );
```

###### 方案五:join + shift

* 对于对象数组进行比较时,这里数组a每次比较的时候都会默认调用toString(),然后toString()又会默认调用join(),这里将join()改为shift(),意思是删除第一个数组元素值并返回

* 所以这样调用每次都会导致a数组删除第一个值并且返回删除掉的那个值,结合这样的规律,每次比较都取出对应位置的值

* 这里是1、2、3,只要符合规律返回的值就行

``` js
var a =[1,2,3];
a.join = a.shift;
console.log(a); // (3) [1, 2, 3, join: ƒ]
// console.log( a ==ᅠ1 && a ==ᅠ2 && a ==ᅠ3 ); // true
console.log(a == 1); // true
console.log(a); // (2) [2, 3, join: ƒ]
console.log(a == 2); // true
console.log(a); // [3, join: ƒ]
console.log(a == 3); // true
console.log(a); // [join: ƒ]
```

### 扩展

* 由上面我们可以总结出一个规律,只要符合一个递增规律的,我们就可以实现对象多等

* 同理我们可以扩展到更多更复杂规律的对象比较中

### 参考文章

> [关于如何使(a === 1 && a === 2 && a === 3)返回true问题的思考](https://github.com/azl397985856/fe-interview/issues/cnblogs.com/shapeY/p/10183749.html) | [js 中怎么使 if(aᅠ==1 && a== 2 && ᅠa==3) 返回 true?](https://juejin.im/post/5c219e92e51d450d5a01aca7)
94 changes: 58 additions & 36 deletions docs/daily/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,84 +25,106 @@

### 历史汇总

#### [duplicate](./2019-07-22.md)
#### [如何令a ==1 && a== 2 && a==3 返回true?](./2019-08-26.md)

tag: `Array`
tag`开放问题` `值比较`

时间: 2019-07-22
时间2019-08-26

#### [以下四个promise有什么不同](./2019-07-25.md)
#### [不借助变量交换两个数](https://mp.weixin.qq.com/s/ki4Xgy0MJLe91HxxpKBFnQ)

tag: `ES6 ` `Promise`
tag`位运算` `开放问题` `数学`

时间: 2019-07-25
时间2019-08-23

#### [页面注入50万个li怎么做提升性能](./2019-07-26.md)
#### [100 * 100 的 Canvas 占内存多大](https://mp.weixin.qq.com/s/EGgsMBjGCG8l9JViYxvX3g)

tag: `性能优化` `开放问题`
tag`图像` `开放问题`

时间: 2019-07-26
时间2019-08-21

#### [如何设计一个对称加密算法](./2019-07-29.md)
#### [实现一个简单的移动端debug工具](./2019-08-14.md)

tag: `非对称加密` `加密算法`
tag`开放问题` `设计`

时间: 2019-07-29
时间2019-08-14

#### [找出字符串中连续出现最多的字符和个数](./2019-07-30.md)
#### [数值0的正负判断](./2019-08-13.md)

tag: `字符串` `连续`
tag: `Number`

时间: 2019-07-30
时间: 2019-08-13

#### [数据格式转化问题](./2019-07-31.md)
#### [base64 编码 会让源代码增加多少???](./2019-08-06.md)

tag: `DFS` `数据格式转化`
tag`base64`

时间: 2019-07-31
时间:2019-08-06

#### [数据格式转化问题](./2019-08-05.md)

tag: `格式` `对象`

时间:2019-08-05

#### [JS 中 Number 类型的可以表示的范围是多少](./2019-08-01.md)

tag: `Number` `二进制` `精度`

时间: 2019-08-01

#### [数据格式转化问题](./2019-08-05.md)
#### [数据格式转化问题](./2019-07-31.md)

tag: `格式` `对象`
tag: `DFS` `数据格式转化`

时间: 2019-07-31

#### [找出字符串中连续出现最多的字符和个数](./2019-07-30.md)

tag: `字符串` `连续`

时间: 2019-07-30

#### [如何设计一个对称加密算法](./2019-07-29.md)

tag: `非对称加密` `加密算法`

时间: 2019-07-29

#### [页面注入50万个li怎么做提升性能](./2019-07-26.md)

tag: `性能优化` `开放问题`

时间: 2019-07-26

#### [以下四个promise有什么不同](./2019-07-25.md)

tag: `ES6 ` `Promise`

时间: 2019-07-25

#### [duplicate](./2019-07-22.md)

tag: `Array`

时间: 2019-07-22

时间:2019-08-05

#### [base64 编码 会让源代码增加多少???](./2019-08-06.md)

tag:`base64`

时间:2019-08-06

#### [数值0的正负判断](./2019-08-13.md)

tag: `Number`

时间: 2019-08-13

#### [实现一个简单的移动端debug工具](./2019-08-14.md)

tag:`开放问题` `设计`

时间:2019-08-14

#### [100 * 100 的 Canvas 占内存多大](https://mp.weixin.qq.com/s/EGgsMBjGCG8l9JViYxvX3g)

tag:`图像` `开放问题`

时间:2019-08-21


#### [不借助变量交换两个数](https://mp.weixin.qq.com/s/ki4Xgy0MJLe91HxxpKBFnQ)

tag:`位运算` `开放问题` `数学`

时间:2019-08-23



0 comments on commit 5cc13f6

Please sign in to comment.