Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/467.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript &引用;“特权”;方法调用成员方法问题_Javascript_Javascript Framework - Fatal编程技术网

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()
方法


我的问题是,创建“特权”方法(以及相关字段)的最佳实践是什么,这些方法的作用域是它们要属于的对象?对于我的示例对象,还有什么其他方法可以提供私有或特权方法,同时也可以适当地确定作用域。我不是在寻找满足需求的模糊解决方案,而是寻找最佳实践。

不要使用
。Put
var 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() {}


它们是等价的。如果两个函数之间有循环引用,并且希望在使用前强制定义,则后者可能很有用。

不要使用
。Put
var 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”关键字被设置为该函数调用的全局对象

如果你