“特权”方法调用成员方法问题
考虑以下代码:
function Dog()
{
this.foo = function() {};
this.walk = function()
{
if(canWalk())
{
alert('walking');
return;
}
alert('I have no legs!');
}
canWalk = function()
{
this.foo();
return false;
}
}
var instance = new Dog();
instance.walk();
该代码中的“特权”canWalk()
方法存在一个错误,假设 this
指针指向 Dog
的实例代码>.它实际上似乎指向全局对象,这让我感到困惑!我读过,由于闭包,我可以在构造函数的范围内获取对 this 的引用,然后在我的“特权”方法中使用该引用,但这似乎是一种黑客行为。
我只是勉强掌握 this 指针在各种上下文中的行为。据我所知,“附加”到对象的方法将接收指向附加对象的 this
。例如,foo.doStuff()
将有一个 this
指向 foo
实例。
令人不安的是,虽然我认为我很聪明并在我的对象上创建了“特权”方法,但看来我实际上正在将函数转储到全局范围内!也许有一个名为 init()
的全局方法(很有可能)来自另一个库或文件,而不是我自己创建的。如果我随后使用名为 init()
的“特权”方法定义了一个漂亮的小封装对象,我将替换另一个全局 init()
方法。
我的问题是,创建范围仅限于它们所属对象的“特权”方法(以及与此相关的字段)的最佳实践是什么?我的示例对象的其他方法可以提供私有或特权方法,同时也具有适当的范围。我不是在寻找满足要求的晦涩解决方案,而是寻找最佳实践。
Consider the following code:
function Dog()
{
this.foo = function() {};
this.walk = function()
{
if(canWalk())
{
alert('walking');
return;
}
alert('I have no legs!');
}
canWalk = function()
{
this.foo();
return false;
}
}
var instance = new Dog();
instance.walk();
There is a bug in that code with the "privileged" canWalk()
method assuming the this
pointer points to the instance of Dog
. It actually appears to be pointing to the global object which is confusing me! I've read that due to closures I can grab a reference to this
in the scope of the constructor then use that reference in my "privileged" method but that seems like a hack.
I just barely grasp the behavior of the this
pointer in various contexts. I understand that a method that is "attached" to an object will receive a this
pointing to the attached object. For example, foo.doStuff()
would have a this
pointing to the foo
instance.
What's troubling is that while I think I'm being clever and creating "privileged" methods on my OBJECT, it appears that I'm ACTUALLY dumping functions into global scope! Perhaps there was a global method called init()
(quite possible) from another library or file not my own creation. If I then defined a nice little encapsulated object with a "privileged" method called init()
I would be replacing the other global init()
method.
My question is, what is the best practice for creating "privileged" methods (and fields for that matter) that are scoped to the object they are intended to belong to? What other approach to my sample object would provide private or privileged methods while also being properly scoped. I'm not looking for obscure solutions that meet the requirements but rather what the best practice is.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不要使用
这个
。将var self = this;
放在 Dog 函数的顶部并使用self
。这样您将始终拥有对狗的“安全”引用。在你的例子中,
this
应该指向Dog
,除非我也遗漏了一些东西。至于您的特权方法,您忘记定义变量。添加
var canWalk;
还有另一种方式:闭包。我举个例子:
现在你不需要
this
或new
。另外,您可以这样做:这样您就可以在权限函数中引用
dog
。 如果您不打算使用原型设计,我建议您使用封闭方法。顺便说一下。为避免混淆:
和
是等效的。如果两个函数之间有循环引用并且想要强制使用前定义,则后者可能很有用。
Don't use
this
. Putvar self = this;
at the top of your Dog function and useself
. That way you will always have a 'safe' reference to the Dog.In your example
this
should point to theDog
though unless I'm missing something as well.As for your privileged method, you forgot to define the variable. Add
var canWalk;
There is another way: closures. I will give an example:
Now you don't need
this
ornew
. Additionally you could do this:So you can have references to the
dog
in your priveledges functions. I would advise the closure approach if you're not going to be using prototyping.By the way. To avoid confusion:
and
Are equivalent. The latter can be useful if you have a circular reference between two functions and you want to enforce define-before-use.
首先,您需要在
canWalk
前面添加一个var
。这样,canWalk
函数就被限制在dog()
的范围内,而不是成为隐式全局函数。this
指向函数的“所有者”。当使用 new 运算符时,该函数会创建自己的作用域。因此,在dog()
体内,this
指的是狗实例对象。在您的walk
函数中,this
也指的是狗实例,因为您将walk
函数设置为dog 的实例
(this.walk = function () { ... }
)。然而,在canWalk
中,没有所有者,因此this
指向全局对象window
。我意识到我的解释可能会令人困惑,所以这是我的解释的代码注释版本:
希望能够澄清问题。
First, you need a
var
in front of yourcanWalk
. That way, thecanWalk
function is confined to the scope ofdog()
, rather than being an implicit global.this
points to the "owner" of the function. When using thenew
operator, the function creates its own scope. So, within the body ofdog()
,this
refers to the dog instance object. Inside yourwalk
function,this
also refers to the dog instance, because you're setting thewalk
function to an instance ofdog
(this.walk = function () { ... }
). However, incanWalk
, there is no owner, sothis
points to the global object,window
.I realize that my explanation might be confusing, so here's the code annotation version of my explanation:
Hope that clears things up.
正如您所了解的,像这样直接调用 canWalk 意味着“this”关键字被设置为该函数调用的全局对象。
如果您想在当前狗的上下文中运行调用,您可以显式执行以下操作:
canWalk.call(this)
As you've gathered, calling canWalk straight up like that means that the 'this' keyword is set to the global object for that function call.
If you want to run the call under the context of the current dog you can explicitly do so like this:
canWalk.call(this)