ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript を使用する際に知っておくべき細かい詳細
今回は、JavaScriptを使用する際に知っておくべき細かい点と、JavaScriptについて知っておくべき注意事項についてお届けします。実際の事例を見てみましょう。
break ステートメントと continue ステートメントには両方ともジャンプ機能があり、既存の順序からコードを実行できます。
break ステートメントは、コード ブロックまたはループから抜け出すために使用されます。
var i = 0; while(i < 100) { console.log('i 当前为:' + i); i++; if (i === 10) break; }
continue ステートメントは、現在のサイクルを直ちに終了し、ループ構造の先頭に戻り、次のサイクルを開始するために使用されます。
var i = 0; while (i < 100){ i++; if (i % 2 === 0) continue; console.log('i 当前为:' + i); }
break ステートメントと continue ステートメントに加えて、呼び出された関数から呼び出した関数に戻って実行を継続することを示す return ステートメントもあることに注意してください。return には戻り値を伴うことができ、これは次のように指定されます。リターン後のパラメータ。戻り後、関数は終了し、次のステートメントは実行されなくなります。
JavaScript 言語では、ステートメントの前にラベルがあり、これは任意の場所にジャンプするために使用されます。プログラムでは、ラベルには任意の識別子を使用できますが、予約語は使用できません。また、ステートメント部分には任意のステートメントを使用できます。
タグは通常、特定のループから抜け出すために、break ステートメントおよび continue ステートメントと組み合わせて使用されます。
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
ホイスティングのスコープは関数スコープと連動します。ここでは関数のスコープについて言及されていないことを理解していますが、読者に思い出していただくために言及し、さらに議論するためにスコープの部分にリンクします
「ホイスティングは var
で宣言された変数に対してのみ有効です」。必然的にそうなる。変数宣言のホイストだけがホイスティングのすべてではありません。JavaScript には、スコープ内で宣言をホイスティングするための 4 つの方法があります (優先順位順):
- this や引数などの言語定義の宣言。 this という変数をスコープ内で再定義することはできません。これは、言語によって自動的に定義されるステートメントであり、最も高い優先順位を持ち、つまり最上位に引き上げられ、誰もそれをオーバーライドできません
- 仮パラメータ。仮パラメータを変更するために var を使用する必要はありませんが、仮パラメータは確かに変数であり、自動的に次に高い優先順位
- 関数宣言に昇格します。 var に加えて、関数宣言でも新しい名前を定義でき、最初の 2 つに次いでスコープの先頭にホイストされます
- 最後に、この記事で説明されている通常の変数があります。これらは宣言された変数です。 var
JavaScript の内部では、整数であっても、すべての数値が 64 ビット浮動小数点数として格納されます。したがって、1 と 1.0 は同じであり、同じ数です。
これは、JavaScript 言語の末尾には整数がなく、すべての数値が 10 進数 (64 ビット浮動小数点数) であることを意味します。混乱しやすいのは、一部の操作は整数でのみ完了できることです。現時点では、JavaScript は操作を実行する前に 64 ビット浮動小数点数を 32 ビット整数に自動的に変換します。
浮動小数点数は正確な値ではないため、小数との比較や演算を行う場合は特に注意する必要があります。
0.1 + 0.2 === 0.3 // false 0.3 / 0.1 // 2.9999999999999996 (0.3 - 0.2) === (0.2 - 0.1) // false
精度は 2 進数 53 桁までです。つまり、2 の 53 乗以下、つまり -253 ~ 253 の絶対値を持つ整数を正確に表現できます。
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
上記のコードでは、値が 2 の 53 乗より大きくなると、整数演算の結果にエラーが表示され始めます。したがって、2 の 53 乗を超える値は精度を維持できません。 2 の 53 乗は 16 桁の 10 進数値であるため、単純なルールとして、JavaScript は 15 桁の 10 進数値を正確に処理できます。
Math.pow(2, 53) // 9007199254740992 // 多出的三个有效数字,将无法保存 9007199254740992111 // 9007199254740992000
規格によれば、64 ビット浮動小数点数の指数部の長さは 2 進数で 11 ビットです。つまり、指数部の最大値は 2047 (2 の 11 乗マイナス 1) になります。つまり、64 ビット浮動小数点数の指数部の最大値は 2047 です。その半分を割って負の数を表現すると、JavaScript が表現できる数値範囲は 21024 ~ 2 ~ 1023 になります(公開範囲)。 ) この範囲を超える数値は表現できません。
数値が 2 の 1024 乗以上の場合、「フォワード オーバーフロー」が発生します。つまり、JavaScript ではそのような大きな数値を表すことができず、Infinity が返されます。
Math.pow(2, 1024) // Infinity Math.pow(2, -1075) // 0
科学表記法に自動的に変換される数値の場合、parseInt は科学表記法表現を文字列として扱うため、奇妙な結果が生じます。
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浏览器怎么制作原生剪贴板
以上がJavaScript を使用する際に知っておくべき細かい詳細の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。