Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/478.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_Closures_Language Design - Fatal编程技术网

Javascript 为什么不能在闭包中的私有函数内直接访问此属性?

Javascript 为什么不能在闭包中的私有函数内直接访问此属性?,javascript,closures,language-design,Javascript,Closures,Language Design,在我自己的回答中,我指出JavaScript闭包的“公共”属性不能在“私有”函数中访问 那篇文章中给出的例子是 function anobject(){ var privatefunction = function(){ //publicfunction(); //wrong; you have no access to it console.log(this); //refer to the global object, not the object c

在我自己的回答中,我指出JavaScript闭包的“公共”属性不能在“私有”函数中访问

那篇文章中给出的例子是

function anobject(){
    var privatefunction = function(){
        //publicfunction(); //wrong; you have no access to it
        console.log(this); //refer to the global object, not the object creating
    };
    this.publicfunction = function(){
        console.log(this); //refer to the object creating
    }
}
我认为原因是一些向后兼容性问题
privatefunction
必须属于全局对象。因此,公共函数只是一个分配给
this
属性的匿名函数。这就解释了为什么调用
publicfunction
会失败,因为它需要先引用

但是,以下修复仍然不起作用:

function anobject(){
    var privatefunction = function(){
        //publicfunction(); //wrong; you have no access to it
        console.log(this); //refer to the object creating
    }.bind(this);
    this.publicfunction = function(){
        console.log(this); //refer to the object creating
    }
}
正如我明确指定的那样,
privatefunction
应该与对象创建绑定,调用
publicfunction
应该可以工作,但它不能。我必须做到以下几点:

function anobject(){
    var privatefunction = function(){
        this.publicfunction();
        console.log(this); //refer to the object creating
    }.bind(this);
    this.publicfunction = function(){
        console.log(this); //refer to the object creating
    }
}
function anobject(){
    var privatefunction = function(){
        publicfunction();
        console.log(this); //refer to the object creating
    };
    var publicfunction = function(){
        console.log(this); //refer to the object creating
    }
    this.publicfunction = publicfunction;
}
另一种解决方法(我使用的方法)如下:

function anobject(){
    var privatefunction = function(){
        this.publicfunction();
        console.log(this); //refer to the object creating
    }.bind(this);
    this.publicfunction = function(){
        console.log(this); //refer to the object creating
    }
}
function anobject(){
    var privatefunction = function(){
        publicfunction();
        console.log(this); //refer to the object creating
    };
    var publicfunction = function(){
        console.log(this); //refer to the object creating
    }
    this.publicfunction = publicfunction;
}
现在是问题部分。这种行为背后的原因是什么?在没有明确规范的情况下,通过禁用访问此的属性,它试图避免什么


更新:问题的主要部分是:当解释器在作用域链中找不到名称时,为什么不查看
this
属性?

这里的问题是引用
this
是由函数/方法的调用方确定的,例如:

function anobject(){
    // here "this" is the object
    var privatefunction = function(){
        // here "this" is the object **that called privatefunction()**
    };
    this.publicfunction = function(){
        // this method will always be called by the object, so "this" is the object
    }
}
要实现您的目标,您还可以尝试以下方法:

function anobject(){
    var that = this;
    var privatefunction = function(){
        [do what you like using "that"]
    };
    this.publicfunction = function(){
        [here you can use "this" directly, or "that"]
    }
}

在第二个示例中,
publicfunction()
被定义为对象的属性

this.publicfunction = function(){
    console.log(this);
}
因此,此函数不能通过其名称直接访问
publicfunction()
,并且与上下文无关。函数实际上不属于任何上下文,而是属于它是其属性的对象

在您的示例中,当
privatefunction()
调用
publicfunction()
时,这会引发一个错误,因为没有函数声明为名为
publicfunction()
变量,而不是,因为
的属性不可访问:

function anobject(){
    var privatefunction = function(){
        //publicfunction(); // You cannot call publicfunction() because there is
                            // no function defined with this name
    }.bind(this);
    this.publicfunction = function(){
        console.log(this);
    }
}
看看这个例子,
publicfunction()
即使在
anobject()中也无法访问:

但是,如果在
anobject()
的上下文中将
publicfunction()
定义为变量,则可以通过其名称访问此函数。例如,您只需在
anobject()的闭包中声明
function publicfonment()

但在这种情况下,
publicfunction()
anobject()
的执行上下文之外是不可访问的,因此可以将其视为“私有”函数:

var a = new anobject();
if(typeof a.publicfunction === 'undefined')
    console.log('Public function is undefined outside of anobject()');
因此,这就是为什么我们使用
this
关键字来声明
publicfunction()
:它使它可以在
anobject()
的上下文之外访问,但这样做只能将此函数定义为
anobject()
属性

因此,访问此函数的唯一方法是调用
this.publicfunction()

有关
关键字的更多详细信息:


JavaScript中的变量与属性:

我认为您对JavaScript中作用域的工作方式有一些误解。你可以在这里看一看:这与作用域无关,主要的问题是为什么当JavaScript找不到名称时,它没有查看
this
对象?我几乎在我的帖子中解释了这一点。请仔细阅读。无论如何,您已经提供了另一种解决方法。您所说的
privatefunction
技术就是调用它的对象。事实并非如此。如果我定义另一个公共函数并让它调用
privatefunction
,那么如果我在测试中调用全局范围内的公共函数,
这个
仍然是全局对象。正如我在回答中所说的,当你调用
privatefunction()
时,即使在对象内部,因为你调用它的方式不是
this.privatefunction()
(这是不可能的,因为它不是该对象的方法)然后,
函数中的这个
是全局对象。如果我不够清楚,请告诉我,我会在有时间的时候更好地解释。好的。你是说在JavaScript中,没有对象前缀的名称总是指变量,而不是任何对象的属性吗?
function anobject(){
    var privatefunction = function(){
        this.publicfunction();
        console.log(this);
    }.bind(this);
    this.publicfunction = function(){
        console.log(this);
   }
}