3

Javascriptでは、丸括弧で囲まずに文字列リテラルのメソッドを直接呼び出すことができます。ただし、数値や関数などの他のタイプは対象外です。これは構文エラーですが、Javascriptレクサーがこれらの他のタイプを丸括弧で囲む必要がある理由はありますか?

たとえば、アラートメソッドを使用してNumber、String、およびFunctionを拡張し、リテラルでこのメソッドを呼び出そうとすると、Stringに対しては機能しますが、NumberおよびFunctionのSyntaxErrorになります。

function alertValue() {
    alert(this);
}

Number.prototype.alert = alertValue;
String.prototype.alert = alertValue;
Function.prototype.alert = alertValue;

文字列オブジェクトに対して直接alertを呼び出すことができます。

"someStringLiteral".alert() // alerts someStringLiteral

しかし、それは数値と関数の構文エラーです。

7.alert();
function() {}.alert();

これらのタイプを使用するには、角かっこで囲む必要があります。

(7).alert(); // alerts "7"
(function() {}).alert(); // alerts "function() {}"

更新

@Crescentによるリンクと@Davおよび@Timothyによる回答7.alert()は、数値定数を探しているために失敗する理由を説明しています。それを乗り越えるには、余分な空白または余分なドットを挿入します。

7 .alert()
7..alert()
7. .alert();

関数を呼び出す前に関数を括弧で囲む必要があるのと同様の構文上の理由はありますか?

Rubyは動的言語であり、この問題を処理するため、ある種の先読みで解決できる問題であるかどうかを知るために、通訳者や字句解析者に精通していません。例えば:-

7.times { |i| print i }

アップデート2

@CMSの答えは、関数が上記で機能しなかった理由を理解する上で的を射ています。以下のステートメントは機能します。

// comma operator forces evaluation of the function
// alerts "function() {}"
<any literal>, function() {}.alert();​​​​​​​

// all examples below are forced to be evaluated as an assignment expression
var a = function() {}.alert(); 

var b = {
    x: function() { return "property value" }.alert()
}

[ function() { return "array element" }.alert() ];​
4

5 に答える 5

6

文字通り、他のNumberすべての答えはあなたを正しい方向に向けています、それ7.は有効ですDecimalLiteral

文法は、最初のドットの後の10進数がオプションであることを示しています。

DecimalLiteral ::
DecimalIntegerLiteral . DecimalDigitsopt ExponentPartopt 

*optサフィックスに注意してください

ここで、関数の場合、問題は、ステートメントコンテキストで評価されていることです。

関数オブジェクトを作成するための2つの有効な文法的方法があります(関数を作成する3番目の方法はFunctionコンストラクターを使用することですが、今のところトピックから外れています)。

FunctionDeclaration:

function name(/*[param] [, param] [..., param]*/) {
   // statements
}

関数式:

var foo = function /*nameopt*/(/*[param] [, param] [..., param]*/) {
  // statements
};

文法はほとんど同じですが、違いはfunctionキーワードが表示される場所です。

関数宣言は、functionキーワードがグローバルコード上または関数内で直接見つかった場合に発生しFunctionBodyます。

関数式が発生すると、上記の例のように、キーワードfunctionコンテキストで見つかります。2番目の関数はの一部ですAssignmentExpression

しかし、実際には2つの問題があります。まず、aの名前FunctionDeclarationは必須です。

次に、FunctionDeclarationステートメントが評価されると、ドットが予期されていないため、ドットは単にaを引き起こしSyntaxErrorます。

関数を括弧で囲むと(正式にはグループ化演算子と呼ばれます)、関数は式コンテキストで評価されます。これは関数式です。

たとえば、次のようになります。

0,function () {}.alert();

上記は、コンマ演算子が式を評価するために機能します。

FunctionDeclarationsまた、は「解析時」(より正確には、コントロールが変数インスタンス化プロセスによって実行コンテキストに入るとき)に評価され、識別子(関数名)が現在のスコープ全体で使用できるようになることも知っておく必要があります。例:

foo(); // alerts "foo", function made available at 'parse time'
foo = function () { alert('bar') }; // override with a FunctionExpression
function foo () { alert('foo'); } // FunctionDeclaration
foo(); // alerts "bar", the overriden function

おすすめ記事:

于 2010-04-28T04:17:13.883 に答える
3

ヒント:7.は有効な数値定数です。

于 2010-04-28T03:24:48.373 に答える
1

レクサーは、ピリオドがすぐに続く数値を確認すると、10進値を期待しています。7 .alert()のように、「創造的」になって数字の間にスペースを入れることはできますが、コードの保守に行き詰まった場合、人々はおそらくあなたを追い詰めるでしょう。

于 2010-04-28T03:26:01.203 に答える
0

数値が期待する小数点を使用すると、オブジェクトが期待するとおりにドット演算子が機能します。

7.0.toFixed(0)

于 2010-04-28T04:06:58.667 に答える
0

曖昧さを解消するために括弧を使用することを好みます。

(7).alert();
于 2010-04-28T05:18:24.823 に答える