Javascript - 这是一个好习惯吗?

时间:2015-07-01 15:17:42

标签: javascript jquery standards document-ready iife

在我们公司,我们正在开设一个新的网络项目,我是该公司的新成员,并且以前的应用程序可以像这样制作文档。 (顺便说一句,我们正在使用jQuery)

var AccountingMovements = function AccountingMovements() {

    //sometimes they use var _that = this;
    var _this = this;

    _this.Constructor = function Constructor() {
        //here goes the code when document is ready
    }
}

var $AccountingMovements = new AccountingMovements();
$(document).ready($AccountingMovements.Constructor);

当我问我的同事他们为什么使用这种模式时,他们告诉我Javascript代码必须让他们拥有自己的构造函数,并且代码应该像这样写,并且当我问它是否是公司时规则要做到这一点,他们说不是,没有公司标准说这应该是这样写的。他们似乎只是这样做,因为"它总是如何完成"而不是说这是一个常见的javascript标准练习或类似的东西。

在我身边,我学会了使用IIFE和jquery文档准备好,我在javascript专家给出的许多网页示例,使用的实际解释,甚至维基百科文章中都找到了。我这样编写代码

(function (code) {
    code(window.jQuery, window, document);
}(function ($, window, document) {
    $(function () {
        //here goes the code when document is ready
    });
}));

我的开发领导者(对于javascript并不是太了解,因为他来自桌面开发背景,但他在业务逻辑方面表现很好)告诉我,因为它'一个新的项目,每当我看到一个新的解决方案,一个更好的实现,或一些有用的东西,我必须毫不犹豫地告诉他,他将与其他领导人讨论。所以我告诉他我的方法,并且我没有理解旧构造函数代码的目的,并且没有人给我一个令人信服的解释,他告诉我自己查看是否有什么可以支持鉴于我向他展示了备用我的资源,为了告诉订单,以防我的情况更好,抛弃另一种方法。

所有这个故事,我的问题是,

javascript构造函数方法是否有名称?我的意思是,这是一个真正的标准,实践还是推荐?因为我找不到任何有关它的信息。可能是我错了,构造函数方法更好或更有效,但由于我没有相关信息,我需要确定以讨论我的实现。

提前致谢。

4 个答案:

答案 0 :(得分:2)

JavaScript语言中的单词Constructor没有特殊含义;只有你的同事赋予它的意义。像dojo这样的一些JS框架创建了类似命名的函数,但它们也有专门的,集中的方式来定义对象,以及它们称为构造函数的集中位置(而不是在下一行手动调用它,为错误留出空间)

在构建自己之前,相信任何JavaScript对象必须等到DOM准备好之后,也可能会产生误导。您如何看待JQuery创建自己? (并且必须非常早,在人们编写$().ready以使其执行onload功能之前)

我不知道你的同事写作对象的方式有任何具体问题,只要他们为他们当前的Constructor函数分配一个非常不同的语义。上面的代码如var _this = this是构造函数。 was-Constructor函数的内容最好描述为onDOM或类似。如果他们更喜欢遵循这个系统,那么他们的班级系统通过中央图书馆可能是最好的;无论是你自己还是别人。

答案 1 :(得分:0)

一个很大的区别是全球范围的污染。由于它们似乎没有将其功能包装在IIFE中,因此可以从全局范围访问所有功能和变量。如果第三方JS库(或甚至其他一些内部代码)重用其中任何一个,这可能会导致错误和安全问题。

您提到的方法是一个非常有用的模式,因为它允许对代码进行作用并指示哪个部分需要等待DOM:

// IIFE to create a closure to prevent global scope pollution
(function(code) {
  // execute `main` function with params
  code(window.jQuery, window, document);
}(function main($, window, document) {
  $(function readyDOM() {
    //here goes the code when document is ready
  });

  // This is the rest of your code that is not dependent on the DOM
  // Such as any object (constructers) declarations
}));

然而,这在功能上等同于:

