JAVASCRIPT: 是传值还是传引用

原文地址:http://snook.ca/archives/javascript/javascript_pass


In JavaScript, we have functions and we have arguments that we pass into those functions. But how JavaScript handles what you’re passing in is not always clear. When you start getting into object-oriented development, you may find yourself perplexed over why you have access to values sometimes but not other times.

在Javascript中,我们有functions和传入functions的参数。但是,Javascript是怎么处理这些参数的并不总是很清楚。当你开始接触面向对象编程的时候,你可能会感到困惑,因为你会发现有的时候感觉是传值,而有的时候是传引用。

When passing in a primitive type variable like a string or a number, the value is passed in by value. This means that any changes to that variable while in the function are completely separate from anything that happens outside the function. Let’s take a look at the following example:

当你传入一个像String或者number的基本数据类型的参数的时候,那么这个是传值。这意味着,在方法中,任何对这个变量的改变都不会对这个方法外产生任何影响。让我们看一个例子:

function myfunction(x)
{
      // x is equal to 4
      x = 5;
      // x is now equal to 5
}

var x = 4;
alert(x); // x is equal to 4
myfunction(x); 
alert(x); // x is still equal to 4

当传入一个对象的时候,那么就是传引用。在这种情况下,这个对象的任何属性在这个方法里都是可以被访问的(对象本身的属性是可以被修改的)。让我们看一下另外的例子:

function myobject()
{
	this.value = 5;
}
var o = new myobject();
alert(o.value); // o.value = 5
function objectchanger(fnc)
{
	fnc.value = 6;
}
objectchanger(o);
alert(o.value); // o.value is now equal to 6

So, what happens when you pass in a method of an object? Most would expect (or at least I did) that it would be passed by reference allowing the method to access other parts of the object it is apart of. Unfortunately, that’s not the case. Check out this example:

所以,当你传入一个对象的方法时会发生什么?大多数人都会认为(至少我这么认为):这个肯定是传引用,允许这个方法可以修改这个对象的其他属性。很遗憾,不是这么一回事。看一下这个例子:

function myobject()
{
	this.value = 5;
}
myobject.prototype.add = function()
{
	this.value++;
}
var o = new myobject();
alert(o.value); // o.value = 5
o.add();
alert(o.value); // o.value = 6
function objectchanger(fnc)
{
	fnc(); // runs the function being passed in
}
objectchanger(o.add);
alert(o.value); // sorry, still just 6

The problem here is the use of the ‘this’ keyword. It’s a handy short-hand for referring to the current object context. When passing a function as a parameter, though, the context is lost. More accurately,this now refers to the context of the object making the call instead of the object’s function we just passed in. For standalone functions, this would be the window object and for functions called from an event, this would be the event object.

在这里的问题是关键字 “this”的运用。"this" 是一个简写,指向当前对象的环境。当把一个function作为一个参数传入的时候,这个环境就丢失了。更确切的说,"this"现在指向的是运行这个方法的对象的环境而不是这个方法原本的环境。对于独立的functions,这个"this"指向的是window对象,而对于在一个事件中被运行的functions,那么这个"this"指代的是这个事件的对象。

Solving the problem 为解决这个问题


There are two possible ways to get around this.

有两种可行的方法去解决这个问题。

Option 1: When you know the method    第一种:当你知道是哪个对象的方法时

If you know the method of the object that will be called then it’s fairly easy. Just pass in the object instead of the function and call that instead. Using the objectchanger from the last example you’d get the following:

如果你知道是哪个对象的方法被传入时,那么一切就会简单很多。不要把对象的方法传入,而是把这个对象传入,同时通过对象运行这个方法。用上一个例子中的objectchanger,你会得到下面的例子:

function objectchanger(obj)
{
	obj.add(); // runs the method of the object being passed in
}
objectchanger(o);
alert(o.value); // the value is now 7

Option 2: When you don’t know the method   第二种:当你不知道是哪个对象的方法的时候

If you don’t know the method of the object being passed in then you need to pass both the method and the object as parameters and use thecall method. call is part of the JavaScript specification and allows a function to run in the context of another object. As a result, the thiskeyword will reference the right object: the object we passed in.

如果你不知道是哪个对象的方法传入的时候,你需要把方法和对象同时作为参数传入,并使用call方法来运行。call是Javascript内置的一个方法,允许一个方法在指定的一个对象环境下运行。结果就是,"this" 就会指向正确的对象(我们传入的那个对象)。

Here’s our objectchanger function one more time:

下面就是我们用这个方法修改过的objectchanger:

function objectchanger(fnc, obj)
{
	fnc.call(obj); // runs the method of the object being passed in
}
objectchanger(o.add, o);
alert(o.value); // the value is now 7

Happy Scripting!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值