2

私は今、javascript を学んでいます。私には美しい関数型言語のように思えます。PHP からの素晴らしい移行です。もっと早くこれを行うべきでした。ただし、これを理解することはできません:

var v1 = (/[abc]/).test;
v1('a');

test method called on incompatible undefined、その正規表現のテスト メソッドを変数に格納し、後で呼び出すようにしています。

しかし、それは私自身の機能で動作します:

function foo(){
    return 'I\'m foo';
}

var f = foo;
f(); // returns I'm foo

とにかく関数は親オブジェクトのメソッドにすぎないので、メソッドでも機能するはずですよね?

最終的に、私がこれを試みている理由は、次のようなものを書くことができるようにするためです:

var a = ['a', 'b', 'c'];
a.every( (/[abc]/).test );

その正規表現に対して各配列メンバーをチェックします。

なぜこれが機能しないのですか?組み込み関数を渡す際の制限ですか? それとも、私は何か間違ったことをしていますか?

PS: 今、歯を食いしばって、悪い習慣について何かをこもらせたり、良い習慣を台無しにしたりするとしたら、私は遊んでいるだけです。しかし、私はそれらについても聞きたいです。

4

5 に答える 5

3

メソッドだけを保存すると、オブジェクトへの参照は保持されません.test。メソッドへの参照が保存されるだけで、特定のオブジェクトは保持されません。メソッドはオブジェクトの「単なる」プロパティであり、メソッドへの参照を保存してもオブジェクトにバインドされず、メソッドへの参照が保存されるだけです。

特定のオブジェクトでそのメソッドを呼び出すには、そのオブジェクトでそれを呼び出す必要があります。

次のように、目的のオブジェクトでメソッドを呼び出す独自の関数を作成できます。

var v1 = function(x) {
    return /[abc]/.test(x);
}

次に、これを行うと:

v1('a');

関数でこれと同等のことを実行します。

/[abc]/.test('a');

ただし、正規表現を定義して .test() を数回呼び出すこともできるため、なぜそうしているのかは完全には明らかではありません。

var myRegex = /[abc]/;
console.log(myRegex.test('a'));
console.log(myRegex.test('b'));
console.log(myRegex.test('z'));
于 2013-06-12T00:25:12.030 に答える
3

それは私自身の機能で動作します

関数内で使用していませんthis。次の例を検討してください。

var obj = {
    foo: 42,
    bar: function() {
        alert(this.foo);
    }
};
var f = obj.bar;
f(); // will alert `undefined`, not `42`

とにかく関数は親オブジェクトのメソッドにすぎないので、メソッドでも機能するはずですよね?

「メソッド」は、オブジェクトのプロパティに割り当てられた関数の口語的な用語です。関数はスタンドアロンの値です。関数が割り当てられているオブジェクトへの接続はありません。関数は複数のオブジェクトに割り当てることができるのに、どうしてこれが可能になるのでしょうか?

なぜこれが機能しないのですか?

this関数内で何を参照するかは、実行時に決定されます。したがって、関数を変数に割り当てて後で呼び出す場合

var v1 = (/[abc]/).test;
v1('a');

this関数内ではwindow、正規表現オブジェクトではなく、 が参照されます。

できることは、.bind [MDN]thisを使用して特定の値に明示的にバインドすることです。

var a = ['a', 'b', 'c'];
var pattern = /[abc]/;
a.every(pattern.test.bind(pattern));

ただし.bind、関数を返すため、関数式を使用する場合の唯一の利点は、記述が少し短いことです。


組み込み関数を渡す際の制限ですか?

いいえ、それが関数の仕組みであるため、すべてのメソッド/関数に問題が存在します。ただし、組み込み関数の良いところthisは、 が間違った型のオブジェクトを参照している場合 (エラーをスローすることによって) を明示的に教えてくれることが多いことです。


の詳細をご覧くださいthis

于 2013-06-12T00:29:27.107 に答える
1

test関数は正規this表現である必要があります。式/[abc]/.testは束縛されていない関数を与えます (それが に属していることを覚えていません/[abc]/)。あなたがそうするようにそれを呼び出すthisundefined、関数は失敗します。

bind関数が属するオブジェクトを関数に記憶させるために使用できます。

var v1 = /[abc]/.test.bind(/[abc]/);

また

var v1 = RegExp.prototype.test.bind(/[abc]/);
于 2013-06-12T00:32:20.283 に答える
0

メソッドへの参照は、それが何のメソッドであったかについての知識を失いました。これは、JS が機能する方法としてはあまり良い方法ではありません。

できるよ:

var v1 = /[abc]/;
v1.test('a');    

テスト メソッドをカプセル化する必要がある場合は、次のようにします。

var v1 = function(str){
    return /[abc]/.test(str);
};
v1('a');
于 2013-06-12T00:25:12.690 に答える
0

これが許容できる解決策かどうかはわかりませんが、次のことができます。

v1 = function(exp) { return (/[abc]/).test(exp); }
v1('a');
于 2013-06-12T00:25:27.260 に答える