简单说 通过JS的隐式转换,关键时刻救你一命

说明

JavaScript在比较的时候,会进行隐式转换,你如果对隐式转换不是特别熟悉,结果往往出乎你的意料。
我们来看看这行代码

(![]+[])[+!![]- -+!![]- -+!![]]+({}+[])[+!![]]+(![]+[])[+!![]- -+!![]- -+!![]]

这行代码的结果可能出乎你的意料,看结果
这里写图片描述

结果居然是sos,这就是为什么会给文章这样一个题目了,这行代码看上去似乎是乱七八糟的,但是相信你看完这篇文章,一定能自己写出这样的代码来。

解释

相信我,这行代码是简单的,它并不复杂,我们先来分解一下这行代码

(![]+[])[+!![]- -+!![]- -+!![]]   //s
+  
({}+[])[+!![]]				      //o
+                
(![]+[])[+!![]- -+!![]- -+!![]]   //s

我们把这一行,分解成了3行了。

先看第一行
(![]+[])[+!![]- -+!![]- -+!![]]
这行还能分成两部分

(![]+[])		
[+!![]- -+!![]- -+!![]]

我们继续看这分开的两部分
(![]+[]) 看看这个是什么意思
友情提示:
[ ] 转为布尔值是 true
[ ] 转为字符串是 ""

如果想知道为什么,推荐看看下面的两篇文章。
简单说 JavaScript中的tostring( ) 与 valueOf( )方法
简单说 !![]==true 与 []==true 引发的思考

![ ] 就是false
(![]+[]) 会转为这个样子 (false+"") 结果就是"false",字符串类型的哦!

[+!![]- -+!![]- -+!![]]这个又是什么意思呢?
我们能看见 +!![] 这个东西是什么,居然出现了三次
+!![],!的优先级最高,先算 !![ ],!![ ] 是对 [ ]进行了布尔值的转换,最后结果就是true,最后在往前面来个+,就成了+true 这样,进行隐式转换,把true转为数字,就是1,好了,+!![] 就是 1 的意思,我们用1来替换一下代码,看看变成了什么样子[1- -1 - -1],我相信大家都能算出这么简单的正数 减 负数 减 负数 的结果来,所有最后的结果是[3]

好的,我们把第一行的这两个部分放在一起看看 "false"[3],这下明显了吧!字符串的第3个字符,这样就有s了

继续看第二行
({}+[]])[+!![]]
我们同样拆成两部分

({}+[]])
[+!![]]

第一部分 ({}+[])
( )里面的{},不是语法上的花括号,不是语句块的意思,而是表示了一个空对象,这里相加的时候会调用对象的toString()方法,所以它会转为"[object Object]",字符串类型的哦!
[ ],它同样也会调用toString()方法,所以[ ],会转为"",也就是一个空字符串。
这两个结果放在一起就是"[object Object]"+"" ,最后结果是"[object Object]"

第二部分 [+!![]]
上面我们已经知道+!![] 是 1 的意思,所以最后的结果就是[1]
好的,我们把第二行的这两个部分放在一起看看"[object Object]"[1],这样我们就看的很清楚了,o也有了

最后的第三行,和第一行一模一样,好的我们用 + ,把这三行的结果拼接起来就是 “sos” 了。

总结

最后用张图总结一下
这里写图片描述

相信现在,你应该是理解上面的代码了,写这个代码,也主要是想理解理解隐式转换,题目是开玩笑的,希望大家永远不会真的遇到需要这样的代码的关键时刻。
最后推荐两篇相关的文章,希望对大家有所帮助。
简单说 JavaScript中的tostring( ) 与 valueOf( )方法
简单说 !![]==true 与 []==true 引发的思考

### JavaScript 中 `value` 的定义及用法 在 JavaScript 中,`value` 是个通用术语,用来描述某个变量、属性或表达的具体数据内容。它可以是个基本类型的值(如数字、字符串、布尔值),也可以是复杂对象的个引用。 #### 基本类型中的 `value` 对于基本数据类型(number, string, boolean, null, undefined 等),它们的值是固定的,存储在内存栈中[^1]。例如: ```javascript let numValue = 42; // number 类型的值 let strValue = "Hello"; // string 类型的值 let boolValue = true; // boolean 类型的值 ``` 这些变量直接保存了具体的数值,而不是指向其他位置的引用。 #### 对象中的 `value` 当提到对象时,`value` 可能是指对象某属性的具体取值。通过点号操作符或者方括号语法访问对象属性时,返回的就是该属性对应的值[^3]。例如: ```javascript const obj = { key1: "value1", key2: 42, }; console.log(obj.key1); // 输出 "value1" console.log(obj["key2"]); // 输出 42 ``` 这里 `obj.key1` 和 `obj["key2"]` 都代表各自对应属性的实际值。 #### 方法调用中的含 `value` 些内置方法也会涉及如何处理其内部逻辑下的实际值。比如前面提及到的 `toString()` 和 `valueOf()` 方法,在不同场景下分别尝试获取目标实体作为字符串表现形或是原始值的表现形[^2]。下面展示了个例子明两者差异: ```javascript const customObj = { toString: function () { return "[Custom Object]"; }, valueOf: function () { return 10; } }; // 使用加法规则触发转换 console.log(customObj + ""); // 调用了 toString(), 结果为 "[Custom Object]" console.log(+customObj); // 调用了 valueOf(), 结果为 10 ``` 上述代码片段展示了当运算符期望得到不同类型的操作数时,默认行为会选择合适的方去提取有效负载——即所谓的“值”。 #### 自定义函数参数传递中的 `value` 在创建自定义函数过程中,形参本质上是用来接收实参传入的那个特定时刻所携带的信息副本或者映射关系;而这个被赋予给形参的内容正是我们所的那个外部提供的‘值’[^4]。如下所示简单的验证密码长度案例里头,用户输入框内的文字串就是最终成为校验算法入口处的关键 input 参数之真实体现: ```html <input type="password" id="pwdInput"> <button onclick="checkPassword()">Check</button> <script> function checkPassword() { const pwdElement = document.getElementById('pwdInput'); let inputValue = pwdElement.value; if (inputValue.length >= 8 && inputValue.length <= 16){ alert("Valid password!"); }else{ alert("Invalid password length."); } } </script> ``` 在这个 HTML 片段中,`pwdElement.value` 提取出 `<input>` 元素当前包含的文字序列并赋给了局部变量 `inputValue` ,随后依据设定条件完成相应提示动作。 ---
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值