2

我之前在思考一个问题。我想检查一个函数是否已经被放入一个数组中。如果是这样抛出异常。我用控制台做了这个小测试......

在此处输入图像描述

所以我想我可以说对象总是只是引用,并且在设置之后ax可以更改x并且a也会受到影响?

这是否意味着条件x = a无论如何,这就是我想要的。

使用它来检查函数/对象是否已经在数组中,我可以正确地做到这一点......

在此处输入图像描述

有一个更好的方法吗?

这是否也意味着如果我将一个变量传递给一个函数并在该函数中对其进行变异,它也会在该函数之外发生变异?

编辑

我想我对这个小测试的突变是正确的。但我不明白为什么它在第二个示例的第一个日志中出现栏

在此处输入图像描述

在此处输入图像描述

编辑结束

示例 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 == 一个

我认为您理解但只是想澄清一下,x并且a最初是不同的,因为它们引用了不同的功能。当您设置x = a它们时,它们都指向最初声明的函数x,因此是相同的。即使这些功能在实现方面是相同的,但它们都是被构造的,然后被放置在内存的不同部分中。

于 2013-03-18T02:32:53.650 回答
1

当你这样做时:

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

xa指向不同的功能。即使您比较它们是否相等,它们也不相等,因为这里的所有相等检查都是查看它们是否指向相同的函数 - 没有尝试查看它们在运行时是否会产生相同的输出(即毕竟,一般来说几乎不可能做到)。

当您执行类似的操作时x = a, x 现在引用 a 所引用的任何内容 - 同一个对象。所以现在他们比较平等。

如果您需要查看数组中是否已经存在函数,我建议您创建一个字典(哈希映射、哈希表,无论您想调用什么),而不是仅仅将数组放在一个大列表中,它使用字符串作为键作为函数价值观。关键是函数的“名称” - 每当您创建该函数时,您将使用相同的名称,并且内存中不同位置但具有相同字符的名称将比较相等。

于 2013-03-18T02:31:42.153 回答
1

你真的很困惑。JavaScript 中的所有内容(除了原始数据类型nullundefined)都是对象,并且对象作为引用存储在变量中。阅读以下答案以了解有关两者之间差异的更多信息:https ://stackoverflow.com/a/13268731/783743

当您定义两个相同的函数(在您的情况下xa)时,JavaScript 将它们视为单独的函数。这是因为除了函数体之外,函数还维护自己的环境和状态。因此xa不是同一个函数,这就是为什么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该对象不在数组中。

如果要检查两个函数的函数体是否相同,请使用此函数:

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

只要两个函数完全相同(包括空格、参数、函数名等),现在console.log(sameFunctionBody(x, a))就会返回。true

于 2013-03-18T02:42:03.950 回答