我遇到了以下问题。我的JavaScript结构如下所示。
我创建了一个包含所有控制器的对象。这些控制者有自己的责任。以下代码属于main.js
首先调用的文件:
main.js
var App = {};
App.init = function() {
console.log('init');
App.uiController.init();
App.heroController.init();
}
在函数中,init()
我调用控制器的初始化程序。
控制器对象如下所示:
uiController.js
App.uiController = {
root: 0,
init: function() {
// Development
console.log('init uiController');
root = this;
// Call functions
root.doSomething();
},
doSomething: function() {
}
}
加载所有脚本后,我调用最后一个脚本init.js
:
init.js
App.init();
我的HTML标记如下所示:
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
</head>
<body>
<!-- // Start HTML \\ -->
<header id="header">
</header><!-- End header#header -->
<main class="main">
</main><!-- End main.main -->
<footer id="footer">
</footer><!-- End footer#footer -->
<!-- JavaScript -->
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script src="scripts/main.js" type="text/javascript"></script>
<script src="scripts/constructors/uiController.js" type="text/javascript"></script>
<script src="scripts/constructors/heroController.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
<script src="scripts/init.js" type="text/javascript"></script>
</body>
</html>
在我root
用来选择的功能中this
-我当前所在的文件。通常,我会root
在每个函数(作用域)中创建变量,并为其提供值this
。但是我认为这样做会更好,在每个控制器对象中(全局)创建一个空的根,所以我只需要创建一个值并将其添加一次root
,如下所示:
App.uiController = {
root: 0,
init: function() {
root = this;
// Call functions
root.doSomething();
},
doSomething: function() {
}
}
当我root
在init()
函数中使用console.log时,在上面的示例中,它将返回一个对象,该对象具有生活在我现在所在的当前控制器中的所有功能App.uiController
。因此,我认为这很好用,并且我root
只需要为每个控制器创建和声明一次。所以,我也做了同样的heroController
像我一样的uiController
和可变的登录root
到控制台。我收到具有正确功能的不同对象:
但是,问题来了。在main.js
我调用heroController.init()
之后uiController.init()
,当控制器中的事件触发uiController时,我在控制台中收到错误,提示其中的某些功能uiController
无法正常工作。
当我删除root
每个控制器内部的全局变量并在init控制器中声明它时,var root = this;
代码将再次起作用。
为什么上面的设置不能按我预期的那样工作?
根据金舒克·巴萨克(Kingshuk basak)的回答,我尝试了一些新方法。这是我的想法:
答案代码对我不起作用。它会给我的错误:Uncaught ReferenceError: root is not defined
。当我使用我的问题的代码和改变root: 0
的heroController
,以1
两者登录到控制台:console.log(App.uiController.root, App.heroController.root);
我得到0
和1
在控制台中。我将其放置在两个代码中的位置无关紧要,其他值不会覆盖这些值。这对我来说真的很奇怪。
然后我尝试也注释掉heroController
中main.js
,然后CONSOLE.LOGroot
中uiController.init() function
。我得到的值是0
正确的,但是在此之后,我root = this;
直接在它之后设置和console.log,root.root
该值也将作为对象,0
而不是this
作为uiController
对象。这使它更加混乱,为什么root
不更改为对象而不是0
。同样,当root
孔代码中只有一个时heroController.init()
,在文件中注释掉之后main.js
。仅Console.logroot
会给我uiController
预期的对象。
最后,我也在这两个init()
函数中尝试过:
root = this;
this.root = root;
console.log('heroController', root);
当我这样做时,root
每个控制器的值是正确的,因为它将包含对象-该对象-以及所有对应的功能。但这将使我面临与前面提到的问题相同的问题,即uiController无法按预期工作。
设置root
为控制器的属性以免于不必键入var root = this
控制器方法,这是没有用的。您应该只var root = this
在需要时执行此操作,因为该属性最终并不是的净收益var root = this
。
您得到的第一个答案是部分答案。金舒克·巴萨克(Kingshuk basak)正确的是,您正在做的是root
在全局空间中设置变量。看,如果您这样做:
function foo() {
something = 1;
}
您正在something
全球范围内进行设置。要使其对您的功能本地化,您需要var
:
function foo() {
var something = 1;
}
即使该函数是原型的一部分,var
第一个代码段中的缺少也不会使JavaScript将其解释为this.something
。
Kingshuk basak建议您通过使用使其成为控制器的一部分this
。可以,是的,但是您必须使用来访问它,this
因为这就是JavaScript的工作方式。因此,使用它的天真的方法是:
uiController = {
root: 0,
init: function() {
this.root = this;
this.root.doSomething(); // You havve to use `this` here too!!
},
doSomething: function() {
this.root.somethingElse();
}
}
根据您的问题所言,您只是想使自己免于编写的麻烦var root = this
。所以root
永远不会改变。但是,请仔细考虑一下。
你在做什么是添加一个命名的属性root
来this
,具有完全相同的值this
。为了root
具有同等价值的访问,this
您已经需要拥有this
。因此,没有充分的理由this.root
存在。如上所述,如果您这样做了this.root = this
,那么对它的每次访问都必须是this.root
这样,这样您才不会明显减轻您的负担。不仅如此,而且this.root.foo()
在执行时还需要其他间接方式:root
必须首先获取this
。
您可以这样做:
uiController = {
root: 0,
init: function() {
var root = this.root = this;
root.doSomething();
},
doSomething: function() {
var root = this.root;
root.somethingElse();
}
}
但这又不能减轻负担。
您只需要var root = this
在需要时执行。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句