質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

2回答

1479閲覧

Functionクラスについて

foo45

総合スコア106

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2015/10/28 12:57

javascript

1 2var obj1 = new Function("return 1;"); 3 4console.log(obj1 instanceof Function);

前回の質問でこのようなコードを書き、動かした結果からFunctionクラスは関数で、new演算子でオブジェクトを作っていることから、コンストラクタであると思ったのですが、なぜ引数を渡すだけで新たな関数オブジェクトが定義できるのか不思議です。
上記のコードのように僕が書いたら、インスタンス生成のとき引数で渡した値がデフォルトでセット(初期化)されてオブジェクトのメンバになるのですよね?
なぜそれで新たな関数が定義できるのでしょうか。

Functionクラスの内部のコードはどのようになっているのか教えてください。
またFunctionクラスもオブジェクトということは、その上にクラスをまとめるもののようなものがるのですか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

むしろfunction() {}と書くとnew Function()として解釈されると思っていいでしょう。
Function の中身については、多くは JavaScript ではありません。
各 JS 実装系のネイティブコード (例えば Chrome の JS 実行環境 "V8" なら、C++) で書かれています。

そして JavaScript (ECMAScript) の仕様として、 Function のインスタンスは「関数」であり、() を付けることでその処理内容を実行することが取り決められています。

つまり特別扱いです。Function のインスタンスは本来、現在の JavaScript では実装できない機能を持っています。
他に Array のインスタンスも、arr[1] = "foo";とするだけでlengthプロパティが変化するなど、現在のJavaScriptでは実装できません。

Functionクラスもオブジェクトということは、その上にクラスをまとめるもののようなものがるのですか?

JavaScript で一般にクラスと呼ばれているものは、厳密には「コンストラクター関数」です。
つまりFunction自体も関数であり、Function instanceof Functiontrueになります。
そして、あらゆるクラスをまとめるものという意味では、JavaScript にはすべてのオブジェクトの基底クラスとなる Object が存在します。

Function instanceof Functiontrueですし、Function instanceof Objecttrueです。
継承関係にあるといえます。
<あらゆるオブジェクト> instanceof Objectはほとんどすべてのケースでtrueとなります。

ただし、ややこしくなりますが、JavaScript にはオブジェクトと呼ばれるものが2種類存在します。
それは、Objectobjectです。
前者はいわゆるクラス。コンストラクター関数の名前です。
後者は値の型です。JavaScript では、値の型とクラスは分けて考えます。

(ここでも特別扱いが存在するのでややこしいのですが、) Function インスタンス以外のオブジェクトの型は、基本的にすべてobjectです。(Function のみfunction型が用意されています。)

typeof {}: "object"(new Object() と同じため)
typeof []: "object"(new Array() と同じため)
typeof /foo/: "object"(new RegExp("foo") と同じため)
typeof new String("foo"): "object"(typeof "foo" とは違います)
typeof function(){}: "function"(new Function() と同じにもかかわらず、特別扱い)

functionobjectではありません。型には継承関係は存在しないのです。

そして、最後のややこしさ。
<あらゆるオブジェクト> instanceof Objectはほとんどすべてのケースでtrueとなります。
の、「ほとんどすべて」に該当しないケースの話です。

var obj = Object.create(null); とした時、
typeof obj: object なのに、
obj instanceof Object: false になります。

object型なのに、Objectクラスのインスタンスではないのです。
この辺の意味まではまだ…、存在するという紹介にとどめておきます。

object かつ Object である {}``new Array()など
object だが Object ではない Object.create(null)実はnull自体も何故かここ
object ではないが Object である function(){}``new Function()
object でも Object でもない 3.14``true``"foo"など。スカラー型

ということで、まじめに考えるとちょっとややこしい JavaScript のクラスと型まわりの話です。

投稿2015/10/29 01:50

tozjp

総合スコア790

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

foo45

2015/10/29 06:43

とても詳しく書いていただきありがとうございます! このあたりの事がもっと詳しく書かれている技術書を探しているのですが、ありますでしょうか?
think49

2015/10/29 13:38

To: tozjpさん > そして、あらゆるクラスをまとめるものという意味では、JavaScript にはすべてのオブジェクトの基底クラスとなる Object が存在します。 ECMAScript においてある一つのデータに対して [[Class]] は唯一のものです。 例えば、new Function の [[Class]] は Function であり、Object を [[Class]] に持ちません。 プロトタイプチェーンとしては [[Prototype]] の行き着く先に Object が存在するという考え方は出来なくもありませんが、ECMAScript 規定外の JavaScript API 仕様では必ずしも Object を [[Prototype]] に持ちません。 つまり、arg instanceof Object は Object 型を保証しません。 > ただし、ややこしくなりますが、JavaScript にはオブジェクトと呼ばれるものが2種類存在します。 > それは、Objectとobjectです。 > 前者はいわゆるクラス。コンストラクター関数の名前です。 > 後者は値の型です。JavaScript では、値の型とクラスは分けて考えます。 型の名前が小文字から始まるわけではありません。 new Object は「Object 型」であり、型の名称は大文字から始まるルールです。 http://www.ecma-international.org/ecma-262/6.0/#sec-object-type > (ここでも特別扱いが存在するのでややこしいのですが、) Function インスタンス以外のオブジェクトの型は、基本的にすべてobjectです。(Function のみfunction型が用意されています。) オブジェクトの型は全て等しく「Object 型」です。 typeof 演算子を「型の文字列を返す演算子」と認識されているようですが、厳密には異なります。 typeof 演算子で "function" を返す対象は「`[Call]]` を持つ Object 型」です。 「`[Call]]` を持つ Object 型」であれば関数であり、関数が `Function` のインスタンスとは限りません。 typeof 演算子は Object 型に限ってはかなり細かく返り値を分類しており、「Object 型」の判定には向いていないのが実情です。 http://www.ecma-international.org/ecma-262/6.0/#sec-typeof-operator To: foo45さん 深い理解を望むのなら『JavaScript 第6版』『ECMA-262 Edition 5.1を読む』がお勧めです。 http://www.amazon.co.jp/dp/4873115736 http://www.amazon.co.jp/dp/479803892X
guest

0

大雑把にいえば、下記コードの fn1, fn2 は同じです。

JavaScript

1var fn1 = new Function("return 1;"); 2var fn2 = function () { return 1;};

JavaScript における関数とは「[[Call]] を持つオブジェクト」です。
ですので、プロパティが存在しますし、プロトタイプ上に Object#hasOwnProperty 等も存在します。
プロトタイプチェーンがどのように組まれているかについては Object.getPrototypeOf__proto__ を使えば分かるでしょう。

JavaScriptにクラスはない
JavaScript はプロトタイプベースなので「クラス」という表現は誤解を招くと思います。

投稿2015/10/28 13:27

think49

総合スコア18162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

foo45

2015/10/28 14:05

このMDNというサイトのコンテンツがまさに知りたかったことです じっくり勉強してみます。ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問