2

以前、あることを考えていました。関数がすでに配列に入れられているかどうかを確認したかったのです。その場合は、例外をスローします。コンソールでこの小さなテストを行いました...

ここに画像の説明を入力

つまり、オブジェクトは常に単なる参照であり、aasxを設定した後、変更xaて影響を受ける可能性があると言えるでしょうか?

x = aこれは、私が望んでいることは何であっても条件を意味するのでしょうか。

これを使用して、関数/オブジェクトが既に配列にあるかどうかを確認するだけで、これを正しく行うことができます...

ここに画像の説明を入力

これを行うより良い方法はありますか?

これは、変数を関数に渡してその関数で変更すると、その関数の外でも変更されることを意味しますか?

編集

私は、この小さなテストで突然変異について正しいと思います。しかし、2番目の例の最初のログにある理由がわかりません

ここに画像の説明を入力

ここに画像の説明を入力

編集終了

例 1:

var x = function(){console.log("hello")}; var a = function(){console.log("hello")}; 

console.log(x == a); //comes out false

//Set a as x
a = x; 

console.log(x == a); //comes out true

例 2:

Array.prototype.Contains = Array.prototype.Contains || function (obj) {
    return this.indexOf(obj) != -1;
};

var x = function(){console.log("hello")}; var a = function(){console.log("hello")}; 

var z = a;

console.log(x == a); //comes out false

var l = [];
l.push(x);

//Set a as x
a = x; 

l.push(a);

console.log(x == a); //comes out true

console.log(l.Contains(x)); //Should come out true
console.log(l.Contains(a)); //Should come out true
console.log(l.Contains(z)); //Should come out false
4

3 に答える 3

3

あなたの質問は私には完全に明確ではありませんが、できる限り答えようとします。

機能の向上

関数を活用するために、indexOf関数を単純化することができます。

Array.prototype.Contains = Array.prototype.Contains || function (obj) {
    return this.indexOf(obj) >= 0;
};

また、実装では、内部に戻ることで早期に終了できる場合、すべてをループしていることを指摘したいと思いますif

Array.prototype.Contains = Array.prototype.Contains || function (obj) {
    var i;
    for (i = 0; i < this.length; i += 1) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
};

x == a

理解していると思いますが、明確にしたいだけで、x異なるa機能を参照しているため、元々異なります。設定x = aすると、両方とも最初に宣言された関数を指してxいるため、同じです。関数は実装に関しては同じですが、両方とも構築され、メモリの異なる部分に配置されました。

于 2013-03-18T02:32:53.650 に答える
1

これを行う場合:

var x = function(){console.log("hello")}; var a = function(){console.log("hello")}

xさまざまな機能をa指します。等しいかどうかを比較したとしても、ここですべての等価チェックが行うのは、それらが同じ関数を指しているかどうかを確認するためです。実行時に同じ出力が生成されるかどうかを確認する試みはありません (つまり、結局のところ、一般的に行うことはほとんど不可能です)。

のようなことをするとx = a、 x は、 a が参照しているものすべてを参照するようになりました-同じオブジェクト。だから今、それらは等しく比較されます。

関数が配列に既に存在するかどうかを確認する必要がある場合は、配列を大きなリストに配置するだけでなく、文字列をキーとして関数として使用する辞書 (ハッシュマップ、ハッシュテーブルなど、任意の名前) を作成することをお勧めします。値。キーは関数の「名前」になります。その関数を作成するときはいつでも同じ名前を使用し、メモリ内の異なる場所にあるが同じ文字を含む名前は同等に比較されます。

于 2013-03-18T02:31:42.153 に答える
1

あなたは本当に混乱しています。JavaScript のすべて (プリミティブ データ型と を除くnull)undefinedはオブジェクトであり、オブジェクトは参照として変数に格納されます。2 つの違いについて詳しくは、次の回答をお読みください。

2 つの同一の関数 (あなたのケースではxa) を定義すると、JavaScript はそれらを別個の関数として認識します。これは、関数本体に加えて、関数も独自の環境と状態を維持するためです。したがってx、 とaは同じ関数ではないため、 がx === a返されますfalse

を設定x = aすると、基本的に に保存されている参照が にコピーさaxます。したがって、これらは同じ関数を指すようになりました (これは、a最初に参照していた関数です)。元々参照していた関数xは失われ、最終的にガベージ コレクションが行われます。したがってx === a、 が返されますtrue

Containsところで、オブジェクトがすでに配列内にあるかどうかを確認するために特別な関数を作成する必要はありません。使用するだけindexOfです:

var array = [];
function x() {}

array.indexOf(x); // returns -1
array.push(x);
array.indexOf(x); // returns 0

インデックスが0オブジェクトより小さい場合、配列にはありません。

2 つの関数の関数本体が同じかどうかを確認する場合は、次の関数を使用します。

function sameFunctionBody(a, b) {
    return String(a) === String(b);
}

両方の関数がまったく同じである限り(空白、パラメーター、関数名などを含む)console.log(sameFunctionBody(x, a))が返されるようになりました。true

于 2013-03-18T02:42:03.950 に答える