简体   繁体   English

了解 javascript 代码片段输出

[英]Understanding javascript code snippet outputs

Firstly sorry for such vague question, I couldn't think of title which make sense.首先很抱歉这个模糊的问题,我想不出有意义的标题。

I was trying to understand this line in JS (outputs: 12216520)我试图理解 JS 中的这一行(输出:12216520)

 color = +("0x" + color.slice(1).replace( 
    color.length < 5 && /./g, '$&$&'));

Can someone help me in understanding that how javascript is going to evaluate it?有人可以帮助我了解 javascript 将如何评估它吗?

I tried two snippet我尝试了两个片段

   color = +`0x${color}`.slice(1).replace( 
    color.length < 5 && /./g, '$&$&');

This gives null in console这在控制台中给出了 null

and

    color = "0x" + color.slice(1).replace( 
    color.length < 5 && /./g, '$&$&') + color;

This gives me 0xBA68C8 #BA68C8 in console这给了我控制台中的0xBA68C8 #BA68C8

Whereas the first snippet outputs this 12216520而第一个片段输出这个12216520

Code snippet for reference代码片段供参考

 console.log(lightOrDark('#BA68C8 ')) function lightOrDark(color) { var r, g, b, hsp; let co if (color.match(/^rgb/)) { color = color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/); r = parseInt(color[1]); g = parseInt(color[2]); b = parseInt(color[3]); } else { color = +("0x" + color.slice(1).replace( color.length < 5 && /./g, '$&$&')); r = color >> 16; g = color >> 8 & 255; b = color & 255; } hsp = Math.sqrt( 0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b) ); if (hsp>150) { return 'light'; } else { return 'dark'; } }

So, first of all, the and/or operators in Javascript can return things other than true or false .因此,首先,Javascript 中的 and/or 运算符可以返回truefalse以外的内容。 Javascript values can be "truthy" or "falsy", and if you chain a series of arguments with the && operator ( a && b && c && d ), the result of that operation will be the first argument in that chain that was falsy, or the last argument in the chain if none was. Javascript values can be "truthy" or "falsy", and if you chain a series of arguments with the && operator ( a && b && c && d ), the result of that operation will be the first argument in that chain that was falsy ,或者链中的最后一个参数,如果没有的话。 (It's easy to check from there that if you only pass true or false arguments, you get the expected result.) So, for a string whose length is 5 or greater, color.length < 5 && /./g is false , and for a string whose length is smaller, the result is /./g . (从那里很容易检查,如果你只传递truefalse arguments,你会得到预期的结果。)因此,对于长度为 5 或更大的字符串, color.length < 5 && /./gfalse ,并且对于长度较小的字符串,结果为/./g

Next, Javascript has a concept of "implicit conversions": when you use an operation with an argument that has the wrong type for that operation, it will try to convert the argument to that type if it's at all possible.接下来,Javascript 有一个“隐式转换”的概念:当您使用带有错误类型的参数的操作时,如果可能的话,它将尝试将参数转换为该类型。 In particular, the expression +a is not a string addition operation (that would be a + b ) but the positive equivalent of -b that changes a number's sign.特别是,表达式+a不是字符串加法运算(即a + b ),而是改变数字符号的-b的正等效项。 +a doesn't do any changing of the sign, but it expects a number as an argument, and so it tries to convert a to a number. +a不会对符号进行任何更改,但它需要一个数字作为参数,因此它会尝试将a转换为数字。 And in particular, if a is a string that starts with 0x , it will parse it as a hexadecimal number.特别是,如果a是以0x的字符串,它会将其解析为十六进制数。

So let's go now step by step:所以现在让我们一步一步来 go:

color  // "#BA68C8"
color.length  // 7
color.length < 5 && /./g  // false
color.slice(1)  // "BA68C8"
color.slice(1).replace(false, '$&$&')  // "BA68C8"
"0x" + color.slice(1).replace(false, '$&$&')  // "0xBA68C8"
+"0xBA68C8"  // 12216520 (the decimal equivalent to hexadecimal BA68C8)

Now, if the length of color is less than 5 (with "#FFF" , for example), the first argument to .replace is the RegExp /./g .现在,如果color的长度小于 5(例如,使用"#FFF" ), .replace的第一个参数是正则表达式/./g This matches every single character in a string.这匹配字符串中的每个字符。 And the replacement value contains $& , which is a special code which gets substituted by the matched string.并且替换值包含$& ,这是一个特殊的代码,它被匹配的字符串替换。 So:所以:

color  // "#ABC"
color.length  // 4
color.length < 5 && /./g  // /./g
color.slice(1)  // "ABC"
color.slice(1).replace(/./g, '$&$&')  // "AABBCC"
"0x" + color.slice(1).replace(/./g, '$&$&')  // "0xAABBCC"
+"0xAABBCC"  // 11189196 (the decimal equivalent to hexadecimal AABBCC)

Firstly, for the original snippet:首先,对于原始片段:

color = +("0x" + color.slice(1).replace( 
color.length < 5 && /./g, '$&$&'));

Basically it's using to convert from Hexadecimal string to Decimal number.基本上它用于将十六进制字符串转换为十进制数。 Here is how it's work:这是它的工作原理:

var color = '#BA68C8';
color = color.slice(1).replace(color.length < 5 && /./g, '$&$&'); // This use to remove the '#' character from hex string.
console.log(color); // BA68C8
color = "0x" + color; // This use to add '0x' prefix to indicate the hex number
console.log(color); // 0xBA68C8
color = +color; // Convert to Decimal, this is relative to parseInt(color)
console.log(color); // 12216520

In your 2 snippet.在你的 2 片段中。 The second one is nothing similar to the original snippet.第二个与原始片段没有任何相似之处。 While the first one gives null because you put the wrong variable in the braces.而第一个给出 null 因为你在大括号中放了错误的变量。 This is the right one:这是正确的:

color = +`0x${color.slice(1).replace( 
color.length < 5 && /./g, '$&$&')}`;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM