This time I will bring you the small details you must know when using JavaScript, and what are the precautions you must know about JavaScript. The following is a practical case, let’s take a look.
Both the break statement and the continue statement have a jump function, which allows the code to be executed out of the existing order.
The break statement is used to break out of a code block or loop.
var i = 0; while(i < 100) { console.log('i 当前为:' + i); i++; if (i === 10) break; }
The continue statement is used to immediately terminate the current cycle, return to the head of the loop structure, and start the next cycle.
var i = 0; while (i < 100){ i++; if (i % 2 === 0) continue; console.log('i 当前为:' + i); }
Note that in addition to the break and continue statements, there is also a return statement that indicates returning from the called function to the calling function to continue execution. The return can be accompanied by a return value, which is determined by the parameters after return. specified. After return, the function ends, and the following statements will no longer be executed.
JavaScript language allows, there is a label (label) in front of the statement, which is equivalent to the locator , used to jump to any location in the program. The label can be any identifier, but it cannot be a reserved word. The statement part can be any statement. The
tag is usually used in conjunction with the break statement and continue statement to jump out of a specific loop.
top: for (var i = 0; i < 3; i++){ for (var j = 0; j < 3; j++){ if (i === 1 && j === 1) break top; console.log('i=' + i + ', j=' + j); } } // i=0, j=0 // i=0, j=1 // i=0, j=2 // i=1, j=0
The scope of Hoisting follows the function scope. I understand that function scope has not been mentioned here, but I can mention it to remind readers, and then link to the scope part for further discussion;
"Hoisting is only for var
declared variables are valid", not necessarily. The hoisting of variable declarations is not all hoisting. JavaScript has four ways for declarations to be hoisted within the scope (in order of priority):
- Language-defined declarations, such as this and arguments . You cannot redefine a variable called this in the scope because this is a statement automatically defined by the language, and it has the highest priority, that is, it is hoisted to the top, and no one can overwrite it
-Formal parameters. Although we do not need to use var to modify formal parameters, formal parameters are indeed variables and are automatically promoted to the next highest priority
-function declaration. In addition to var, function declaration can also define new names, and will also be hoisted to the top of the scope, second only to the first two
-Finally, there is the regular variable mentioned in this article, which is the var declaration Variables
Internally in JavaScript, all numbers are stored as 64-bit floating point numbers, even integers. Therefore, 1 and 1.0 are the same and are the same number.
This means that there are no integers at the bottom of the JavaScript language, all numbers are decimals (64-bit floating point numbers). What is easily confusing is that some operations can only be completed with integers. At this time, JavaScript will automatically convert the 64-bit floating point number into a 32-bit integer and then perform the operation.
Since floating point numbers are not exact values, special care must be taken when comparing and performing operations involving decimals.
0.1 + 0.2 === 0.3 // false 0.3 / 0.1 // 2.9999999999999996 (0.3 - 0.2) === (0.2 - 0.1) // false
The accuracy can only be up to 53 binary digits, which means that integers with an absolute value less than or equal to 2 raised to the power of 53, that is, -253 to 253, can be accurately represented.
Math.pow(2, 53) // 9007199254740992 Math.pow(2, 53) + 1 // 9007199254740992 Math.pow(2, 53) + 2 // 9007199254740994 Math.pow(2, 53) + 3 // 9007199254740996 Math.pow(2, 53) + 4 // 9007199254740996
In the above code, after it is greater than 2 raised to the 53rd power, the results of integer operations begin to show errors. Therefore, any value greater than 2 raised to the 53rd power cannot maintain accuracy. Since 2 raised to the 53rd power is a 16-digit decimal value, the simple rule is that JavaScript can accurately handle 15-digit decimal numbers.
Math.pow(2, 53) // 9007199254740992 // 多出的三个有效数字,将无法保存 9007199254740992111 // 9007199254740992000
According to the standard, the length of the exponent part of a 64-bit floating point number is 11 binary bits, which means that the maximum value of the exponent part is 2047 (2 to the 11th power minus 1). In other words, the maximum value of the exponent part of a 64-bit floating point number is 2047. If half of it is divided to represent a negative number, the numerical range that JavaScript can represent is 21024 to 2-1023 (open range). Numbers beyond this range cannot be represented.
If a number is greater than or equal to 2 raised to the power of 1024, then "forward overflow" will occur, that is, JavaScript cannot represent such a large number, and Infinity will be returned.
Math.pow(2, 1024) // Infinity Math.pow(2, -1075) // 0
For numbers that are automatically converted to scientific notation, parseInt treats the scientific notation representation as a string, thus leading to some strange results.
parseInt(1000000000000000000000.5) // 1 // 等同于 parseInt('1e+21') // 1 parseInt(0.0000008) // 8 // 等同于 parseInt('8e-7') // 8
parseInt方法还可以接受第二个参数(2到36之间),表示被解析的值的进制,返回该值对应的十进制数。默认情况下,parseInt的第二个参数为10,即默认是十进制转十进制。
parseInt('1000', 2) // 8 parseInt('1000', 6) // 216 parseInt('1000', 8) // 512
isFinite方法返回一个布尔值,表示某个值是否为正常的数值。
isFinite(Infinity) // false isFinite(-Infinity) // false isFinite(NaN) // false isFinite(-1) // true
它的作用是操作同一个对象的多个属性时,提供一些书写的方便。
var obj = { p1: 1, p2: 2, }; with (obj) { p1 = 4; p2 = 5; } // 等同于 obj.p1 = 4; obj.p2 = 5;
注意,如果with区块内部有变量的赋值操作,必须是当前对象已经存在的属性,否则会创造一个当前作用域的全局变量。
var obj = {}; with (obj) { p1 = 4; p2 = 5; } obj.p1 // undefined p1 // 4
二进制或运算符(or):符号为|,表示若两个二进制位都为0,则结果为0,否则为1。
二进制与运算符(and):符号为&,表示若两个二进制位都为1,则结果为1,否则为0。
二进制否运算符(not):符号为~,表示对一个二进制位取反。
异或运算符(xor):符号为^,表示若两个二进制位不相同,则结果为1,否则为0。
左移运算符(left shift):符号为<<
右移运算符(right shift):符号为>>
带符号位的右移运算符(zero filled right shift):符号为>>>
void运算符的作用是执行一个表达式,然后不返回任何值,或者说返回undefined。
下面是一个更实际的例子,用户点击链接提交表单,但是不产生页面跳转。
<a href="javascript: void(document.form.submit())"> 提交 </a>
圆括号不是运算符,而是一种语法结构。它一共有两种用法:一种是把表达式放在圆括号之中,提升运算的优先级;另一种是跟在函数的后面,作用是调用函数。
简单的规则是,Number方法的参数是对象时,将返回NaN,除非是包含单个数值的数组。
Number({a: 1}) // NaN Number([1, 2, 3]) // NaN Number([5]) // 5
之所以会这样,是因为Number背后的转换规则比较复杂。
第一步,调用对象自身的valueOf方法。如果返回原始类型的值,则直接对该值使用Number函数,不再进行后续步骤。
第二步,如果valueOf方法返回的还是对象,则改为调用对象自身的toString方法。如果toString方法返回原始类型的值,则对该值使用Number函数,不再进行后续步骤。
第三步,如果toString方法返回的是对象,就报错。
String方法的参数如果是对象,返回一个类型字符串;如果是数组,返回该数组的字符串形式。
String({a: 1}) // "[object Object]" String([1, 2, 3]) // "1,2,3"
String方法背后的转换规则,与Number方法基本相同,只是互换了valueOf方法和toString方法的执行顺序。
先调用对象自身的toString方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
如果toString方法返回的是对象,再调用原对象的valueOf方法。如果valueOf方法返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
如果valueOf方法返回的是对象,就报错。
SyntaxError
对象是解析代码时发生的语法错误。
ReferenceError
对象是引用一个不存在的变量时发生的错误。
angeError
对象是一个值超出有效范围时发生的错误。主要有几种情况,一是数组长度为负数,二是Number对象的方法参数超出范围,以及函数堆栈超过最大值。
TypeError
对象是变量或参数不是预期类型时发生的错误。比如,对字符串、布尔值、数值等原始类型的值使用new命令,就会抛出这种错误,因为new命令的参数应该是一个构造函数。
URIError
对象是 URI 相关函数的参数不正确时抛出的错误,主要涉及encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()、escape()和unescape()这六个函数。
eval
函数没有被正确执行时,会抛出EvalError错误。该错误类型已经不再使用了,只是为了保证与以前代码兼容,才继续保留。
var err1 = new Error('出错了!'); var err2 = new RangeError('出错了,变量超出有效范围!'); var err3 = new TypeError('出错了,变量类型无效!'); err1.message // "出错了!" err2.message // "出错了,变量超出有效范围!" err3.message // "出错了,变量类型无效!"
try...catch结构允许在最后添加一个finally代码块,表示不管是否出现错误,都必需在最后运行的语句。
function cleansUp() { try { throw new Error('出错了……'); console.log('此行不会执行'); } finally { console.log('完成清理工作'); } } cleansUp() // 完成清理工作 // Error: 出错了……
map方法不仅可以用于数组,还可以用于字符串,用来遍历字符串的每个字符。但是,不能直接使用,而要通过函数的call方法间接使用,或者先将字符串转为数组,然后使用。
var upper = function (x) { return x.toUpperCase(); }; [].map.call('abc', upper) // [ 'A', 'B', 'C' ] // 或者 'abc'.split('').map(upper) // [ 'A', 'B', 'C' ]
其他类似数组的对象(比如document.querySelectorAll方法返回DOM节点集合),也可以用上面的方法遍历。
map方法还可以接受第二个参数,表示回调函数执行时this所指向的对象。
var arr = ['a', 'b', 'c']; [1, 2].map(function(e){ return this[e]; }, arr) // ['b', 'c']
如果数组有空位,map方法的回调函数在这个位置不会执行,会跳过数组的空位。
Array(2).map(function (){ console.log('enter...'); return 1; }) // [, ,]
reduce方法和reduceRight方法依次处理数组的每个成员,最终累计为一个值。
它们的差别是,reduce是从左到右处理(从第一个成员到最后一个成员),reduceRight则是从右到左(从最后一个成员到第一个成员),其他完全一样。
这两个方法的第一个参数都是一个函数。该函数接受以下四个参数。
累积变量,默认为数组的第一个成员
当前变量,默认为数组的第二个成员
当前位置(从0开始)
原数组
[1, 2, 3, 4, 5].reduce(function(x, y){ console.log(x, y) return x + y; }); // 1 2 // 3 3 // 6 4 // 10 5 //最后结果:15
Object.keys方法和Object.getOwnPropertyNames方法都用来遍历对象的属性。
Object.keys方法的参数是一个对象,返回一个数组。该数组的成员都是该对象自身的(而不是继承的)所有属性名。
Object.getOwnPropertyNames方法与Object.keys类似,也是接受一个对象作为参数,返回一个数组,包含了该对象自身的所有属性名。
对于一般的对象来说,Object.keys()和Object.getOwnPropertyNames()返回的结果是一样的。只有涉及不可枚举属性时,才会有不一样的结果。Object.keys方法只返回可枚举的属性,Object.getOwnPropertyNames方法还返回不可枚举的属性名。
var a = ['Hello', 'World']; Object.keys(a) // ["0", "1"] Object.getOwnPropertyNames(a) // ["0", "1", "length"]
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
navigator.clipboard浏览器怎么制作原生剪贴板
The above is the detailed content of Small details you must know when using JavaScript. For more information, please follow other related articles on the PHP Chinese website!