このシリーズはRuan Yifeng氏のまたは "JavaScript tutorial "の記録組織、下でのチュートリアルを基にしています。このチュートリアルはjsを学ぶための最高のチュートリアルの一つです!
最高のチュートリアルと教師阮依峰オープンソースの方法を共有するために、もう一度再記録する理由は、1つは、もう一度学ぶために慎重に再読する自分自身を強制することです!
演算子
算術演算子
- jsは10オペレータを提供します。
- 加算演算子:
x + y - 減算演算子: x - y
- 乗算演算子:
x * y - 演算子は
x * y - 指数演算子:
x ** y - 剰余演算子: x % y
- 自己増加演算子: ++x または x++
- 自己減少演算子:--xまたはx--。
- アルゴリズム
x * y - 負の数値演算子:-x
- jsでは、ブーリアン値や数値など、数値以外の値を追加することができ、文字列の追加は2つの文字列を連結するために使用されます。
true + true // 2
1 + true // 2
1 + 'a' // "1a"
false + 'a' // "falsea"
加算演算子は、実行時に和を取るか連結を取るかを決定するために使われます。演算子の違いにより、構文の振る舞いが異なります。
'3' + 4 + 5 // "345"
3 + 4 + '5' // "75"
加算演算子にはオーバーロードがあります。すべての演算子は数値に変換され、対応する数学演算が実行されます。
- オブジェクトの合計:演算子がオブジェクトの場合、元の型の値に変換してから合計します。
元の型に変換されたオブジェクトのデフォルト値は[object Object]です。
var obj = { p: 1 };
obj+5 // "[object Object]5"
オブジェクトはプリミティブ型の値に変換されます。
- オブジェクトの valueOf メソッドを自動的に呼び出します。オブジェクトのvalueOfメソッドはデフォルトでオブジェクト自身を返します。
- 文字列に変換するには、もう一度 toString メソッドを呼び出します。オブジェクトに対する toString メソッドは、デフォルトで [object Object] を返します。
valueOfメソッドまたはtoStringメソッドをカスタマイズして、オブジェクトの加算結果を変更します。
obj.valueOf() // {p: 1}
obj.valueOf().toString() // "[object Object]"
obj.valueOf=function () {
return 1;
}
obj+5 // 6
唯一の特別なケースは、演算子が Date オブジェクトの場合は toString メソッドが優先されるということです。
var obj = new Date();
obj.valueOf = function () { return 1 };
obj.toString = function () { return 'hello' };
obj + 5 // "hello5"
- 剰余演算子は、前の演算子を次の演算子で割った余りを返します。結果のプラス記号かマイナス記号かは、最初の演算子によって決まります。
-1 % 2 // -1
1 % -2 // 1
絶対値は、負の数の正しい余り値を得るために使用できます。
// 正しい書き方は
function isOdd(n) {
return Math.abs(n % 2) === 1;
}
isOdd(-5) // true
isOdd(-4) // false
- 自己インクリメント演算子と自己デクリメント演算子は単項演算子で、演算子は1つだけです。
演算後に変数の値が変化することを演算の副作用といいます。自己インクリメント演算子と自己デクリメント演算子だけが副作用を持つ演算子です。
変数の後にオートインクリメント/デクリメントが置かれた場合、変数操作の前に値を返し、その後オートインクリメント/デクリメント操作を行います 変数の後にオートインクリメント/デクリメントが置かれた場合、オートインクリメント/デクリメント操作を先に行い、変数操作の後に値を返します
- 数値演算子は、あらゆる値を数値に変換します。
数値を負の数値に変換する負の数値演算子。
は元の変数の値を変更せず、新しい値を返します。
- 指数演算子で指数演算が完結
指数演算子は左抱合ではなく右抱合です。つまり、複数の指数演算子を併用する場合は、右端の計算が最初に実行されます。
// 相当于 2 ** (3 ** 2)
2 ** 3 ** 2 // 512
- 代入演算子は変数に値を代入するために使用します。x += y, x -= y のような複合代入演算子もあります。
比較演算子
- 比較演算子は2つの値の大きさを比較し、ブール値を返します。
- > より大きい演算子
- < より小さい演算子
- < Konariアルゴリズム
- >= 演算子
- == 等価演算子
- === 厳密な等号演算子
- != 不等号演算子
- !== 厳密には不等号演算子
- 等価比較と非等価比較。
等価でない比較の場合、アルゴリズムは両方の演算子が文字列かどうかを調べ、文字列の場合は辞書順に比較し、そうでない場合は両方の演算子を数値に変換してから数値の大きさを比較します。
- 等号演算子は2つの値が等しいかどうかを比較し、厳密等号演算子は2つの値が「同じ値」であるかどうかを比較します。
2つの値が同じ型でない場合、厳密等号演算子===は偽を返しますが、等号演算子==は同じ型に変換してから比較します。
- 厳密な等号演算子:異なる型は偽を返し、同じ型のプリミティブ値は等しいかどうか比較され、複合値は同じアドレスを指すかどうか比較され、未定義とNULLはそれ自身と厳密に等しい。
2つのオブジェクトを比較する場合、厳密な等号演算子はアドレスを比較し、大なり小なり演算子は値を比較します。
var obj1 = {};
var obj2 = {};
obj1 > obj2 // 比较的是值 false
obj1 < obj2 // 比较的是值 false
obj1 === obj2 // 比较的是地址 false
等価演算子の比較は暗黙のうちに型変換されるため、厳密には等価演算子のみを使用することをお勧めします。
ブール演算子
- ブール演算子は、式をブール値に変換するために使用します。4つの演算子があります。
- 反転演算子: !
- 演算子: &&
- またはオペレーター:
- 三項演算子: ?:
- 逆演算子は、ブール値を反対の値に変更します。2回反転させるのは、値をブール値に書き換える簡単な方法です。
- 演算子 && は、複数の式を評価するためによく使われます。
演算子 && は、第一演算子のブール値が真の場合は第二演算子の値を返し、第一演算子のブール値が偽の場合は第一演算子の値を返し、第二演算子は評価しません。
if文の代わりに&&や演算が使えます。
if (i) {
doSomething();
}
//
i && doSomething();
- or 演算子 () は、複数の式を評価するためにも使われます。
or演算子のルールは次のとおりです。1番目の演算子のブール値がtrueの場合、1番目の演算子の値が返され、2番目の演算子の値は求められません。
or 演算子は、変数のデフォルト値を設定するときによく使われます。
function saveText(text) {
text = text || '';
// ...
}
// あるいは、次のように書くこともできる。
saveText(this.text || '')
- and演算子やor演算子は、1つ目の式の値が2つ目の式を実行するかどうかを制御するメカニズムで、「短絡」と呼ばれています。
- 三項条件演算子は、3つのオペランドを必要とするjsの唯一の演算子です。
ブール演算子
- 2進ビット演算子は、2進ビットに直接計算を実行するために使用され、そのうちの7つがあります。
- 二項演算子:符号は、二進ビットが両方とも0の場合、結果は0であり、そうでない場合は1であることを示します。
- 2進数と演算子:記号&は、2進数のビットが両方とも1であれば結果は1、そうでなければ0であることを示します。
- 二項演算子:記号~は二項ビットの逆数を表します。
- Different-or 演算子: 記号 ^ は、2 つの 2 進ビットが同じでない場合、結果が 1 になり、そうでない場合は 0 になることを示します。
- 左シフト演算子:記号 <<.
- 右シフト演算子:記号 >>。
- ヘッダゼロ補数右シフト演算子:記号 >>>、記号
- ビット演算子は整数に対してのみ動作します。 演算子が整数でない場合、自動的に整数に変換されます。JavaScript 内では値は 64 ビット浮動小数点数として保存されますが、ビット演算は 32 ビット符号付き整数に対して実行され、戻り値は 32 ビット符号付き整数となります。
このプロパティを使うと、任意の値を32ビット整数に変換する関数を書くことができます。
function toInt32(x) {
return x | 0;
}
- ビット演算子は、オブジェクトのプロパティを設定するスイッチとして使用できます。
あるオブジェクトに4つのスイッチがあり、それぞれが変数であるとします。a,b,c,dは4つのスイッチで、それぞれが1つの2進数ビットを占めます。
var FLAG_A = 1; // 0001
var FLAG_B = 2; // 0010
var FLAG_C = 4; // 0100
var FLAG_D = 8; // 1000
- 指定されたスイッチが現在の設定でオンになっているかどうかをバイナリ和演算でチェックします。
var flags = 5; // バイナリ 0101
// スイッチCがオンになっているかチェックする
if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
// ...
}
- A、B、Dスイッチをオンにする必要があると仮定すると、マスク変数を構築し、バイナリまたは算術マスク変数を使用して、3つのスイッチを確実にオンにすることができます。
var mask = FLAG_A | FLAG_B | FLAG_D;
// 0001 | 0010 | 1000 => 1011
flags = flags | mask; // 3つのスイッチがすべてオンになっているバイナリビットを表す変数
- 二進法と算術は、現在の設定のうち、スイッチの設定と異なる項目をすべてオフにすることができます。
flags = flags & mask;
- つまり、最初の実行で現在の設定と反対の値を取得し、再度実行することで元の値を取得することができます。
flags = flags ^ mask;
- バイナリ否定は、現在の設定を反転させることができます。
flags = ~flags;
void とコンマ演算子
- void 演算子は式を実行し、値を返さない、あるいは未定義を返します。
void 0 // undefined
void(0) // undefined 推奨される書き方
void 演算子の優先順位は高いので、エラーを避けるには括弧を使います。
var x = 3;
void (x = 5) //undefined
x // 5
- void 演算子の主な用途は、ブラウザのブックマークツールと、ウェブページのジャンプを防ぐためのハイパーリンクへのコード挿入です。
以下のコードでは、リンクをクリックした後、まずonclickを実行し、次にfalseを返すので、ブラウザは次のページにジャンプしません。
<script>
function f() {
console.log('Hello World');
}
</script>
<a href="http://.om"&;ck="f();&;&;se;"> </>
上記の代わりにvoid演算子を書くこともできます。
<a href="javascript: void(f())"> </a>
あるいは、ページジャンプを生成せずにフォームを送信するリンクを実装します。
<a href="javascript: void(document.form.submit())">
</a>
- カンマ演算子は、2 つの式を評価し、後者の値を返すために使用します。
'a', 'b' // "b"
var x = 0;
var y = (x++, 10);
x // 1
y // 10
用途は、値を返すことと、いくつかの補助的な操作を行うことです。
var value = (console.log('Hi!'), true);
// Hi!
value // true
操作の順序
- 優先順位の高い演算子から実行
- 括弧()は操作の優先順位を上げるために使用します。つまり、括弧内の式が最初の操作になります。
括弧は演算子ではなく、構文の構成要素です。括弧を使うには2つの方法があります。1つは括弧の中に式を入れる方法で、これにより演算の優先順位が上がります。
括弧で囲まれた関数は、その関数自身を返します。関数の直後の括弧は、その関数の呼び出しを表します。
括弧の中に入れることができるのは式だけです。
Operator Precedenceleft union" ( ) 演算子は左から右へ、"right union" ( ) 演算子は右から左へ動作します。
代入演算子、三項演算子、指数演算子は、jsでは「右共役」です。
構文
データ型の変換
- JavaScriptは動的型付け言語であり、変数の型はコンパイル時には決定できず、実行時に知る必要があります。同時に、jsの変数の型は自由に変更することができるので、弱く型付けされた言語です。
- JSの演算子にはデータ型の要件があります。その結果、自動的な型変換がしばしば発生します。
- 強制型変換とは、主にNumber()、String()、Boolean()を使用して、それぞれ任意の型の値を数値、文字列、ブール値に手動で変換することを指します。
- Number() は数値に変換します。parseInt 関数よりも厳格です。
- 元の型の値を変換
// 数値:変換後の元の値
Number(324) // 324
// 文字列:数値としてパースできる場合、対応する値に変換される。
Number('324') // 324
// 字符串:如果不可以被解析为数值,返回 NaN
Number('324abc') // NaN
// 空文字列を0にする
Number('') // 0
// 布尔值:true 转成 1,false 转成 0
Number(true) // 1
Number(false) // 0
// undefined:转成 NaN
Number(undefined) // NaN
// null0に変換する
Number(null) // 0
// スペースを無視する
Number('\t\v
12.34
') // 12.34
- オブジェクトを変換するときのルールは次のとおりです。最初のステップでは、オブジェクト自身のvalueOfメソッドを呼び出します。元の型の値が返された場合は、その値に対して直接 Number 関数が使用され、それ以上の処理は行われません。第 2 段階では、valueOf メソッドがオブジェクトを返す場合、そのオブジェクト自体の toString メソッドを呼び出します。toString メソッドが元の型の値を返す場合は、それ以上の手順を踏むことなく、その値に対して Number 関数を使用します。第 3 に、toString メソッドがオブジェクトを返す場合、エラーが報告されます。
カスタム valueOf または toString。
Number({
valueOf: function () {
return 2;
}
})
// 2
Number({
toString: function () {
return 3;
}
})
// 3
Number({
valueOf: function () {
return 2;
},
toString: function () {
return 3;
}
})
// 2
- String() は、以下の規則に従って文字列を変換します:
元の型の値 Numeric: 対応する文字列。文字列:元の値。Boolean: true-"true"、false-"false"。undefined: "未定義"。null: "null".
オブジェクト Stringパラメータは、オブジェクトの場合は文字列型、配列の場合は配列の文字列型を返します。
String({a: 1}) // "[object Object]"
String([1, 2, 3]) // "1,2,3"
変換ルールは以下の通りです:まず、オブジェクト自身のtoStringメソッドを呼び出します。元の型の値が返された場合、その値には String 関数を使用し、次のステップには進みません。2番目のステップでは、toStringメソッドがオブジェクトを返す場合、元のオブジェクトのvalueOfメソッドを呼び出します。valueOfメソッドが元の型の値を返す場合は、その値に対してString関数を使用し、次のステップは実行しません。第 3 に、valueOf メソッドがオブジェクトを返す場合、エラーが報告されます。
String({
toString: function () {
return 3;
}
})
// "3"
String({
valueOf: function () {
return 2;
}
})
// "[object Object]"
String({
valueOf: function () {
return 2;
},
toString: function () {
return 3;
}
})
// "3"
- Boolean()はブール値に変換されます。ルールは単純で、以下の6つの値がfalseになる以外は、残りはすべてtrueです。
undefined、null、NaN、''、false
- jsのデータ型自動変換は次のように行われます:第一に、異なるデータ型が互いに演算するときに自動的に変換されます。第二に、非ブール値型のデータに対してブール値を求める場合。第三に、単項演算子を使用した数値型以外の値の場合。変換時のルールは、どのような型の値が期待されているか、その型の変換関数を呼び出すことです。位置が文字列と数値の両方になり得る場合、デフォルトの変換は数値になります。
- JavaScript は、ブール値が期待される場合、ブール値でない引数を自動的にブール値に変換します。ブール関数はシステム内部で自動的に呼び出されます。
次の2つのメソッドは、式をブール値に変換します。
//
expression ? true : false
//
!! expression
- 演算子を文字列に変換する可能性がある加算演算子を除いて、他の演算子は自動的に演算子を値に変換します。
ヌル値、未定義値 NaN
エラー処理メカニズム
- JavaScriptはネイティブでErrorコンストラクタを提供しており、スローされるエラーはすべてこのコンストラクタのインスタンスです。エラーが発生すると、jsエンジンはErrorインスタンスオブジェクトをスローし、エラーが発生した時点でプログラム全体が壊れ、それ以上先に進みません。
var err = new Error(' ');
err.message // " "
- エラーインスタンスのプロパティ
- message: エラーメッセージ
- nameエラー名
- stackエラースタック
function throwit() {
throw new Error('');
}
function catchit() {
try {
throwit();
} catch(e) {
console.log(e.stack); // print stack trace
}
}
catchit()
// Error
// at throwit (<anonymous>:2:9)
// at catchit (<anonymous>:7:5)
// at <anonymous>:1:1
- Errorのインスタンスは最も一般的なエラータイプで、jsはErrorの派生オブジェクトを6つ提供しています。
- SyntaxError オブジェクト: コード解析時に発生する構文エラー
- ReferenceErrorオブジェクト:存在しない変数を参照した際に発生するエラー。
- RangeError オブジェクト: 値が有効範囲外の場合に発生するエラー。
- TypeError オブジェクト: 変数やパラメータが期待された型でない場合に発生するエラー。
- URIError オブジェクト: URI 関連関数の引数が正しくない場合にスローされるエラー。
encodeURIComponent()decodeURIComponent()主に encodeURI(), decodeURI(), , escape(), unescape() です。 - EvalError オブジェクト: 使用されなくなりました。
- stackエラースタック
function UserError(message) {
this.message = message || 'デフォルトのメッセージ';
this.name = 'UserError';
}
UserError.prototype = new Error();
UserError.prototype.constructor = UserError;
- throw文:手動でプログラムの実行を中断し、エラーをスローします。
if (true) {
throw new Error('x 正の数でなければならない');
}
// Uncaught Error: x 正の数でなければならない
// at <anonymous>:2:9
- try....catch構造は、エラーを処理し、先に進むかどうかを選択するために使用されます。
try {
throw new Error(' !');
} catch (e) {
console.log(e.name + ": " + e.message);
console.log(e.stack);
}
// Error: !
// at <anonymous>:3:9
// ...
catch ブロックは、さまざまな種類のエラーをキャッチするための判定文を追加します。
try {
foo.bar();
} catch (e) {
if (e instanceof SyntaxError) {
console.log(e.name + ": " + e.message);
} else if (e instanceof RangeError) {
console.log(e.name + ": " + e.message);
}
// ...
}
try...catch...finally構造体内のコードのfinallyブロックは、エラーの発生に関係なく、最後に実行されます。
function cleansUp() {
try {
throw new Error('エラー ......');
console.log('この行では');
} finally {
console.log('クリーンアップを完了する');
}
}
finallyブロックの前にreturn文があっても、finallyブロックは実行され、returnされます。
function idle(x) {
try {
console.log(x);
return 'result';
} finally {
console.log('FINALLY');
}
}
idle('hello')
// hello
// FINALLY
return文はfinallyコードの中で実行され、finallyの実行が終わるまで待ってからfinallyに戻ります。
var count = 0;
function countUp() {
try {
return count;
} finally {
count++;
}
}
countUp()
// 0
count
// 1
最終ブロックの典型的なシナリオ
openFile();
try {
writeFile(Data);
} catch(e) {
handleError(e);
} finally {
closeFile();
}
プログラミングスタイル
- 「プログラミング・スタイル」とは、コードを書くときのスタイル・ルールのことです。
- プログラミングのスタイルで考慮すべき主なポイント:インデント、ブロック、括弧、行末のセミコロン、変数宣言、厳密な等号、文の併記など。
- ブロックを使用する場合は、同じ行の文の直後に左中括弧 js { を使用し、別の行には書かないでください。これは、**JavaScriptが自動的に文末にセミコロンを追加する**ためで、見づらいエラーが発生します。
block {
// ...
}
次の return 文は実際には 2 つの文になり、問題になることがあります。
return
{
key: value
};
//
return;
{
key: value
};
// 正しい書き方は
return {
key : value
};
- 行末のセミコロン:セミコロンは文の終わりを表します。
構文上、最後にセミコロンを付ける必要がないケースが3つあります。セミコロンをつけると、jsエンジンはセミコロンを空文として解釈します。
- for およびwhileループ
for ( ; ; ) {
} // セミコロンはない
while (true) {
} // セミコロンはない
しかし....whileにはセミコロンが必要です
- 分岐ステートメント: if、switch、try
if (true) {
} // セミコロンはない
switch () {
} // セミコロンはない
try {
} catch {
} // セミコロンはない
- 関数宣言文
function f() {
} // セミコロンはない
関数式でもセミコロンを使用する必要があります。
var f = function f() {
};
この3つの場合を除き、すべての文にはセミコロンを使用します。
Automatic Semicolon InsertionJavaScriptでは、セミコロンがない場合は自動的にセミコロンを追加します。これは「自動セミコロン追加」(ASI)と呼ばれる構文機能です。
しかし、JavaScriptは、次の行の先頭が行末と連動して解釈できる場合、自動的にセミコロンを追加しません。
また、セミコロンが自動的に追加されるかどうかは予測不可能で、さらなるエラーを引き起こす可能性があります。
最後のセミコロンを省略してはいけない理由はもう一つあります。JavaScriptのコード圧縮ソフトの中には、自動的にセミコロンを追加しないものがあります。そのため、セミコロンのない終了に遭遇すると、コードを1行に圧縮するのではなく、そのままにしてしまい、圧縮が最適でなくなってしまうのです。
また、閉じるセミコロンを書かないと、スクリプトのマージエラーが発生することがあります。そのため、一部のコードベースでは、ステートメントの最初の行の前にセミコロンを追加しています。これにより、他のスクリプトとマージしたときに、前のスクリプトのステートメントの最後の行にセミコロンがなく、実行時エラーになるという問題を回避することができます。
;var a = 1; // ...
- グローバル変数の使用は避け、どうしても使いたい場合は大文字にすることを検討してください。
- 変数宣言は、変数リフティングの存在により、多くのステートメントでグローバル変数が作成されます。
関数はすべて使用時に定義する必要があります。関数内の変数宣言は、すべて関数のヘッダーに記述します。
- 厳密な等号演算子のみを使用することをお勧めします。
- スイッチ...ケース構造をオブジェクト構造に置き換えることができます。
コンソールオブジェクトとコンソール
- consoleオブジェクトはJavaScriptのネイティブオブジェクトで、コンソールに様々な情報を出力します。
- コンソールの一般的な使い方: プログラムのデバッグ、ウェブコードの実行中のエラーメッセージの表示、ウェブコードと対話するためのコマンドラインインターフェイスの提供。
- 開発者ツールのいくつかのパネル。
- 要素:WebページのHTMLソースコードとCSSコードを表示します。
- リソース:ウェブページによって読み込まれた様々なリソースファイルと、ハードドライブ上に作成された様々なコンテンツを表示します。
- ネットワーク:ウェブページのHTTP通信を表示します。
- ソース:ウェブページに読み込まれたスクリプトのソースコードをブレークポイントデバッグで表示します。
- タイムライン: ウェブページの様々な動作を時系列で表示します。
- パフォーマンス:CPUやメモリの消費量など、ウェブページのパフォーマンスを表示します。
- コンソール:つまり、jsコマンドを実行するために使用されるコンソール、およびjsコードのコンソールメソッド出力内のページです。
- console.log(), console.info(), console.debug()
console.warn()JSON.stringify.error()- console.table()
- console.count()
- debugger 文は主にデバッグに使用され、ブレークポイントを設定します。
標準ライブラリ
以下は、基本的にjsネイティブオブジェクトの紹介です。
オブジェクトオブジェクト
- JavaScript は Object オブジェクトをネイティブに提供します。
- JavaScript の他のすべてのオブジェクトは Object オブジェクトを継承しており、Object のインスタンスです。
- Objectオブジェクトのネイティブメソッドは、Object自体のメソッドとObjectのインスタンスのメソッドの2つに分けられます。
- Objectオブジェクト自体のメソッド:Objectオブジェクトに直接定義されたメソッド
- Objectのインスタンスメソッド: Object.prototypeオブジェクトに定義されたメソッド。Object インスタンスで直接使用できます。
// メソッド自体は
Object.selfPrint = function (o) { console.log(o) };
// インスタンス・メソッド
Object.prototype.print = function () {
console.log(this);
};
var obj = new Object();
obj.print() // Object
- Object自体は、任意の値をオブジェクトに変換するツールメソッドとして使用できる関数です。値はオブジェクトでなければならないことが保証されています。
- パラメータのないオブジェクト・メソッド、または未定義、NULL、空のオブジェクトを返すメソッド。
var obj = Object();
//
var obj = Object(undefined);
var obj = Object(null);
obj instanceof Object // true
パラメータがプリミティブ型の場合、プリミティブ型の値を対応するラップされたオブジェクトのインスタンスに変換します。
引数がオブジェクトの場合、そのオブジェクトが返されます。
var arr = [];
var obj = Object(arr); // 元の配列を返す
obj === arr // true
var value = {};
var obj = Object(value) // 元のオブジェクトを返す
obj === value // true
var fn = function () {};
var obj = Object(fn); // 元の関数を返す
obj === fn // true
- 変数がオブジェクトかどうかの判定
function isObject(value) {
return value === Object(value);
}
isObject([]) // true
isObject(true) // false
- instanceof 演算子は、オブジェクトが指定されたコンストラクタのインスタンスであることを確認します。
- オブジェクトのコンストラクタは、新しいオブジェクトを生成するために使用されます。
var obj = new Object();
//
var obj = {};
- オブジェクト・コンストラクタは、ツール・メソッドに似ています。引数がオブジェクトの場合、オブジェクトが直接返されます。引数がプリミティブ型の値の場合、その値に対応するラッパーオブジェクトが返されます。
- オブジェクトの静的メソッド
Object.getOwnPropertyNames()Object.keys() は、オブジェクトのプロパティを走査します。Object.getOwnPropertyNamesObject.keys メソッドは列挙可能な属性のみを返し、列挙不可能な属性名も返します。
通常、Object.keys を使用してオブジェクトのプロパティを走査します。
オブジェクトの属性数のカウント
var obj = {
p1: 123,
p2: 456
};
Object.keys(obj).length // 2
Object.getOwnPropertyNames(obj).length // 2
- Objectインスタンスオブジェクトのメソッド。
Object.prototype.valueOf()デフォルトではオブジェクトそのものです。Object.prototype.toString()デフォルトの戻り値は string 型です。Object.prototype.toLocaleString()現在のオブジェクトに対応するローカル文字列フォームを返します。Object.prototype.hasOwnProperty()プロパティが現在のオブジェクト自身のプロパティであるか、プロトタイプオブジェクトから継承されたプロパティであるかを判断します。Object.prototype.isPrototypeOf()現在のオブジェクトが他のオブジェクトのプロトタイプであるかどうかを判定します。Object.prototype.propertyIsEnumerable()プロパティが列挙可能かどうかを判断します。
Object.prototype.toString配列、文字列、関数、および Date オブジェクトには、このメソッドをオーバーライドするカスタムの toString メソッドがあります。
[1, 2, 3].toString() // "1,2,3"
'123'.toString() // "123"
(function () {
return 123;
}).toString()
// "function () {
// return 123;
// }"
(new Date()).toString()
// "Fri Jul 31 2020 GMT+0800 (日本標準時)"
- データ型の決定
データ型を正しく判定する方法については、typeofは数値型、文字列型、ブーリアン型、未定義型しか正確に返せず、オブジェクト型は返せないので、型を正確に判定するためには使えません。また、継承されたオブジェクトに対するinstanceofは、現在のオブジェクトのインスタンスを判定してtrueを返すことに加えて、継承された上位のオブジェクトのインスタンスを判定してもを返すので、基本的な型ではなく、オブジェクトのインスタンスかどうかだけを判断することができます。
Object.prototype.toStringつまり、値の型を決定する最も正確な方法は、 オブジェクトの型文字列を返すメソッドを 使うことです。
以下のように、空のオブジェクトのtoStringメソッドは文字列オブジェクトObjectを返し、2番目のObjectは現在値のコンストラクタを表します。
var obj = {};
obj.toString() // "[object Object]"
Object.prototype.toString.call(value) // valueの値に対してObjectを呼び出す.prototype.toString
Object.prototype.toString値の型を確認することは可能です。以下のように、typeof演算子よりも正確な型判定関数を実装します。
var type = function (o){
var s = Object.prototype.toString.call(o);
return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};
type({}); // "object"
type([]); // "array"
type(5); // "number"
type(null); // "null"
type(); // "undefined"
type(/abcd/); // "regex"
type(new Date()); // "date"
特定のタイプを決定するメソッドを実装します:
var type = function (o){
var s = Object.prototype.toString.call(o);
return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};
['Null',
'Undefined',
'Object',
'Array',
'String',
'Number',
'Boolean',
'Function',
'RegExp'
].forEach(function (t) {
type['is' + t] = function (o) {
return type(o) === t.toLowerCase();
};
});
type.isObject({}) // true
type.isNumber(NaN) // true
type.isRegExp(/abc/) // true
- toLocaleString() は、独自のローカル文字列を実装するために使用します。
Array.prototype.toLocaleString()Number.prototype.toLocaleString()Date.prototype.toLocaleString()などのオブジェクト用にこのメソッドをカスタマイズします。
属性 説明 オブジェクト
- JSは「プロパティ記述オブジェクト」と呼ばれる内部データ構造を提供し、オブジェクトのプロパティを記述し、プロパティが書き込み可能かどうか、反復可能かどうかなど、その振る舞いを制御します。
- 各属性には、その属性に関するメタ情報を保持する、対応する属性記述オブジェクトがあります。
- 以下はプロパティ記述オブジェクトの例です:
{
value: 123, // 属性的属性值 默认undefined
writable: false, // 属性值(value)是否可改变(可写) 默认true
enumerable: true, // 属性がトラバース可能かどうか、デフォルトはtrue
configurable: false,// 属性的可配置性,默认true 控制属性描述对象的可写性
get: undefined, // getこの属性の値の関数は、デフォルトでは未定義である。
set: undefined // set属性に格納された値の関数で、デフォルトは未定義である。
}
get関数(またはset関数)を定義する場合、writeプロパティをtrueに設定したり、valueプロパティを同時に定義したりするとエラーになります。
Object.getOwnPropertyDescriptor()プロパティ説明オブジェクトの取得
var obj = { p: 'a' };
Object.getOwnPropertyDescriptor(obj, 'p')
// Object { value: "a",
// writable: true,
// enumerable: true,
// configurable: true
// }
Object.defineProperty()オブジェクトを属性で記述し、属性を定義または変更し、変更後のオブジェクトを返します。
Object.defineProperty(object, propertyName, attributesObject)
パラメーター
- object: プロパティが配置されているオブジェクト
- propertyName: string, プロパティ名
- attributesObject: 属性記述オブジェクト
Object.defineProperties()複数のプロパティを一度に定義可能
- JSON.stringifyメソッドは、enumerableがfalseであるプロパティを除外します。オブジェクトの JSON フォーマット出力で特定のプロパティを除外する場合は、それらのプロパティの enumerable を false に設定します。
- アクセサは属性を定義するもうひとつの方法です。 アクセサが定義されると、対応する関数が実行されます。
defineProperty メソッドでプロパティ記述オブジェクトを通してアクセッサを定義することに加えて、以下の書き込みが可能です。
var obj = {
get p() {
return 'getter';
},
set p(value) {
console.log('setter: ' + value);
}
};
アクセッサは、プロパティの値がオブジェクト内部のデータに依存するような状況でよく使用されます。
var obj ={
$n : 5,
get next() { return this.$n++ },
set next(n) {
if (n >= this.$n) this.$n = n;
else throw new Error('新しい値は、現在の値以上でなければならない。');
}
};
obj.next // 5
obj.next = 10;
obj.next // 10
obj.next = 5;
// Uncaught Error: 新しい値は、現在の値よりも大きくなければならない。
- オブジェクトのコピー:
オブジェクトは参照型なので、データはヒープに格納され、スタック値にはオブジェクトのアドレスが格納されます。デフォルト値型の代入は別の変数にコピーされますが、参照型の代入は参照アドレスを直接別の変数にコピーするため、参照代入はしばしばシャローコピーと呼ばれます。ディープコピーとは、参照型のデータを新しい変数に正確にコピーすることです。
オブジェクトのディープコピーの基本原理は、オブジェクトのプロパティをトラバースし、プロパティを再割り当てし、再帰的に別のオブジェクトにオブジェクトではないプロパティの値に、プロパティの値がオブジェクトである場合は、再帰的に現在の関数を実行します。
- 方法1。 欠点は、関数のディープコピーができないことと、オブジェクトのアクセサ・プロパティが値としてコピーされることです。
var DeepCopy = function dc(obj) {
if (obj===null) {
return obj;
}
else if (typeof obj === 'object') {
if (obj instanceof Array) {
var newArr = [], i, len = obj.length;
for (i = 0; i < len; i++) {
newArr[i] = dc(obj[i]);
}
return newArr;
} else {
var newObj = {};
for (var name in obj) {
newObj[name] = dc(obj[name]);
}
return newObj;
}
}
// 'number' 'string' 'boolean' undefined null
return obj;
}
var objFunction=function(){
//
}
var obj0={
p1:1,
get p2(){
return this.p1;
},
p3:objFunction
}
var obj1=DeepCopy(obj0);
// {p1: 1, p2: 1, p3: }
// p1: 1
// p2: 1
// p3: ƒ ()
obj1.p3===obj0.p3 // true
- 方法2defineProperty を使用してプロパティ記述子を設定し、プロパティのコピーを終了します。これは、オブジェクトのアクセサ・プロパティをコピーすることで実現できます。ただし、コピーされたアクセサ・プロパティ関数は浅いコピーです。
var DeepCopy = function dc(obj) {
if (obj===null) {
return obj;
}
else if(typeof obj === 'object'){
if (obj instanceof Array) {
var newArr = [], i, len = obj.length;
for (i = 0; i < len; i++) {
newArr[i] = dc(obj[i]);
}
return newArr;
} else {
var newObj = {};
for (var name in obj) {
if (obj.hasOwnProperty(name)) {
Object.defineProperty(
newObj,
name,
Object.getOwnPropertyDescriptor(obj, name)
);
}
}
return newObj;
}
}
return obj;
}
- 方法3以下のように、new Functionコンストラクタを使って関数関数のディープコピーを実装します。これがjsのディープコピーを扱う最も完全な方法です。
var DeepCopy = function dc(obj) {
if (obj===null) {
return obj;
}
else if (typeof obj === 'object') {
if (obj instanceof Array) {
var newArr = [], i, len = obj.length;
for (i = 0; i < len; i++) {
newArr[i] = dc(obj[i]);
}
return newArr;
} else {
var newObj = {};
for (var name in obj) {
if (obj.hasOwnProperty(name)) {
//newObj[name] = dc(obj[name]);
if(typeof obj[name] === 'function'){
newObj[name] = dc(obj[name]);
}
else{
Object.defineProperty(
newObj,
name,
Object.getOwnPropertyDescriptor(obj, name)
);
}
}
}
return newObj;
}
}
else if(typeof obj === 'function'){
// var funStr="var f="+obj.toString()+";"
// return new Function(funStr+"return f;");
return new Function("return "+obj+";");
}
return obj;
}
obj1=DeepCopy(obj0);
// {p1: 1, p3: }p1: 1p2: (...)p3: ƒ anonymous( )get p2: ƒ p2()__proto__: Object
obj1.p3===obj0.p3 // false
obj1.p2===obj0.p2 // true
- 方法4
getOwnPropertyDescriptorアクセッサ属性関数のディープコピーでは、取得した属性記述子オブジェクトを使用して、そのget属性とset属性を決定し、その関数のディープコピーを完成させることができます。
- 方法5.JSON.stringfy()またはJSON.parse()を使用して、オブジェクトのディープコピーを達成するために、json文字列にシリアライズし、jsオブジェクトにパースする簡単な方法もあります。しかし、これには致命的な問題があります。つまり、カスタム関数をコピーできないメソッドは、関数の値をjson文字列に変換できないのです。)
var objFunction=function(){
//
}
var obj0={
p1:1,
get p2(){
return this.p1;
},
p3:objFunction,
p4:{
p5:5
}
}
var newObj = JSON.parse(JSON.stringify(obj0));
newObj
// {p1: 1, p2: 1, p4: { }}
// p1: 1
// p2: 1
// p4:
// p5: 5
ES6でオブジェクトのコピーを実装する方法:Object.assign、expand演算子など。
また、Array の slice メソッドと concat メソッドは元の配列を変更せず、新しい配列の浅いコピーを返します。 また、$.extend メソッドの最初の引数は、深いコピーかどうかを示す bool 値です:jQuery.extend( [deep ], target, object1 [, objectN ] )
- 制御オブジェクトの状態
Object.preventExtensionsメソッド:オブジェクトに新しい属性を追加できなくなります。Object.preventExtensionsObject.isExtensible メソッドは、オブジェクトがメソッドを使用するかどうかをチェックします。オブジェクトにプロパティを追加できるかどうかをチェックします。- Object.sealメソッドは、オブジェクトが新しい属性を追加したり古い属性を削除したりできないようにします。
- Object.freeze メソッドはオブジェクトを一定にします。新しいプロパティを追加したり、古いプロパティを削除したり、プロパティの値を変更したりすることはできません。 object.isFrozen()
オブジェクトの書き込み可能性をロックする上記3つの方法には抜け穴があります。プロトタイプ・オブジェクトを変更することで、オブジェクトにプロパティを追加することが可能です。解決策は、プロトタイプも凍結することです。もう1つの制限は、プロパティの値がオブジェクトである場合、これらのメソッドがフリーズできるのはプロパティが指すオブジェクトだけであり、オブジェクト自体の中身をフリーズできるわけではないということです。
配列オブジェクト
- Array は JavaScript ネイティブオブジェクトで、新しい配列を生成するコンストラクタです。
var arr = new Array(2); // 等同于 var arr = Array(2);
arr.length // 2
arr // [ empty x 2 ]
- Array()コンストラクタには、引数が異なると結果が異なるという大きな欠点があります。したがって、配列リテラル
// 推奨されないメソッド
var arr = new Array(1, 2);
//
var arr = [1, 2];
- 配列かどうかを判定する Array.isArray() 静的メソッド
var arr = [1, 2, 3];
typeof arr // "object"
Array.isArray(arr) // true
- 配列オブジェクトのインスタンスメソッド:
- valueOf() は配列そのものを返します。
- toString() は、配列の文字列形式を返します。
- push() は、配列の末尾に 1 つ以上の要素を追加し、追加後の配列の長さを返します。このメソッドは、元の配列を変更します。
- pop() は、配列の最後の要素を削除し、その要素を返します。このメソッドは元の配列を変更します。
プッシュとポップを組み合わせて使うことで、「最後に入って最初に出てくる」スタック構造を形成することができます。
var arr = [];
arr.push(1, 2);
arr.push(3);
arr.pop();
arr // [1, 2]
- shift() は、配列の最初の要素を削除してその要素を返します。このメソッドは、元の配列を変更します。
shift() メソッドは、配列を走査して空にします。
var list = [1, 2, 3, 4];
while (list.length) {
console.log(list.shift());
}
list // []
push()とshift()の組み合わせは、「先入れ先出し」のキュー構造を作ります。
- unshift() は、配列の最初の位置に要素を追加し、追加後の配列の長さを返します。このメソッドは、元の配列をシフトします。
var arr = [ 'c', 'd' ];
arr.unshift('a', 'b') // 4
arr // [ 'a', 'b', 'c', 'd' ]
- join() は、指定した引数を区切り文字として、すべての配列メンバを連結した単一の文字列を返します。デフォルトはカンマ区切りです。
var a = [1, 2, 3, 4,undefined, null];
a.join(' ') // '1 2 3 4 '
a.join(' | ') // "1 | 2 | 3 | 4 | | "
a.join() // "1,2,3,4,,"
- concat() は、複数の配列を結合する際に使用します。新しい配列のメンバを、後者の元の配列のメンバに追加して新しい配列を返します。
['hello'].concat(['world'])
// ["hello", "world"]
['hello'].concat(['world'], ['!'])
// ["hello", "world", "!"]
[].concat({a: 1}, {b: 2})
// [{ a: 1 }, { b: 2 }]
- reverse() は配列を反転させます。配列の要素を逆さまに並べ、変更後の配列を返します。このメソッドは、元の配列を変更します。
- slice() は、配列の一部を取り出して新しい配列を返すために使用します。元の配列は変更されません。
Left-closed-right-open、return resultに末尾の要素が含まれていません。
arr.slice(start, end);
2番目のパラメータを省略すると、常に配列の最後のメンバが返されます。すべてのパラメータを省略すると、要素のグループが返されます。1番目のパラメータが配列の長さ以上、または2番目のパラメータが1番目のパラメータより小さい場合は、空の配列が返されます。
Array.prototype.slice.call(likeArrayObj)slice() の重要な用途は、配列のようなオブジェクトを実際の配列に変換することです。
- splice() は、元の配列メンバの一部を削除し、削除した位置に新しい配列メンバを追加します。このメソッドは、元の配列を変更します。
パラメータは、開始位置、削除する要素の数、削除位置に追加する新しい要素です。
arr.splice(start, count, addElement1, addElement2, ...);
2番目のパラメータに0を指定すると、要素が挿入されます。
var a = [1, 1, 1];
a.splice(1, 0, 2) // []
a // [1, 2, 1, 1]
最初のパラメータだけを指定すると、配列の最後までを「カット」します。
- sort() は、配列のメンバをデフォルトでは辞書順にソートします。元の配列は変更されます。
['d', 'c', 'b', 'a'].sort()
// ['a', 'b', 'c', 'd']
[4, 3, 2, 1].sort()
// [1, 2, 3, 4]
[11, 101].sort()
// [101, 11]
[10111, 1101, 111].sort()
// [10111, 1101, 111]
ソートメソッドは、関数
[10111, 1101, 111].sort(function (a, b) {
return a - b;
})
// [111, 1101, 10111]
[
{ name: " ", age: 30 },
{ name: " ", age: 24 },
{ name: " ", age: 28 }
].sort(function (o1, o2) {
return o1.age - o2.age;
})
// [
// { name: " ", age: 24 },
// { name: " ", age: 28 },
// { name: " ", age: 30 }
// ]
sort パラメータ関数は、比較する 2 つの配列メンバを表す 2 つの引数を取ります。この関数の戻り値が 0 より大きい場合は、最初の要素が 2 番目の要素の後に配置され、0 以下の場合は、最初の要素が 2 番目の要素の前に配置されます。
- map() は、配列のすべてのメンバを引数関数に順番に渡し、その結果を新しい配列として返します。要素の配列は変更されません。
var numbers = [1, 2, 3];
numbers.map(function (n) {
return n + 1;
});
// [2, 3, 4]
numbers // [1, 2, 3]
mapパラメータ関数は3つの引数を取ります。現在のメンバ、現在の位置、そして配列そのものです。
[1, 2, 3].map(function(elem, index, arr) {
return elem * index;
});
// [0, 2, 6]
mapの2番目のパラメータは、コールバック関数内でthis変数をバインドするために使用されます。
- forEachは、配列の全メンバーに対して順番に引数関数を実行するという点ではmapに似ていますが、値を返しません。
forEachメソッドは中断できません。割り込みたい場合は、forループを使うか、someメソッドやeveryメソッドを使います。
- some()、every()メソッドは "assert "に似ており、配列メンバが特定の条件を満たすかどうかを示すブール値を返します。
someメソッドは、1つのメンバの返り値が真である限り、someメソッド全体に対して真を返し、そうでない場合は偽を返します。
everyメソッドは、すべてのメンバがtrueを返せばtrueを返し、そうでなければfalseを返します。
someメソッドの引数関数は条件を判定してtrueを返し、everyメソッドの引数関数は条件を判定してfalseを返すという、forループのbreak割り込みのようなループができます;
var arr = [1, 2, 3, 4, 5];
arr.some(function (elem, index, arr) {
console.log(elem); //操作の実行
return elem >= 3;
});
// 1
// 2
// 3
// true
arr.every(function (elem, index, arr) {
if(elem<=3){
console.log(elem);
return true;
}
else{
return false;
}
});
// 1
// 2
// 3
// false
- filter () 配列のメンバをフィルタリングして、新しい配列のメンバの条件を満たすものを返します - つまり、filter パラメータ関数は、新しい配列の真のメンバを返します。元の配列を変更することはありません。
パラメータ関数は、現在のメンバー、現在の位置、配列全体の3つの引数を取ります。
[1, 2, 3, 4, 5].filter(function (elem) {
return (elem > 3);
})
[1, 2, 3, 4, 5].filter(function (elem, index, arr) {
return index % 2 === 0;
});
- reduce(), reduceRight() は、配列の各メンバを順番に処理し、最終的に値を累積します。処理されるのは、最後に累積された値の累積値と、現在の要素の実行結果の累積値です。reduce は左から右へ処理し、reduceRight は右から左へ処理するという違いがあります。
[1, 2, 3, 4, 5].reduce(function (a, b) {
console.log("最後の:"+a, " :"+b);
return a + b;
})
// 最後の:1 :2
// 最後の:3 :3
// 最後の:6 :4
// 最後の:10 :5
// 15
最初に実行されると、累積値aが配列の最初の要素となり、その後に累積値と要素値
アキュムレーション変数(デフォルトは配列の1番目のメンバ)、カレント変数(デフォルトは配列の2番目のメンバ)、カレントポジション、そして元の配列です。最初の2つは
reduceとreduceRightの第2パラメータには、実行時の初期値を指定することができます。
[1, 2, 3, 4, 5].reduce(function (a, b) {
console.log("最後の:"+a, " :"+b);
return a + b;
},10)
// 最後の:10 :1
// 最後の:11 :2
// 最後の:13 :3
// 最後の:16 :4
// 最後の:20 :5
// 25
reduce (あるいは reduceRight) を使用すると、 最大の文字長を持つ配列要素を見つけるなどのトラバーサル操作を実装できます。
function findLongest(entries) {
return entries.reduce(function (longest, entry) {
return entry.length > longest.length ? entry : longest;
}, '');
}
findLongest(['aaa', 'bb', 'c']) // "aaa"
- indexOf() は、配列内で指定した要素が最初に現れる位置を返します。
- lastIndexOf() は、配列内で指定した要素が最後に出現する位置を返します。
- arrayメソッドが配列を返す場合、arrayメソッドを連鎖的に呼び出すことができます。
var users = [
{name: 'tom', email: 'tom@example.com'},
{name: 'peter', email: 'peter@example.com'}
];
users.map(function (user) {
return user.email;
})
.filter(function (email) {
return /^t/.test(email);
})
.forEach(function (email) {
console.log(email);
});
// "tom@example.com"
梱包対象物
- jsの3つのプリミティブ型(数値、文字列、ブーリアン)は、特定の条件下で自動的にオブジェクトに変換され、プリミティブ型の「ラップオブジェクト」となります。
- ラッパー・オブジェクト」とは、3つのネイティブ・オブジェクト Number、String、Booleanのことで、それぞれ数値、文字列、ブーリアン値に対応します。これら3つのネイティブ・オブジェクトは、元の型の値をオブジェクトに変換することができます。
var v1 = new Number(123);
var v2 = new String('abc');
var v3 = new Boolean(true);
typeof v1 // "object"
typeof v2 // "object"
typeof v3 // "object"
v1 === 123 // false
v2 === 'abc' // false
v3 === true // false
- ラップされたオブジェクトは、まず第一に、JavaScriptのすべての値を "オブジェクト "という型がカバーできるようにすることで、言語全体に共通のデータモデルが存在するように設計されています。第二に、プリミティブ型の値に独自のメソッドを呼び出す方法を与えることです。
- Number、String、Booleanは、通常の関数として呼び出されたときに、任意の型の値をNumeric、String、Booleanなどのプリミティブ型の値に変換したり、プリミティブ型の値をオブジェクトに変換するコンストラクタとして呼び出されたときに、型変換に使用されます。
- プリミティブ型からインスタンス・オブジェクトへの自動変換: プリミティブ型の値が自動的にラッパー・オブジェクトとして呼び出されることがあります。
例えば、文字列はlengthプロパティを呼び出します:
'abc'.length // 3
abcは文字列であり、それ自体がオブジェクトではないため、length属性を呼び出すことはできません。JavaScriptエンジンは、自動的にlength属性が呼び出されるラップされたオブジェクトに変換します。呼び出しが終わると、一時オブジェクトは破棄されます。これは、元の型からインスタンスオブジェクトへの自動変換と呼ばれます。
自動変換によって生成されたラッパー・オブジェクトは読み取り専用で、変更することはできません。そのため、文字列は新しいプロパティを追加することができません。また、ラッパーのインスタンスは呼び出しが終了すると自動的に破棄されるので、呼び出しのたびに、実際には新しいラッパー・オブジェクトが生成されます。
var s = 'Hello World';
s.x = 123;
s.x // undefined
- カスタム・メソッドやカスタム・プロパティは、 ラッパー・オブジェクトのプロトタイプに追加することができます。
ブール値オブジェクト
- ラップされたオブジェクトに対応する元の型の値を valueOf() で取得します。
new Boolean(false).valueOf()
番号オブジェクト
- Numberオブジェクトの静的プロパティ:
Number.POSITIVE_INFINITY無限大を指し示す正の無限大。Number.NEGATIVE_INFINITY負の無限大、-無限大を指します。- Number.NaN:数値でないことを示し、NaNを指します。
- Number.MIN_VALUE:最小の正の数を示し、0に最も近い負の数は-Number.MIN_VALUEとなります。
- Number.MAX_VALUE:正の数の最大値を示します。
Number.MAX_SAFE_INTEGERは正確に表現できる最大の整数を表します。Number.MIN_SAFE_INTEGER: は正確に表現できる最小の整数、すなわち -0097199254740991 を表します。
- インスタンスメソッド
Number.prototype.toString()このメソッドは、数値を文字列形式に変換するために使用されます。このメソッドは、出力の10進法を示すパラメータを取ることができます。
(10).toString() // "10"
(10).toString(2) // "1010"
(10).toString(8) // "12"
(10).toString(16) // "a"
そうしないと、jsエンジンは.を小数点として解釈してしまい、混乱する可能性があります。誤解されないように書く方法は何でも構いません。
10.toString(2)
// SyntaxError: Unexpected token ILLEGAL
10.5.toString() // ".5.toString(2) // ".5.toString(8) // ".5.toString(16) // "a.8"
角括弧を使用して呼び出すことができます。
10['toString'](2) // "1010"
他の2進数から10進数に変換したい場合は、parseIntを使用します。
Number.prototype.toFixed()C関数は、数値を指定した桁数の10進数に変換し、その10進数に対応する文字列を返します。
(10).toFixed(2) // ".005.toFixed(2) // "10.01"
浮動小数点数のため、jsの小数5の丸めは不確実であり、注意して使用する必要があります。
Number.prototype.toExponential()数値を科学表記法に変換Number.prototype.toLocaleString()市外局番を引数として指定し、その市外局番の現地語表記を返します。
(123).toLocaleString('ja-JP-u-nu-hanidec')
// " "
toLocaleString() の 2 番目のパラメータは、返される文字列をカスタマイズするための設定オブジェクトです。たとえば、style 属性で出力の形式を指定します。デフォルトは decimal で、 percent や currency も指定できます。
(123).toLocaleString('ja-JP', { style: 'percent' })
// "%"
(123).toLocaleString('ja-JP', { style: 'currency', currency: Y' })
// "¥123.00"
(123).toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })
// "123,00 "
(123).toLocaleString('en-US', { style: 'currency', currency: 'USD' })
// "$123.00"
- カスタムメソッドは、Number.prototype オブジェクトで使用できます。
Number.prototype.add = function (x) {
return this + x;
};
Number.prototype.subtract = function (x) {
return this - x;
};
(8).add(2).subtract(4) // 6
文字列オブジェクト
String.fromCharCode()この静的メソッドは、Unicode コードポイントの文字列を返します。
Unicodeのコードポイントは0xFFFFより大きくできず、0xFFFFより大きいコードポイントを持つ文字は4バイトを占めますが、JavaScriptはデフォルトで2バイト文字をサポートしています。例えば、0x20BB7は次のように書くために2つの文字に分割する必要があります。
String.fromCharCode(0xD842, 0xDFB7) // " "
String.prototype.lengthインスタンス属性は文字列の長さを返します。- インスタンスメソッド
String.prototype.charAt()指定された位置の文字を返します。文字列の配列添え字に相当します。String.prototype.concat()2つの弦の結合- slice()は、もとの文字列を変更せずに、もとの文字列から部分文字列を取り出して返すために使用します。slice(start,end)は左閉じ、右開きです。2番目のパラメータを省略すると、文字列の最後まで取り出します。
- substring() は元の文字列から部分文字列を取り出し、slice のように元の文字列を変更せずにそれを返します。しかし、substring() の第一引数が第二引数より大きい場合、結果は二つの位置を入れ替えた結果となり、負の数は 0 に変換されます。 このような直感に反する動作があるため、slice を使用することをお勧めします。
- substr() は、元の文字列から部分文字列を取り出し、元の文字列を変更せずにそれを返します。最初の引数は文字列の開始位置で、2 番目の引数は長さです。第2引数を省略すると、文字列を最後まで取得します。第2引数に負の値を指定すると、0に変換されます。
'JavaScript'.substr(4, 6) // "Script"
'JavaScript'.substr(4) // "Script"
'JavaScript'.substr(-6) // "Script"
'JavaScript'.substr(4, -1) // ""
- trim() は、文字列の両端の空白を削除して新しい文字列を返します。元の文字列を変更することはありません。
- indexOf() は、ある文字列が別の文字列の中で最初に出現する位置を返します。lastIndexOf() は最後からマッチします。
- toLowerCase() は文字列のすべてを小文字に変換し、 toUpperCase() はすべてを大文字に変換します。どちらも、元の文字列
- match() は、元の文字列が部分文字列にマッチするかどうかを調べ、最初にマッチした文字列の配列を返します。マッチしない場合は null を返します。返される配列には index 属性と input 属性が含まれます。
var matches = 'cat, bat, sat, fat'.match('at');
matches.index // 1
matches.input // "cat, bat, sat, fat"
match()引数には正規表現を指定します。
- search() は、マッチした文字列の最初の位置を返します。マッチしない場合は -1 を返します。引数には正規表現を指定できます。
- replace() はマッチした部分文字列を置き換えますが、通常は最初にマッチした部分文字列のみが置き換えられます。
'aaa'.replace('a', 'b') // "baa"
- split() は、パラメータに従って文字列を分割し、分割後の部分文字列の配列を返します。split パラメータが空文字列の場合は各文字を分割し、省略した場合は元の文字列の配列を返します。
'a|b|c'.split('|') // ["a", "b", "c"]
'a|b|c'.split('') // ["a", "|", "b", "|", "c"]
'a|b|c'.split() // ["a|b|c"]
'a||c'.split('|') // ['a', '', 'c']
'|b|c'.split('|') // ["", "b", "c"]
'a|b|'.split('|') // ["a", "b", ""]
split 第2引数は、返される配列の長さを表します。
- 二つの文字列を比較します。
数学オブジェクト
- Math は様々な数学関数を提供します。このオブジェクトはコンストラクタではなく、インスタンスを生成することはできません。
- 数学定数を提供する静的プロパティで、読み取り専用です。
- Math.E: 定数e.
- Math.LN2JSON.parse():2の自然対数。
- Math.LN10JSON.parse():10の自然対数。
- Math.LOG2E:底 2 の e の対数。
- Math.LOG10E:底が 10 の e の対数。
- Math.PI: 定数 π.
- Math.SQRT1_2:0.5の平方根。
- Math.SQRT2:2の平方根。
- 静的メソッド:
- Math.abs()絶対値
- Math.ceil()例: 切り上げ
- Math.floor()切り捨て
- Math.max()最大値
- Math.min()最小
- Math.pow()べき乗算
- Math.sqrt()平方根
- Math.log()自然対数
- Math.exp()eのインデックス
- Math.round()丸め
- Math.random(): 乱数
Math.ceilメソッドとMath.floorメソッドを組み合わせて、値の整数部分を返します。
function ToInteger(x) {
x = Number(x);
return x < 0 ? Math.ceil(x) : Math.floor(x);
}
ToInteger(3.2) // 3
ToInteger(-3.2) // -3
Math.round は負の数を異なる方法で丸めます。
Math.round(1.5) //2
Math.round(1.6) //2
Math.round(-1.5) //-1
Math.round(-1.6) //-2
円の面積を求めなさい
var radius = 20;
var area = Math.PI * Math.pow(radius, 2);
Math.sqrtは、負にできないパラメータの値の平方根を求めます。
Math.random()は、Math.random() >= 0かつMath.random() < 1で、0から1の間の擬似乱数を返します。
任意範囲の乱数生成関数
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
任意範囲のランダム整数ジェネレータ関数
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
ランダム文字の生成例
function random_str(length) {
var ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
ALPHABET += 'abcdefghijklmnopqrstuvwxyz';
ALPHABET += '-_';
var str = '';
for (var i = 0; i < length; ++i) {
var rand = Math.floor(Math.random() * ALPHABET.length);
str += ALPHABET.substr(rand, 1);
}
return str;
}
random_str(6) // "NdQKOr"
- 三角関数
- Math.sin():引数の正弦を返します。
- Math.cos():パラメータの余弦を返します。
- 引数の正接を返します。
- Math.asin():引数のアークサインを返します。
- Math.acos():パラメータの逆コサインを返します。
- Math.atan():パラメータのアークタンジェントを返します。
日付オブジェクト
- Dateオブジェクトはjsネイティブの時間ライブラリです。1970年1月1日00:00:00国際標準時をゼロ時点とし、前後1億日の時間範囲を表すことができます。
- 文字列の現在時刻を返すために通常の関数Date()として使用され、パラメータを渡すために、この時間は無効です。
- Dateはコンストラクタとして働き、newを使ってDateオブジェクトのインスタンスを返します。
var today = new Date();
コンストラクタが使用する Date は、さまざまな引数を取ることができます。
// 引数は、時間ゼロから数えたミリ秒数である。
new Date(000)
// Sun Jan 05 2020 GMT+0800 (日本標準時)
// 引数は日付文字列である。
new Date('January 30, 2020');
// Thu Jan 30 2020 GMT+0800 (日本標準時)
// 引数は複数の整数で
// 年、月、日、時、分、秒、ミリ秒を表す。
new Date(2020, 6, 1, 0, 0, 0, 0)
// Wed Jul 01 2020 GMT+0800 (日本標準時)
Dateコンストラクタの引数
- パラメータは1970年元旦の時刻を示す負の整数。
- Date.parse() メソッドでパースできる文字列であれば、何でもパラメータとして使用できます。
- 引数が年、月、日などの複数の整数の場合、年と月を省略することはできません。引数の Date だけがミリ秒数として解釈されます。
- 各パラメータの値の範囲:
年:4桁の年号を使用(例:2000)。 2桁または1桁の数字で表記する場合は、1900を足す(例:10で1910)。マイナスの場合は紀元前を意味します。月:1月以降は0、12月は11。日:1から31まで。時:0から23まで。分:0から59まで。秒:0から59まで。ミリ秒:0から999まで。
このパラメータは、保留時間を示す負の数を使用します。
Date インスタンスの値を取得すると、文字列が返されます。つまり、Date オブジェクトは toString() メソッドをコールして値を取得し、 他のオブジェクトは valueOf() メソッドをコールして値を取得します。
var today = new Date(); today // Sun Aug 02 2020 GMT+0800 (日本標準時) // today.toString() // "Sun Aug 02 2020 GMT+0800 (日本標準時)"
- 日付操作: 型が自動的に変換される場合、Date インスタンスは、数値に変換された場合は対応するミリ秒と等しくなり、文字列に変換された場合は対応する日付文字列と等しくなります。したがって、2 つの Date インスタンスを減算すると、その間のミリ秒数が返され、それらを加算すると、2 つの文字列を連結した新しい文字列が返されます。
- StaticMessage:
- Date.now()は、ミリ秒単位でゼロ時刻から現在時刻に戻ります。
- Date.parse() は、日付文字列を解析し、ゼロ時刻からのミリ秒数を返します。パースに失敗した場合はNaNを返します。
- Date.UTC() は、年、月、日の引数を受け取り、ゼロ時刻までのミリ秒数を返します。は UTC 時間として扱われ、new Date() はローカル時間となります。
//
Date.UTC(year, month[, date[, hrs[, min[, sec[, ms]]]]])
//
Date.UTC(2011, 0, 1, 2, 3, 4, 567) // 567
- インスタンスメソッド
valueOf() はミリ秒数を返します。
toString() は、完全な日付文字列を返します。
toUTCString() は UTC 時間を返します。
toISOString() は ISO8601 構文を返します。
toJSON() は toISOString() と同じ結果になります。
toDateString() return 日付文字列
toTimeString() は、時刻文字列を返します。
toLocaleString() 現地の日付と時刻
toLocaleDateString()現地日付toLocaleTimeString()現地時間getTime():1970年1月1日00:00:00からのミリ秒数で、valueOfメソッドと同等。
インスタンス・オブジェクトの月番号を返します。
getDay():曜日を返します。日曜日は 0、月曜日は 1、といった具合です。
4桁の西暦を返します。
getMonth(): return month.
getHours(): 時間を返します。
getMilliseconds():ミリ秒を返します。
getMinutes(): return minutes.
getSeconds(): 秒を返します。
getTimezoneOffset(): 現在時刻と UTC との時差を分単位で返します。
setDate(date):インスタンスオブジェクトに対応する各月の日付を設定し、変更後のミリ秒のタイムスタンプを返します。
setFullYear(year [, month, date])4桁の西暦を設定します。setHours(hour [, min, sec, ms])時間を設定します。setMilliseconds():ミリ秒を設定します。
setMinutes(min [, sec, ms])分を設定します。setMonth(month [, date])月を設定します。setSeconds(sec [, ms])設定秒数setTime(milliseconds)ミリ秒単位のタイムスタンプを設定します。
RegExp
- 正規表現はテキスト・パターンを表現する方法で、「与えられたパターン」に従ってテキストをマッチさせるために使われます。
- リテラルを使った新しい正規表現。スラッシュは終わりの始まりを示します。新しい正規表現を使ったコードのコンパイル
var regex = /xyz/;
RegExp コンストラクタを使用した新しい正規表現。実行時の新しい正規表現
var regex = new RegExp('xyz');
モディファイア
var regex = new RegExp('xyz', 'i');
//
var regex = /xyz/i;
- インスタンスのプロパティ
修飾子関連プロパティ
RegExp.prototype.ignoreCasei修飾子がセットされているかどうか。RegExp.prototype.globalg修飾子が設定されているかどうかを表します。RegExp.prototype.multilinem修飾子がセットされているかどうか。RegExp.prototype.flags: 設定されているすべての修飾子をアルファベット順に並べた文字列。
var r = /abc/igm;
r.ignoreCase // true
r.global // true
r.multiline // true
r.flags // 'gim'
その他の物件
RegExp.prototype.lastIndex次に検索を開始する場所。属性は読み書き可能RegExp.prototype.source読み取り専用属性を持つ正規表現の文字列形式。
- インスタンスメソッド
- test() は、現在のパターンが引数の文字列にマッチするかどうかを示すブール値を返します。
g 修飾子を指定すると、異なる文字列のマッチに対してテストメソッドを複数回コールする必要がなくなります。
- exec() は、正規表現をマッチさせて返します。マッチに成功した場合は、マッチした文字列の配列を返します。
var s = '_x_x';
var r1 = /x/;
r1.exec(s)
// ["x", index: 1, input: "_x_x", groups: undefined]
// 0: "x"
// groups: undefined
// index: 1
// input: "_x_x"
// length: 1
// __proto__: Array(0)
正規表現に括弧が含まれている場合、返される配列の最初のメンバはマッチに成功した結果全体となり、 それ以降のメンバは括弧に対応するマッチに成功したグループとなります。つまり、2 番目のメンバは最初の括弧に対応し、3 番目のメンバは 2 番目の括弧に対応します。配列全体の length 属性は、マッチの数に 1 を足した値になります。
これは、文字列のマッチ・メソッドでマッチを得るのに便利です。
- g 修飾子は、ルールのインスタンスメソッドを複数回マッチさせることが できます。つまり、test や exec のようなメソッドを同じ規則に対して複数回実行すると、 そのたびにマッチした場所を覚えていて、次回もマッチし続けるということです。
- 文字列の match()、search()、replace()、split() およびその他のメソッドでは、正規表現をパラメータとして使用できます。
- g を match() で使用すると、マッチに成功した場合はすべて返されます。
var s = 'abba';
var r = /a/g;
s.match(r) // ["a", "a"]
search() は、最初にマッチした位置を返します。
str.replace(search, replacement).正常にマッチしたすべての値を g 修飾子で置き換えます。
文字列の先頭と末尾のスペースを除去します。
str.replace(/^\s+|\s+$/g, '')
replaceの2番目の引数には、ドル記号$を使用して、置換される内容を参照することができます。
- 一致した部分文字列。
- は結果の前のテキストにマッチします。
- $': 結果の後のテキストにマッチします。
- n:成功したマッチのn番目のセット。nは1から始まる自然数。
- ドル記号$を指します。
'输出hello world是编程的第一步'.replace(/(\w+)\s(\w+)( /, " ($'$3$2 $1$` $$-- マッチするのは:$&) ")
// "输出 (编程的第一步是world hello输出——$-- マッチするのは:hello world是) 编程的第一步"
replaceの第2引数には、各マッチを関数の戻り値に置き換える関数を指定することもできます。
'3 and 5'.replace(/[0-9]+/g, function (match) {
return 2 * match;
})
// "6 and 10"
var a = 'The quick brown fox jumped over the lazy dog.';
var pattern = /quick|brown|lazy/ig;
a.replace(pattern, function replacer(match) {
return match.toUpperCase();
});
// The QUICK BROWN fox jumped over the LAZY dog.
replace第2引数関数は複数の引数を取ることもでき、第2引数は最初のグループマッチを示します。
- 正規表現のマッチングルール
- 正規表現中の文字がリテラル的な意味のみを表す場合、それは「リテラル文字」と呼ばれます。
- リテラル文字のほかに、特別な意味を持ち、リテラル文字の意味を表さない文字もあります。これらは「メタ文字」と呼ばれます。
点線文字:復帰文字、改行文字、行区切り文字、段落区切り文字を除くすべての文字にマッチします。
位置文字:プロンプト文字がある位置。は開始位置、$は終了位置を示します。
// test先頭になければならない
/^test/.test('test123') // true
// test末尾の位置になければならない
/test$/.test('new test') // true
// 開始位置から終了位置まで、テストされるのは
/^test$/.test('test') // true
/^test$/.test('testtest') // false
/^test$/.test('test test') // false
セレクタ():縦線の記号は「または関係」を表し、cat|dogはcatまたはdogにマッチすることを意味します。
例えば/ab|cd/は、bやcではなく、abやcdにマッチすることを意味します。括弧を使ってマッチする範囲を変更することができます。
/a( |\t)b/.test('a\tb') // true
- 特別な意味を持つ「メタ文字」にマッチさせたい場合は、エスケープ文字の使い方を知っておく必要があります。
/1+1/.test('1+1') // false
/1\+1/.test('1+1') // true
エスケープが必要な文字は ^, ., [, $, , , *, +, ?および
RegExpを使用して正規オブジェクトを生成する場合、文字列は最初に内部的に一度エスケープされるため、エスケープには2つのスラッシュを使用する必要があります。
- 印刷できない特殊文字を含む正規表現は次のように表されます:
\cXはCtrl-[X]を意味し、XはA~Zのいずれかの文字で、制御文字にマッチするのに使われます。[b]はバックスペースにマッチします。 ]は改行キーにマッチします。 ]キャリッジリターンキーにマッチします。\tはタブにマッチします。\ページ区切りにマッチします。\ヌル文字にマッチします。\16 進 2 桁の文字にマッチします。\16 進 4 桁の Unicode 文字にマッチします。
- 文字クラスは、[]内のどの文字にもマッチする、選択可能な文字の範囲を表します。
abcのどれかが真。
/[abc]/.test('hello world') // false
/[abc]/.test('apple') // true
文字クラス内の特殊文字 - 区切り記号 ^: 角括弧内の最初の文字が[^] の場合、否定を意味し、文字クラス内の文字以外を指します。
例えば、[^xyz]は、x、y、z以外がマッチすることを意味します。
角括弧の中に他の文字がない場合、つまり[^]しかない場合は、改行を含むすべての文字にマッチすることを意味します。一方、ドットのメタキャラクタは改行を含みません。
var s = 'Please yes
make my day!';
s.match(/yes.*day/) // null
s.match(/yes[^]*day/) // [ 'yes
make my day']
文字クラス内の特殊文字であるハイフン([]ハイフン)は、連続した複数の文字の省略記法を提供し、連続した文字の範囲を示します。例えば、[abc]は[a-c]、[0123456789]は[0-9]と書くことができます。ハイフネーションは、[]内の連続する範囲の省略記法を示すだけです。
/[a-b-]/.test('-') // true
/[a-b]/.test('-') // false
*A-z]*はA-z間の52文字を表しません。ASCIIでは大文字と小文字の間に他の文字があるからです。
/[A-z]/.test('\\') // true
- 定義済みパターンとは、特定の一般的なパターンを記述する省略記法です。
\Dは[0-9]と同じ0-9の間の数字にマッチします。\Dは0-9以外のすべての文字にマッチします。\A-Za-z0-9_] と同じです。\A-Za-z0-9_] と同じです。\空文字にマッチします。\空でない文字にマッチします。\単語境界にマッチします。\非単語境界、すなわち単語内にマッチします。
全ての文字にマッチさせる場合は、[ \S] を使用します。
var html = "<b>Hello</b>
<i>world!</i>";
// .改行にはマッチしない
/.*/.exec(html)[0] // "<b>Hello</b>"
// すべての文字にマッチする
/[\S\s]*/.exec(html)[0] // "<b>Hello</b>
<i>world!</i>"
- 重複クラス
中括弧 {} はパターンにマッチする回数を表し、{n} はちょうど n 回の繰り返し、{n,} は少なくとも n 回の繰り返し、{n,m} は n 回以上 m 回以下の繰り返しを意味します。
/lo{2}k/.test('look') // true
/lo{2,5}k/.test('looook') // true
- 量化子は、パターンが発生する回数を設定するために使用されます。
? クエスチョンマークは、パターンが 0 回または 1 回発生することを示します。* アスタリスクは、パターンが 0 回以上発生することを示します。+ プラス記号は、パターンが 1 回以上発生することを示します。
// t 0回または1回発生する
/t?est/.test('test') // true
/t?est/.test('est') // true
// t 1回以上発生する
/t+est/.test('test') // true
/t+est/.test('ttest') // true
/t+est/.test('est') // false
// t 0回以上発生する
/t*est/.test('test') // true
/t*est/.test('ttest') // true
/t*est/.test('tttest') // true
/t*est/.test('est') // true
- 貪欲モード:上記のような量化子は、デフォルトでは最大可能マッチ、つまり、次の文字がマッチングルールを満たさないまでマッチします。これは貪欲モードとして知られています。
以下のように、/a+/は1つ以上のaにマッチし、貪欲モードではこのルールに マッチしなくなるまでマッチします。/a+/は、?の /a+? / は非貪欲モードに変更され、初めて条件を満たしたときにはマッチを継続しません。
var s = 'aaa';
s.match(/a+/) // ["aaa"]
s.match(/a+?/) // ["a"]
非貪欲モード記号 +?, *?と?
- 修飾語はパターンの追加規則を示し、通常のパターンの一番最後に置かれます。
g 修飾子はグローバルマッチを示します。i修飾子は大文字小文字を無視することを示します。 m修飾子は複数行モードを示します。デフォルトでは、^と$は文字列の先頭と末尾にマッチします。 m修飾子をつけると、^と$は行頭と行末にもマッチします。
mを追加した後、$は行末に一致させることができます。これは、˶nを別の行、前の行を前の行として扱うのと同じです。
/world$/.test('hello world
') // false
/world$/m.test('hello world
') // true
mが追加されたことにより、改行文字˶nは行の開始とみなされ、それに続く文字は別の行の開始を示します。
/^b/m.test('a
b') // true
- グループ・マッチング:括弧はグループ・マッチングを表し、括弧内のパターンを使ってグループの内容にマッチさせることができます。
() はグループマッチ
/fred+/.test('fredd') // true
/(fred)+/.test('fredfred') // true
グループ・マッチングを使用する場合、g修飾子を同時に使用することはお勧めしません。
var m = 'abcabc'.match(/(.)b(.)/g); m // ['abc', 'abc']上記と同様、gの場合、matchメソッドは式全体にマッチする部分のみを取り込みます。
正規表現のexecメソッドとループを使って、マッチのラウンドごとにグループ・キャプチャを読み込みます。
var str = 'abcabc'; var reg = /(.)b(.)/g; while (true) { var result = reg.exec(str); if (!result) break; console.log(result); } // ["abc", "a", "c"] // ["abc", "a", "c"]
正規表現の内部では、括弧のマッチ内容を参照するために˶nを使うことができます。
/(.)b(.)\1b\2/.test("abcabc") // true
括弧は以下のように入れ子にすることができます。
/y((..)\2)\1/.test('yabababab') // true
タグを以下のようにマッチさせます。
var tagName = /<(([^>]+))>[^<]*<\/\1>/;
tagName.exec("<b>bold</b>")[1] // 'b'
タグと属性のマッチングの実装
var html = '<h1 class="hello">Hello<i>world</i></h1>';
var tag = /<(\w+)([^>]*)>(.*?)<\/\1>/g;
var match = tag.exec(html);
match
// (4) ["<b class="hello">Hello</b>", "b", " class="hello"", "Hello", index: 0, input: "<b class="hello">Hello</b><i>world</i>", groups: undefined]
// 0: "<b class="hello">Hello</b>"
// 1: "b"
// 2: " class="hello""
// 3: "Hello"
// groups: undefined
// index: 0
// input: "<b class="hello">Hello</b><i>world</i>"
// length: 4
// match[0]parse()の第2引数には、JSON.stringifyメソッドと同様の関数を指定できる。
match = tag.exec(html);
> (4) ["<i>world</i>", "i", "", "world", index: 26, input: "<》b class="hello">Hello</b><i>world</i>", groups: undefined]
> 0: "<i>world</i>"
> 1: "i"
> 2: ""
> 3: "world"
> groups: undefined
> index: 26
> input: "<b class="hello">Hello</b><i>world</i>"
> length: 4
- 非キャプチャ・グループ:非キャプチャ・グループと呼ばれ、そのグループに対してマッチが返されない、つまり、マッチの結果に括弧がカウントされないことを意味します。
非キャプチャグループの役割 fooまたはfoofooのマッチが必要だと仮定して、正規表現を/{1, 2}/と書くシナリオを考えてみましょう。非キャプチャグループを使って正規表現を /{1, 2}/ に変更することができます。
var m = 'abc'.match(/(?:.)b(.)/);
m // ["abc", "c"]
通常の逆アセンブルURL
// 通常のマッチング
var url = /(http|ftp):\/\/([^/
]+)(\/[^
]*)?/;
url.exec('http://.om/');
// ["http://.om/",&sp;"tp",&sp;".om",&sp;"/"]
// 非キャプチャ・グループ・マッチング
var url = /(?:http|ftp):\/\/([^/
]+)(\/[^
]*)?/;
url.exec('http://.om/');
// ["http://.om/",&sp;".om",&sp;"/"]
- 事前アサーション: x(?=y) は先行アサーションと呼ばれ、マッチする前に x の後に y が続き、返される結果には y はカウントされません。例えば、数字の後にパーセント記号をマッチさせるには /d+/ と書きます。
最初のアサーション」の括弧で囲まれた部分は返されません。
var m = 'abc'.match(/b(?=c)/);
m // ["b"]
- 先験的否定アサーション: x(?y) は事前否定アサーションと呼ばれ、マッチングの前に x の後に y が続かない場合、y は返り値にカウントされません。例えば、パーセント記号が続かない数値にマッチするには /d+/ と書きます。
/\d+(?!\.)/.exec('3.14') // ["14"]
JSONオブジェクト
JavaScript Object NotationJSON(JavaScript Object Representationの略)は、データ交換のためのテキストフォーマットで、2001年にDouglas Crockfordによって、煩雑なXMLフォーマットに代わるものとして提案されました。- Jsonの大きな利点は、シンプルに記述できること、jsのネイティブ構文に準拠しており、jsエンジンで直接処理できることです。
- 各JSONオブジェクトは値であり、配列、オブジェクト、プリミティブ型のいずれかになります。
- Jsonの型とフォーマット:
- 複合型の値として指定できるのは配列かオブジェクトのみで、関数や正規表現オブジェクト、日付オブジェクトは指定できません。
- プリミティブ値には、文字列、数値、ブーリアン、ヌルの4種類しかありません(NaN、Infinity、-Infinity、undefinedは使えません)。
- 文字列は一重引用符ではなく、二重引用符を使って表現する必要があります。
- オブジェクトのキー名は二重引用符で囲む必要があります。
- 配列やオブジェクトの最後のメンバにカンマを続けることはできません。
- null、empty array[]、empty object {}はすべてJSONの正規値です。
以下は正規のjsonです。
["one", "two", "three"]
{ "one": 1, "two": 2, "three": 3 }
{"names": [" ", " "] }
[ { "name": " "}, {"name": " "} ]
- JSONオブジェクトはjsのネイティブオブジェクトで、JSON形式のデータを処理するために使用されます。
- JSON静的メソッド:JSON.stringify()は、値をJSON文字列に変換し、JSON.parse()で縮小できます。
用途と紹介
オブジェクトに未定義のプロパティ、関数、XMLオブジェクトがある場合、プロパティはJSON.stringifyでフィルタリングされます。
var obj = {
a: undefined,
b: function () {}
};
JSON.stringify(obj) // "{}"
配列のメンバが未定義、関数、XML オブジェクトの場合は null に変換されます。
var arr = [undefined, function () {}];
JSON.stringify(arr) // "[null,null]"
通常のオブジェクトはヌルオブジェクトに変換されます。
JSON.stringify(/foo/) // "{}"
オブジェクトの非可読プロパティは、JSON.stringify では無視されます。
var obj = {};
Object.defineProperties(obj, {
'foo': {
value: 1,
enumerable: true
},
'bar': {
value: 2,
enumerable: false
}
});
JSON.stringify(obj); // "{"foo":1}"
JSON.stringify 第2パラメータ
JSON.stringifyメソッドの第2パラメータが配列の場合、文字列に変換する必要があるプロパティを指定するために使用します。オブジェクトのプロパティに対してのみ有効です。
var obj = {
'prop1': 'value1',
'prop2': 'value2',
'prop3': 'value3'
};
var selectedProperties = ['prop1', 'prop2'];
JSON.stringify(obj, selectedProperties) // "{"prop1":"value1","prop2":"value2"}"
2番目の引数は、関数の場合、JSON.stringifyの戻り値を変更するために使用できます。
function f(key, value) {
if (typeof value === "number") {
value = 2 * value;
}
return value;
}
JSON.stringify({ a: 1, b: 2 }, f) // '{"a": 2,"b": 4}'
ハンドラーが未定義または戻り値を返さない場合、このプロパティは無視されます。
function f(key, value) {
if (typeof(value) === "string") {
return ; // return undefined;
}
return value;
}
JSON.stringify({ a: "abc", b: 123 }, f)
JSON.stringify第3パラメータ
JSON.stringifyは、返されるJSON文字列に可読性を追加し、返されるjson文字列をフォーマットするための第3パラメータを受け付けることができます。数値は、各属性の前に追加されるスペースを示し、文字列の場合は、各行の前に文字列が追加されます。
JSON.stringify({ p1: 1, p2: 2 }, null, 4);
/*
"{
"p1": 1,
"p2": 2
}"
*/
JSON.stringify({ p1:1, p2:2 }, null, '==||==');
/*
"{
==||=="p1": 1,
==||=="p2": 2
}"
*/
パラメータ・オブジェクトのtoJSONメソッド
引数オブジェクトがカスタムtoJSONメソッドを持っている場合、JSON.stringifyは、元のオブジェクトを無視して、このメソッドの戻り値を引数として使用します。
Date オブジェクトには独自の toJSON メソッドがあります。
var date = new Date('');
date.toJSON() // "T.000Z"
JSON.stringify(date) // ""T.000Z""
toJSON()の応用例の1つは、通常のオブジェクトを自動的に文字列に変換することです。
var obj = {
reg: /foo/
};
// 不设置 toJSON 方法时
JSON.stringify(obj) // "{"reg":{}}"
// 设置 toJSON 方法
RegExp.prototype.toJSON = RegExp.prototype.toString;
JSON.stringify(obj) // "{"reg":"/foo/"}"
JSON.parse(JSON.stringify(obj)) // {reg: "/foo/"}
- JSON静的メソッド: JSON.parse()は、JSON文字列を対応するjs値に変換します。文字列は有効なJSON形式でなければなりません。
try {
JSON.parse("'String'");
} catch(e) {
console.log('parsing error');
}
JSON.parse()の2番目のパラメータには、JSON.stringifyメソッドと同様に関数を指定できます。
function f(key, value) {
if (key === 'a') {
return value + 10;
}
return value;
}
JSON.parse('{"a": 1, "b": 2}', f)
// {a: 11, b: 2}





