JavaScript おれおれ Advent Calendar 2011 – 3日目
演算子というと+
とか=
とか&&
とか記号が思い浮かぶんじゃないかと思うんですが、アルファベットで構成される演算子っていうのもあるんですよね。ちょいとまとめてみます。
new
delete
typeof
void
instanceof
in
順に見て行きましょう。
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