◆ Ecma6のアレやめてほしい

先に言っておくと 私はクラス嫌いです

ついでに動的型付けも好きなので JavaScript が好きです


ですが そんな JavaScript にもEcma6でクラス対応とかいうではありませんか!

そこまで詳しくしらべてないですが 中身はこれまで通りプロトタイプであって クラス風な記法ができる 程度だと思うんですが それでもクラスっぽい記法になると 書き方がワンパターンぽくなってしまって微妙 というかおもしろみが無いですよ

クラス好きな人が多いし 何かとJavaScript使う人多いので この先クラス記法が当たり前になりそうで怖いです
最近のライトなJavaScriptユーザで new がなくても 同じことができるって知ってる人どれくらいいるんだろ

プロトタイプベースが好きな人達だけが使う言語であってくれればよかったんですが 最近 JavaScript が流行りすぎ感ありますし ブラウザで動く実質唯一の言語が JavaScript なので嫌々使ってる人もいそうです
(昔は Basic か何かもブラウザで動いたんでしたっけ? scriptタグに言語指定する書き方がある以上動く言語が他にもあったはず)

嫌々使ってるクラス好き大勢のせいで そっち方向にいってしまうのはやめてほしいなぁー



JavaScriptでクラスっぽいことするときのために知っておくとよいこと


new があるとちょっと特殊な関数の実行の仕方になります
new があると () がなくても実行できます
引数を指定しないのでもちろん引数はなしでの実行です
function A(){}
var a

// 関数を普通に実行して結果を代入
a = A()

// Aという関数自体を代入
a = A

// new があると A をちょっと特殊に実行して結果を代入
a = new A()

// new があると関数呼び出しの() は省略できますが引数なし
a = new A


単純にオブジェクトを返すだけなら一緒
function A(){
return {
a:1
}
}

console.log(new A)
console.log(A())
Object {a: 1}
Object {a: 1}


プロトタイプに何かあっても使えないです
function A(){
return {
a:1
}
}
A.prototype.sample = 1
A.prototype.method = function(){return "method"}

var na = new A
var a = A()
console.log(na.sample)
console.log(a.sample)
undefined
undefined


Aが何も返さないと結果が違います
普通に実行すると もちろん返り値は undefined ですが new があると Aオブジェクトが返って来ます
function A(){
}
A.prototype.sample = 1
A.prototype.method = function(){return "method"}

var na = new A
var a = A()
console.log(na)
console.log(a)
console.log(na.sample)
A{}
undefined
1


this も違っています
普通に実行すると もちろん Windowですが new があると A オブジェクトです
function A(){
console.log(this)
}
A.prototype.sample = 1
A.prototype.method = function(){return "method"}

new A
A()
A{}
Window{}


this に値を入れるとわかりやすいですが thisのAオブジェクトがそのまま返り値になります
this がwindowだとグローバル変数が増えるだけなので ifで除外してます
function A(){
if(this !== window)
this.a = "a"
}
A.prototype.sample = 1
A.prototype.method = function(){return "method"}

console.log(new A)
console.log(A())
A{a:"a"}
undefined


Aオブジェクトなので __proto__ の先は A.prototype です
function A(){
if(this !== window)
this.a = "a"
}
A.prototype.sample = 1
A.prototype.method = function(){return "method"}

var na = new A
console.log(na.__proto__)
console.log(na.__proto__ === A.prototype)
A {sample: 1}
true



今までのことから new をしなくても new にするためには……
function A(){
var This
if(this === window){
This = {}
This.constructor = A
This.__proto__ = A.prototype
}else{
This = this
}
This.a = "a"
return This
}
A.prototype.sample = 1
A.prototype.method = function(){return "method"}

var na = new A
var a = A()
console.log(na)
console.log(a)
console.log(na.a, na.sample, na.method(), na.constructor, na instanceof A)
console.log(a.a, a.sample, a.method(), a.constructor, a instanceof A)
A {a: "a"}
A {a: "a"}
a 1 method funcion A() true
a 1 method funcion A() true

thisになるオブジェクトThisを作って This に __proto__ を設定
コンストラクタで this に入れる値を This に入れる
最後に This を return する
とやれば new しなくても new と同じようにインスタンスが作れます

constructor は A.prototype にあるのでプロトタイプチェーンがつながっているので付ける必要はないのですが Chromeの console.log の表記が Object になってしまうので Aオブジェクト とわかりやすく表示させるために付けてます
Firefox は何のインスタンスであろうと Object なので書く必要ないです
Chrome のほうが分かりやすい表示ですね


new が new でしかできない特殊なことをやってるわけじゃないとわかればこんなこともできます
function A(){
}
A.new = function(){
var instance = {}
instance.constructor = A
instance.__proto__ = this
instance.a = "a"
return instance
}
A.prototype.sample = 1
A.prototype.method = function(){return "method"}

console.log(A.new())
A {a: "a"}

Rubyにみたいに コンストラクタのメソッド new を実行して インスタンスを作っています

こっちでもうちょっと色々やってます
http://var.blog.jp/archives/46776504.html