覚えたい
http://ja.wikipedia.org/wiki/%E5%BD%A2%E5%BC%8F%E6%96%87%E6%B3%95
第11条 式
11条はJSの基本的なところ、オブジェクトのところとかがアレしている
delete演算子ってどこで使うんだよ
11.1 基本式
11.1.1 thisキーワード
ThisBindingの値として評価される
$ node
> this.
this.__defineGetter__ this.__defineSetter__ this.__lookupGetter__ this.__lookupSetter__ this.constructor
this.hasOwnProperty this.isPrototypeOf this.propertyIsEnumerable this.toLocaleString this.toString
this.valueOf
this.Array this.ArrayBuffer this.Boolean this.Buffer this.DataView
this.Date this.Error this.EvalError this.Float32Array this.Float64Array
this.Function this.GLOBAL this.Infinity this.Int16Array this.Int32Array
this.Int8Array this.JSON this.Math this.NaN this.Number
this.Object this.RangeError this.ReferenceError this.RegExp this.String
this.SyntaxError this.TypeError this.URIError this.Uint16Array this.Uint32Array
this.Uint8Array this.Uint8ClampedArray this.assert this.buffer this.child_process
this.clearImmediate this.clearInterval this.clearTimeout this.cluster this.console
this.crypto this.decodeURI this.decodeURIComponent this.dgram this.dns
this.domain this.encodeURI this.encodeURIComponent this.escape this.eval
this.events this.fs this.global this.http this.https
this.isFinite this.isNaN this.module this.net this.os
this.parseFloat this.parseInt this.path this.process this.punycode
this.querystring this.readline this.require this.root this.setImmediate
this.setInterval this.setTimeout this.stream this.string_decoder this.tls
this.tty this.undefined this.unescape this.url this.util
this.vm this.zlib
識別子参照
識別子解決を実行することによって評価
リテラル参照
7.8で示されるように評価
配列初期化子
Arrayオブジェクトの初期化を記述するための四季
- 0個以上の式の並びで構成され、角括弧でくくられる
- 要素はリテラルである必要はない
- 演算したやつを配列に入れることも出来る
- 省略可能
- 要素が配列末尾で省略されると、その要素は配列の長さに寄与しない
> [0,1,2] [ 0, 1, 2 ] > [] [] > ["hello".toUpperCase(), "HELLO".toLowerCase()] [ 'HELLO', 'hello' ] > [ , "bbb", "ccc"] [ , 'bbb', 'ccc' ] > ["aaa", , "ccc" ] [ 'aaa', , 'ccc' ] > ["aaa", "bbb", ].length 2
オブジェクト初期化子
- Objectの初期化を記述する式
- 波括弧でくくられたやつ
- 0個以上の値のペア
- 値はリテラルである必要はない
> {"a"} 'a' > {"a":"b"} { a: 'b' } > {"a":"b".toUpperCase()} { a: 'B' }
グループ化演算子
Expressionの評価結果を返す Reference型に属すことがある(どういうことなの)
11.2 左辺式
プロパティアクセス演算子
ドット表記法、角括弧表記法を使う
obj.name obj['name']
こういう書き方で関数を呼び出すことが出来る
> { val : function() { return "world"; } }.val() 'world' > { val : function() { return "world"; } }["val"]() 'world'
new演算子
引数を持たない
- new NewExpression
- refをNewExpressionの評価結果とする
- constructorをGetValue(ref)tろする
- Type(constructor)がObjectでなければTypeError例外をスローする
- constructorConstruct内部メソッドを実装しないなら、TypeError例外をスローする
- 引数を渡さずにconstructorのConstruct内部メソッドを呼び出した結果を返す
引数を持つ
- new NewExpression Arguments
- refをNewExpressionの評価結果とする
- constructorをGetValue(ref)tろする
- argListを引き数値の内部的なリストを生成し、Argumentsの評価結果とする
関数呼び出し
- refをMemberExpressionの評価結果とする
- funcをGetValue(refと)する
- Type(func)がObjectでないなら、TypeError例外をスロー
- IsCallable(func)がfalseであるならTypeError例外をスロー
- thisValueをundefinedする
引数リスト
- Argument からのリスト
- Arguments ArgumentsListの評価結果
- ArgumentList AssignmentExpressoin
- refをAssignmentExpressionの評価結果
- argをgetValue(ref)
唯一の要素がargであるリストを返す
ArgumentList: ArgumentList, AssignmentExpression
- precedingArgsをArgumentListの評価結果とする
- refをAssignmentExpressionの評価結果とする
関数式
FunctionExpressionの評価結果を返す
11.3 後置式
++を前に置く?後ろに置く?といったところ
後置インクリメント演算子
すべての条件がtrueならSyntaxError例外をスローする * Type(lhs)がReference * IsStrictReference(lhs) * Type(GetBase(lhs))がEnvironmentRecord * GetReferencedName(lhs)が"eval"または"arguments"
- newValue = oldValue + 1
- PutValue(lhs, newValue)を呼び出す
- oldValueを返す
後置デクリメント演算子
-1
すべての条件がtrueならSyntaxError例外をスローする * Type(lhs)がReference * IsStrictReference(lhs) * Type(GetBase(lhs))がEnvironmentRecord * GetReferencedName(lhs)が"eval"または"arguments"
- newValue = oldValue - 1
- PutValue(lhs, newValue)を呼び出す
- oldValueを返す
11.4 単項演算子
delete演算子
> obj = { a : "hello", b : "world" } { a: 'hello', b: 'world' } > obj.a 'hello' > obj.b 'world' > delete obj.a true > obj { b: 'world' } > obj.b 'world' > obj.a undefined
void演算子
void UnaryExpression
- exprをUnaryExpression
- GetValue(expr)
- undefined
なんのために使うんだろう
> typeof { } 'object' > typeof void { } 'undefined' > typeof NaN 'number' > typeof void NaN 'undefined'
typeof演算子
生成規則UnaryExpression typeof UnaryExpression
- valをUnaryExpressionの評価結果とする
- Type(val)がReferenceで
- IsUnresolvableReference(val)がtrueなら、"undefined"を返す
- valをGetValue(val)とする
- 表20に従いType(val)により決定されるStringを返す
> typeof void 0 'undefined' > typeof null 'object' > typeof true 'boolean' > typeof 1 'number' > typeof "hello" 'string' > typeof { } 'object' > typeof (function() { return 0; }) 'function'
単項+演算子 単項-演算子
その被演算子をNumber型へ変換する
> +1 1 > +NaN NaN > 1+"1" '11' > !(+0) true > -(+0) 0
ビット否定演算子(~)
ビット補数演算を適用
ビット否定演算子、結果は32bit固定でよい?
論理否定演算子(!)
oldValueがtrueならfalse
ディスカッション
前置後置
値を返す直前にput
前置と後置の違いは返す値が前か後ろかっていうこと
oldValueを返すということは、最初の値を返す
よく言われるのが、前置は返してから増やす 後置は増やしてから返す→でもJavaScriptでは間違い
> a = 0 0 > a++ 0 > a++ 1 > ++a 3 > a = "a" 'a' > a++ NaN > a = "11" '11' > a++ 11 > a 12 > b = "12" '12' > typeof b 'string' > b++ 12 > typeof b 'number' > b 13
JSは型がない。型システムの言語だとたぶんこういう書き方をするとエラーになる
記法
ドットだとアクセスできないキー名が存在する
例
> obj = {"hello world": 0} { 'hello world': 0 } > obj."hello world" ... > obj["hello world"] 0
htmlのforms
thisみたいな予約語をキーにすると、ドット記法が使えなくなってしまう。ので、別の記法を用意している
> obj = { "this" : "test" } { this: 'test' } > obj.this 'test' > obj["this"] 'test' > obj = { "return" : "hoge" } { return: 'hoge' } > obj.return 'hoge' > obj["return"] 'hoge' > obj = { return : "hoge" } { return: 'hoge' } > obj.return 'hoge' > obj = { + : "hoge" } ... > obj = { "+" : "hoge" } { '+': 'hoge' } > obj.+ ...
ビット否定演算子
> ~ 0xffff -65536 > ~ 0xff -256 > ~ 0xff -256 > ~ 0xffff -65536
論理否定演算子
> ! 0xffff false > ! 0 true
void
form onclick=="JavaScript:void()"
delete
- 狙い撃ちにして消す
- strictモードでは使えない
- 値自体は消えないので、メモリ節約にはならない