在Javascript中引用变量

时间:2013-03-18 02:20:53

标签: javascript variables reference

我之前正在思考一些事情。我想检查函数是否已经放入数组中。如果是这样抛出异常。我用控制台做了一点测试......

enter image description here

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

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

使用它来检查函数/对象是否已经在数组中我可以正确地执行此操作...

enter image description here

有更好的方法吗?

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

修改

我想我对这个小测试的突变是正确的。但我不知道为什么它在第二个例子的第一个日志中的栏

enter image description here

enter image description here

编辑结束

示例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

3 个答案:

答案 0 :(得分: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

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

答案 1 :(得分:1)

执行此操作时:

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

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

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

如果您需要查看数组中是否已存在某个函数,我建议您不要只将数组放在一个大列表中,而是创建一个使用字符串作为键的字典(hashmap,hashtable,无论你想调用它)作为价值的功能。关键是函数的“名称” - 每当你创建该函数时,你都使用相同的名称,并且在内存中不同位置的名称但它们中的相同字符将比较相等。

答案 2 :(得分:1)

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

当您定义两个相同的函数时(在您的情况下为xa),JavaScript会将它们视为单独的函数。这是因为除了函数体之外,函数还维护自己的环境和状态。因此,xax === a返回false的功能不同。

通过设置x = a,您实际上将a中存储的引用复制到x。因此,他们现在指向相同的函数(这是函数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