0

どうしても、次のようなことをすることは可能ですか:

function A() {
    var Loaded = 'loaded';
    raise Loaded;
}
function A_raise(evt) {
    console.log(evt);
}
A.prototype.constructor = A;
A.prototype.raise = A_raise;

重要な部分は次の行です。

raise Loaded;
4

2 に答える 2

4

JavaScript で括弧のない関数呼び出しを取得する唯一の方法は、setter/getter プロパティを定義するか、または特別なメソッドの 1 つをオーバーライドすることtoStringですvalueOf。どちらの場合も、呼び出しに渡されるパラメーターを適切に制御することはできません。

function C() {}
C.prototype.valueOf = function () { alert("valueOf called"); };
var c = new C();
// No parentheses
+c;

括弧なしでコンストラクターを呼び出すことはできますが、引数を渡すことはできません。

function f() { alert("f"); }
// No parentheses
new f

できない理由の 1 つは、セミコロンの挿入です。

f()

そのまま関数呼び出しです

f
()

if
(x) { }

は言語のコア部分であるため有効な条件ですifが、関数呼び出しから括弧を削除できる場合、セミコロン挿入はコードを次のように処理する必要があります

var x = raise

y

関数呼び出しの結果に初期化される変数として。


言語拡張について質問されたので、EcmaScript 仕様の第 16 章には、インタープリターが言語の文法に追加できると書かれています。

実装は、プログラム構文と正規表現パターンまたはフラグ構文を拡張する場合があります。これを許可するために、SyntaxError のスローが許可されているすべての操作 (eval の呼び出し、正規表現リテラルの使用、Function または RegExp コンストラクターの使用など) は、実装に遭遇したときに SyntaxError をスローする代わりに、実装定義の動作を示すことが許可されます。プログラム構文または正規表現パターンまたはフラグ構文の定義済み拡張。

それ以来

 raise foo

言語で有効な表現またはステートメントではない場合、許可することはできますが、意味を変えるような方法で許可することはできません。

 raise
 foo

と同じ意味を持つ必要があります

 raise;
 foo

そのため、インタプリタはraise新しい制限されたプロダクションを作成する必要がありますが、これは言い回しのために問題があります:

以下は、文法で制限された唯一のプロダクションです:

それはおそらく非規範的であることを意味していますが、明示的にそうではありません。

于 2013-02-27T17:59:51.193 に答える
1

JavaScript では新しいステートメントを定義できないため、 に示す構文を実際に作成することはできませんA

編集:質問に対するあなたのコメントから、新しいステートメント/キーワードを定義しようとしていることは明らかです。いいえ、できません。


元の答え:

Aコンストラクター内で関数を呼び出すことを目標にしていますか? A_raiseもしそうなら、あなたは本当に近いです。変更するだけです:

raise Loaded;

this.raise(Loaded);

実例| ソース

newキーワードによるコンストラクター関数の呼び出し内には、コンストラクター関数のプロパティthisからプロトタイプを既に受け取っている、新しく構築されたオブジェクトがあります。prototypeしたがって、(プロトタイプを介して)それthisを保持し、関数を参照します。raiseraiseA_raise

しかし、繰り返しになりますが、括弧 (およびthis.) が必要です。

于 2013-02-27T18:02:47.547 に答える