JavaScript おれおれ Advent Calendar 2011 – 3日目
演算子というと+とか=とか&&とか記号が思い浮かぶんじゃないかと思うんですが、アルファベットで構成される演算子っていうのもあるんですよね。ちょいとまとめてみます。
newdeletetypeofvoidinstanceofin
順に見て行きましょう。
new演算子
インスタンスを作る奴ですね。jQueryでもりもり作るような場合にはまず見ないと思うんですが、もっとこうプログラマーちっくにごりごり作る場合にはよく使ったりします。
// MyClassのインスタンスを作成する var obj = new MyClass();
newという演算子はクラスからインスタンス(そのクラスの実体であるオブジェクト)を作成する……というのが一般的な動作です。が、JavaScriptは違います。そのそもクラスというものは存在しません。先の例のMyClassはクラスではなくコンストラクターです。
まあこのあたりの話はまたいずれ、詳しくお話させて頂こうと思っています。
delete演算子
オブジェクトのプロパティを削除します。
var obj = { a: 1, b: 2 };
console.log(obj.a); // => 1
delete obj.a;
console.log(obj.a); // => undefined
削除されたプロパティは参照できないので、undefinedになります。
じゃあ、undefinedを代入するのと何が違うのでしょう?
undefinedを代入した場合は、あくまでその値が代入されているだけで、プロパティは残ります。この状態ではin(後述)やfor inで表示されてしまいます。もちろんconsole系で羅列した場合も表示される事になります。
var a, p, obj;
obj = { a: 1, b: 2 };
delete obj.a;
a = [];
for (p in obj) {
a.push(p);
}
console.log(a.join()); // => b
obj = { a: 1, b: 2 };
obj.a = undefined;
a=[]
for (p in obj) {
a.push(p);
}
console.log(a.join()); // => a, b
またプロトタイプチェインにプロパティがある場合は、自身のプロパティを削除する事でそちらが得られるようになります。
function MyClass() {}
MyClass.prototype.a = 123;
// 自身のプロパティを持たないオブジェクトを作成
var obj = new MyClass();
console.log(obj.a); // => 123
// 自身のプロパティを作成
obj.a = 999;
console.log(obj.a); // => 999
// 自身のプロパティを削除
delete obj.a;
console.log(obj.a); // => 123
typeof演算子
対象の型を文字列で返します。
| 値 | 結果 |
|---|---|
undefined |
"undefined" |
| 真偽値 | "boolean" |
| 数値 | "number" |
| 文字列 | "string" |
| 関数 | "function" |
null |
"object" |
| オブジェクト | "object" |
数値はNaNやInfinityも含みます。
またnew String()で得られるものは文字列ではなくStringオブジェクトであるので、"object"になります。
undefinedの扱いはちょっと例外的
var a; console.log(typeof a); // "undefined" console.log(typeof b); // "undefined" console.log(a); // "undefined" console.log(b); // ReferenceErrorが投げられる
未定義の変数を参照するとReferenceErrorになるのが普通ですが、typeofはエラーにせず"undefined"を返します。
一方定義済みだが値が未定義である変数も同様に"undefined"を返します。
typeof nullが"object"になるのは、実は最初期のただのミス
You know, this all came about because of rushing in early May 1995, which led to a leak of type tag representation shared by null and object types. But null means “no object”, so it didn’t raise hackles until it was too late to fix in Netscape 2, and after that we were loath to “fix” it and “break the web”.
参考
void演算子
右辺を評価後に破棄し、常にundefinedを返します。
var a = 1; console.log(void (a+=1)); // => undefined console.log(a); // => 2
処理自体は行われますので、上記の例では加算を行った後にundefinedが返ります。
ブックマークレットを作る場合にはよく利用されてます。他で使う場面もあるんでしょうか?
instanceof演算子
右辺が左辺のインスタンスであればtrueを、そうでなければfalseを返します。
function MyClass() {}
var obj = new MyClass();
console.log(obj instanceof MyClass); // => true
var obj = {};
console.log(obj instanceof MyClass); // => false
右辺が実行可能でないとTypeErrorが投げられます。
コンストラクターがnew付きで呼ばれたかどうかを判定する場合にも使えます。
function MyClass() {
console.log(this);
if (!(this instanceof MyClass)) {
return new MyClass();
}
}
MyClass();
new MyClass();
newなしで実行すると実行コンテキストがwindow等のグローバルオブジェクトになってしまいます。this.prop = 123のようにプロパティ定義を行ったつもりが、グローバル変数を設定する事になってしまうわけです。
in演算子
右辺で与えられるオブジェクトが左辺で与えられる名前のプロパティを持っていればtrue、そうでなければfalseを返します。
function MyClass() {}
MyClass.prototype.a = 123;
var obj = new MyClass();
obj.b = 456;
console.log("a" in obj); // => true
console.log("b" in obj); // => true
console.log("c" in obj); // => false
プロパティが自身のプロパティであるか、プロトタイプチェイン上のプロパティであるかは問いません。それを判定する場合は .hasOwnProperty()を利用します。
console.log(obj.hasOwnProperty("a")); // => false
console.log(obj.hasOwnProperty("b")); // => true