// IIFE to create a closure to prevent global scope pollution
(function main($, window, document) {
  $(function readyDOM() {
    //here goes the code when document is ready
  });

  // This is the rest of your code that is not dependent on the DOM
  // Such as any object (constructers) declarations
})(window.jQuery, window, document);

这些模式中的任何一个都可以用作其对象声明的包装器。所以将它与它们的对象声明结合起来:

// IIFE to create a closure to prevent global scope pollution
(function main($, window, document) {
  $(function readyDOM() {
    $AccountingMovements.Constructor();
  });

  // A better pattern for object constructors
  // Assigning properties directly to `this` in the object constructor
  //  makes them enumerable by default. See http://jsbin.com/kuxuyataci/edit?js,console
  function AccountingMovements() {
    //sometimes they use var _that = this;
    var _this = this;
  }
  AccountingMovements.prototype.Constructor = function Constructor() {
    //here goes the code when document is ready
  };

  // var will be hoisted
  var $AccountingMovements = new AccountingMovements();
})(window.jQuery, window, document);

答案 2 :(得分:0)

他们想要实现的是“应用程序启动”或“启动按钮”,当页面准备就绪时,他们会调用Constructor,但更合适的名称是init或{{1方法。

在我看来,对于应用程序基础/结构来说,这是一种绝对蹩脚的方式。这也可以用作模块启动器等。

使用initialize作为对主构造函数/函数/对象的引用是一个很好的做法,因为很快你会进入闭包,不知何故你需要引用主模块。

_this我想这里只是一个占位符,你永远不应该像这样命名变量。 Constructor它好多了。

你在这里粘贴的,实际上不是一个模式,只是一个模块内的初始化方法。

Google AccountingMovementsConstructor,了解更多相关信息。

请注意,让某人使用Java或其他不同语言来构建大型javascript应用程序只会遇到最糟糕的情况。

作为上述代码的替代方案:

Javascript design patterns

您可以添加// Define your module (function(w) { w.namespace.myModule = { init: function() { console.log('hey, Im ready to rock'); }, // Usually you have one of these also destroy: function() { console.log('good bye world...'); } } }(window)); // Fast alternative to $(document).ready(...) $(function() { window.namespace.myModule.init(); // hey, Im ready to rock }); 来分隔公钥变量和私有变量。但是我不会在这里,你可以用谷歌做的事情:P

答案 3 :(得分:0)

你可能互相误解了。

您提供的代码段大部分是声明类的JS方式。当然,出于在ready事件上执行一堆代码的唯一目的,这是过度的。但是项目增长了,你需要构建它。这是实现这一目标的众多方法之一,其中没有一种是最好的方法。对于来自Java等纯OOP语言的程序员来说,这是一种鼓励(甚至强制执行)面向对象架构的程序。

由于 JavaScript没有内置类声明语法(< ES2015的实现至少没有),因此出现了多种方法。我所看到的只涉及构造函数的声明。你的也不例外:虽然我会说它不理想,构造函数代码在表示类的构造函数本身就好了。我不明白你为什么要将构造过程分成两个不同的步骤:一旦构造函数完成其工作,对象应该可以使用,单独的构造步骤是不必要的复杂化。

例如,这里是CoffeeScript(粗略地讲,JS上的语法层)如何做到这一点:

# CoffeeScript
class Hi
  # A typical method
  # CS is indenetation-sensitive: class contents and
  # function implementations are indented one more level
  # -> denotes a function
  method: ->
    @a += 1

  # `constructor` is a special identifier in CS
  # code from that function goes into an unusual place
  constructor: ->
    @a = 5

这是输出:

// Generated JavaScript
// Entire program is wrapped in IIFE, for isolation.
// Not relevant to the question, but since it's in the output
// I want to clarify why it's in there.
(function() {
  var Hi;

  Hi = (function() {
    Hi.prototype.method = function() {
      return this.a += 1;
    };

    function Hi() {
      this.a = 5;
    }

    return Hi;

  })();

}).call(this);