Javascript &引用;“特权”;方法调用成员方法问题
考虑以下代码:Javascript &引用;“特权”;方法调用成员方法问题,javascript,javascript-framework,Javascript,Javascript Framework,考虑以下代码: function Dog() { this.foo = function() {}; this.walk = function() { if(canWalk()) { alert('walking'); return; } alert('I have no legs!'); } canWalk = function()
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();
假设这个指针指向狗的实例,那么使用“privileged”canWalk()
方法的代码中有一个bug。它实际上似乎指向全局对象,这让我很困惑!我已经读到,由于闭包,我可以在构造函数的作用域中获取一个对this
的引用,然后在我的“特权”方法中使用该引用,但这看起来像是一个黑客行为
我只是勉强掌握了这个指针在各种上下文中的行为。我知道“附加”到对象的方法将收到指向附加对象的this
。例如,foo.doStuff()
将有一个this
指向foo
实例
令人不安的是,虽然我认为我很聪明,在我的对象上创建了“特权”方法,但似乎我实际上是在将函数转储到全局范围内!可能有一个名为init()
(很可能)的全局方法来自另一个库或文件,而不是我自己创建的。如果我用一个名为init()
的“特权”方法定义了一个很好的小型封装对象,我将替换另一个全局init()
方法
我的问题是,创建“特权”方法(以及相关字段)的最佳实践是什么,这些方法的作用域是它们要属于的对象?对于我的示例对象,还有什么其他方法可以提供私有或特权方法,同时也可以适当地确定作用域。我不是在寻找满足需求的模糊解决方案,而是寻找最佳实践。不要使用此
。Putvar self=this代码>在您的狗功能的顶部,并使用self
。这样,你将永远有一个'安全'的参考狗
在您的示例中,这个
应该指向狗
,除非我也遗漏了什么
至于您的特权方法,您忘记了定义变量。添加var-canWalk代码>
还有另一种方法:闭包。我会举一个例子:
function create_dog() {
function canWalk() {
return false;
}
function walk() {
if (canWalk()) {
alert("walking");
return;
}
alert("I have no hands!");
}
return {
"walk": walk // points to the function walk()
}; // this the API of dog, like public functions (or properties)
}
var dog = create_dog();
dog.walk();
现在您不需要这个
或新的
。此外,您还可以这样做:
function create_dog() {
function canWalk() {
return false;
}
function walk() {
if (canWalk()) {
alert("walking");
return;
}
alert("I have no hands!");
}
var dog = {
"walk": walk
};
return dog;
}
var dog = create_dog();
dog.walk();
因此,您可以在privileges函数中引用狗
如果您不打算使用原型,我会建议使用闭包方法。
顺便说一下。为避免混淆:
function my_func() {}
及
它们是等价的。如果两个函数之间有循环引用,并且希望在使用前强制定义,则后者可能很有用。不要使用此
。Putvar self=this代码>在您的狗功能的顶部,并使用self
。这样,你将永远有一个'安全'的参考狗
在您的示例中,这个
应该指向狗
,除非我也遗漏了什么
至于您的特权方法,您忘记了定义变量。添加var-canWalk代码>
还有另一种方法:闭包。我会举一个例子:
function create_dog() {
function canWalk() {
return false;
}
function walk() {
if (canWalk()) {
alert("walking");
return;
}
alert("I have no hands!");
}
return {
"walk": walk // points to the function walk()
}; // this the API of dog, like public functions (or properties)
}
var dog = create_dog();
dog.walk();
现在您不需要这个
或新的
。此外,您还可以这样做:
function create_dog() {
function canWalk() {
return false;
}
function walk() {
if (canWalk()) {
alert("walking");
return;
}
alert("I have no hands!");
}
var dog = {
"walk": walk
};
return dog;
}
var dog = create_dog();
dog.walk();
因此,您可以在privileges函数中引用狗
如果您不打算使用原型,我会建议使用闭包方法。
顺便说一下。为避免混淆:
function my_func() {}
及
它们是等价的。如果两个函数之间有一个循环引用,并且希望在使用前强制定义,则后者可能很有用。首先,在canWalk
前面需要一个var
。这样,canWalk
函数就被限制在dog()
的范围内,而不是一个隐式全局函数
此
指向函数的“所有者”。使用new
运算符时,函数将创建自己的作用域。因此,在dog()
的主体中,这个
引用了dog实例对象。在您的walk
函数中,this
还引用了dog实例,因为您正在将walk
函数设置为dog
(this.walk=function(){…}
)的实例。但是,在canWalk
中,没有所有者,因此此
指向全局对象窗口
我意识到我的解释可能令人困惑,因此下面是我解释的代码注释版本:
var obj = {
'f': function () {
// this === obj, because obj "owns" this function
// In other words, this function is callable by obj.f()
},
'o': {
'f': function () {
// this === obj.o, because obj.o "owns" this function
// In other words, this function is callable by obj.o.f()
}
}
};
// The new operator essentially sets "this" within the
// function to an empty object and returns that object
var instance = new Dog();
function Dog() {
// this === instance, because of the "new" operator
// For demonstration
var self = this;
this.walk = function () {
// this === instance === self, because self/instance "owns" this function
// In other words, this function is callable by self.walk()
};
var canWalk = function () {
// What's the owner of this object? Nothing,
// so it defaults to the global object, window
// this === window
// Instead, we can access the Dog instance by
// using the "self" variable we set earlier.
// self === instance
};
}
希望这能把事情弄清楚。首先,你需要一个var
在你的canWalk
前面。这样,canWalk
函数就被限制在dog()
的范围内,而不是一个隐式全局函数
此
指向函数的“所有者”。使用new
运算符时,函数将创建自己的作用域。因此,在dog()
的主体中,这个
引用了dog实例对象。在您的walk
函数中,this
还引用了dog实例,因为您正在将walk
函数设置为dog
(this.walk=function(){…}
)的实例。但是,在canWalk
中,没有所有者,因此此
指向全局对象窗口
我意识到我的解释可能令人困惑,因此下面是我解释的代码注释版本:
var obj = {
'f': function () {
// this === obj, because obj "owns" this function
// In other words, this function is callable by obj.f()
},
'o': {
'f': function () {
// this === obj.o, because obj.o "owns" this function
// In other words, this function is callable by obj.o.f()
}
}
};
// The new operator essentially sets "this" within the
// function to an empty object and returns that object
var instance = new Dog();
function Dog() {
// this === instance, because of the "new" operator
// For demonstration
var self = this;
this.walk = function () {
// this === instance === self, because self/instance "owns" this function
// In other words, this function is callable by self.walk()
};
var canWalk = function () {
// What's the owner of this object? Nothing,
// so it defaults to the global object, window
// this === window
// Instead, we can access the Dog instance by
// using the "self" variable we set earlier.
// self === instance
};
}
希望这能把事情弄清楚。如您所知,像这样直接调用canWalk意味着“this”关键字被设置为该函数调用的全局对象
如果您想在当前狗的上下文中运行调用,您可以明确地这样做:
canWalk.call(this)
正如您所收集的那样,直接向上调用canWalk意味着“this”关键字被设置为该函数调用的全局对象
如果你