by shigemk2

当面は技術的なことしか書かない

第8回 ECMA-262 Edition5.1読書会

覚えたい

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モードでは使えない
  • 値自体は消えないので、メモリ節約にはならない