我正在尝试学习一些关于javascript的新概念。这是我编写的一个简单代码。在函数内部,THIS关键字引用全局对象,它是窗口,除非它与另一个对象的上下文绑定。在myobj
对象内部,有两种方法与另一个名为afunc
和anotherfunc
的全局可访问函数共享同一名称。我想在myobj上下文中访问那些全局函数,当然不使用绑定的全局对象到我曾经称之为立即调用的函数。但这是一个错误。 我的问题是,如果javascript中的所有内容都是对象并且窗口对象包含它们,那么为什么我可以使用this.afucn
或window.afunc
来访问这些函数?
(function(){
var afunc=function (){
document.write('this is world'+'</br>');
}
var anotherfunc=function (){
document.write('this is another world');
}
var myobj={
afunc:function(){
document.write('afunc');
},
anotherfunc:function(){
document.write('anotherfunc');
},
context:function(){
(function(){
this.afunc();
this.anotherfunc();
})();
}
};
myobj.context();
})();
&#13;
答案 0 :(得分:2)
确实,在您的情况下,this
将引用全局对象,而this.afunc()
等将访问全局变量afunc
。
但是,除非要显示更多代码,否则您没有全局变量afunc
。您使用
(function(){
var afunc=function (){
document.write('this is world'+'</br>');
}
var anotherfunc=function (){
document.write('this is another world');
}
//...
})();
是本地到封闭函数((function(){ ... })();
部分)。
如果你想让它们全局化,你可以将它们移到函数之外:
var afunc = function() {
document.write('this is world' + '</br>');
};
var anotherfunc = function() {
document.write('this is another world');
};
(function() {
var myobj = {
afunc: function() {
document.write('afunc');
},
anotherfunc: function() {
document.write('anotherfunc');
},
context: function() {
(function() {
this.afunc();
this.anotherfunc();
})();
}
};
myobj.context();
})();
&#13;
但是,请注意,在严格模式中,this
将是undefined
,而不是指全局对象。这样做是因为通常如果有人在函数内使用this
,他们就不会期望它引用全局对象。通过查看代码,并不总是清楚你是否想要访问全局对象(通过this
)或其他一些对象(正如你所注意到的那样,你的意图有些混乱)。
这就是为什么,如果你想访问全局对象,你应该明确地这样做,并通过window
引用它。
答案 1 :(得分:1)
首先,我认为你有些事情有点困惑。
在JavaScript中,不是一切都是函数。相反,可以使用一些不同的原语(从ES5开始):
推荐阅读:Mozilla Documentation on JavaScript Data Structures
这些类型中的每一种都有与之相关的特殊方法 - 除了null
和undefined
,这些是具有非常特定用法的占位符 - 但这些对于帮助修复您对什么的理解并不重要继续用JavaScript。 将提供帮助的关键之一是,JavaScript就是所谓的功能语言。在某种程度上,这意味着函数是第一类对象。除此之外,这意味着可以使用函数作为值。
另一件事是,返回的函数不是返回的唯一的东西 - 发生的是函数编程是围绕闭包的思想构建的,或函数以及定义返回函数的范围内的所有相关变量(毕竟,我们可以在函数中引用返回新函数的变量!)
function foo() {
var bar = 3;
// Returns a function that when called, returns the Number 5.
return function () {
return 1 + 1 + bar;
}
}
就缩小你的错误而言,在myObj.context
函数中,我注意到你写了一个立即调用的表达式......
context: function () {
(function () {
this.afunc();
this.anotherfunc();
})();
},
真的有必要吗?事实上,这个功能真的有必要吗?由于我们现在知道JavaScript将对象上的函数视为值,因此您可以始终只使用myObj.afunc
或myObj.anotherfunc
来处理特定于myObj
的代码。
如果你的意图是编写一个方法来调用afunc
上的anotherfunc
和myObj
方法,那么一组更好的代码就是:
var myObj = {
afunc: function () {
// Magic!
},
anotherfunc: function () {
// More magic!
},
context: function () {
this.afunc();
this.anotherfunc();
}
};
如果您打算调用afunc
声明中立即调用的表达式中定义的anotherfunc
/ myObj
,只需从调用中移除this
即可。 context
。
如果您打算在全局范围内调用afunc
/ anotherfunc
方法,那么您将失去运气:您尚未在给定的代码段中定义此类函数。但是,这可以修复如下:
// Now, afunc exists in the global scope!
function afunc() {
// Magic
}
// Now, anotherfunc exists in the global scope!
function anotherfunc() {
// Magic
}
(function () {
var myObj = {
// Your object...
};
myObj.context();
})();
但是,一般来说,这被认为是糟糕的编程形式,因为我们用不必要的函数,变量和对象混淆了全局范围;最好将函数声明保存在立即调用的对象中,除非你需要在其他地方调用它们。如果你需要在其他地方调用这些函数,你可以考虑研究你会这样做的方法。
答案 2 :(得分:0)
它不起作用,因为this
并不是指你认为它所指的是什么,而是它正在坚持window
。从那里开始,函数在外部并不完全在全局范围内,因为它们包含在(function(){ ... })();
中。现在,对于context
函数,我们不需要function()
包装器,因为全局范围内没有任何内容:
context:function(){
(function(){ // <-- Here
this.afunc();
this.anotherfunc();
})(); // <--
}
删除它(我们无论如何也不想要它),this
将引用myobj
context:function(){
this.afunc();
this.anotherfunc();
}
如果我们想要在myobj
范围之外宣传,那么您不想使用this
。因为这意味着属于myobj
实例的函数。你只想说:
context:function(){
afunc();
anotherfunc();
}
因为myobj
不知道&#34;全球&#34;功能。
(function(){
var afunc=function (){
document.write('this is world'+'</br>');
}
var anotherfunc=function (){
document.write('this is another world');
}
var myobj={
afunc:function(){
document.write('afunc');
},
anotherfunc:function(){
document.write('anotherfunc');
},
context:function(){
afunc();
anotherfunc();
}
};
myobj.context();
})();
&#13;