javascript - 为什么我的 javascript 代码在面试时不被接受?

标签 javascript

面试官告诉我,我必须遵循 javascript“模式”并编写“干净的代码”。他还说我应该遵循原型(prototype)模式。这是我的代码示例:

//namespace declrations
var MyNamespace = {};
MyNamespace.UCs = {};
MyNamespace.Pages = {};
//function declarations
MyNamespace.UCs.test = function () { alert('this is a test function in user control namespace.'); }
MyNamespace.Pages.test = function () { alert('this is a test function in web page namespace.'); }

那么有人能告诉我为什么这段代码不对吗?我的意思是,我首先声明了 namespace ,然后像上面的示例一样添加了我的成员和函数。那么它真的有问题还是我遗漏了什么?

最佳答案

当您在大型环境中编写代码时,可能会开始出现许多问题。因此,将类定义与使用这些类的方式分开很重要。这也意味着您必须创建可以进行单元测试的类,以证明它们按照您说的去做。 Javascript 不是真正的面向对象的语言,因此有几种方法可以“伪造”它。但是因为语言有很大的灵 active ,我们可以复制一些方法。

我们想要远离的一件事是称为函数作用域的东西,因为当 3 或 4 个其他程序员开始假设您的代码正在做什么时,它可能会在以后导致意外的“功能”。如果他们不知道一个全局变量在一两个函数闭包之前被覆盖了,那么发现这个问题就会变得更加困难。所以我建议使用由 John Resig 创建的小类(class)因为它提供了一种非常简单的方法,可为您提供大量所需的功能。

那么让我们写一些代码。

 var myNamespace = myNamespace || { }

 /**
   * Used to store a single entry in the log
   *
   * @class
   */
 var myNamespace.LogEntry = Class.extend({

     /**
       * Used to track the beginning of the page load
       *
       * @private
       * @static
       */
     PAGE_LOAD_TIME = new Date().getTime(),

     /**
       * Used to store the current time
       * 
       * @type int
       */
     time : undefined,

     /**
       * The message of this log entry
       *
       * @type string
       */
     msg : undefined,

     /**
       * @constructor
       * 
       * @param {string} msg The message of this log entry
       */
     init : function (msg) {
         this.time = new Date().getTime() - this.PAGE_LOAD_TIME;
         this.msg = msg
     },

     /**
       * Displays this log entry in a single string
       *
       * @return {string} String representation of this log entry
       */
     toString : function () {
         return this.time + ": " + this.msg;
     }
 });

 /**
   * Used to store a log entry that has data associated with it.
   *
   * @class
   * @extends myNamespace.LogEntry
   */
 var myNamespace.DataEntry = myNamespace.LogEntry.extend({

     /**
       * Used to store data associated with this log entry
       *
       * @type object
       */
     data : undefined,

     /**
       * @constructor
       *
       * @param {string} msg The message that describes this log entry
       * @param {object} data The data associated with this entry
       */
     init : function (msg, data) {
          this._super(msg);
          this.data = data;
     },

     /**
       * @return {string} The string representation of this log entry
       */
     toString : function () {
          // Uses a JSON library to stringify the data into a json string.
          return this._super() + JSON.stringify(this.data);
     }
 });

 /**
   * Provides an interface to log messages
   *
   * @class
   */
 var myNamespace.Log = Class.extend({

     /**
       * Stores log entries
       *
       * @type myNamespace.LogEntry[]
       */
     log : undefined,

     /**
       * @constructor
       */
     init : function () {
         this.log = [ ];
     },

     /**
       * Logs a message into the log
       *
       * @param {string} msg The message you want to log
       */
     msg : function (msg) {
         this.log.push(new myNamespace.LogEntry(msg));
     },

     /**
       * Log a message and data into the log
       *
       * @param {string} msg The message of this log entry
       * @param {object} data The data associated with this log entry
       */
     data : function(msg, data) {
         this.log.push(new myNamespace.DataEntry(msg, data));
     }

 });

好的,这里有很多事情要做。主要部分是这是类的所有定义。我实际上并没有在那里使用任何东西。该程序仅将当前时间存储在声明为 @static 的 LogEntry.PAGE_LOAD_START 中,因此该行为是预期的。我在这里使用了很多 jsDocs 来使一切都清楚地说明意图是什么。如果您没有按照记录它们的方式使用这些类,像 intelliJ 这样的程序可以使用它们来提供代码反馈。

此程序可让您创建和存储可能包含日志记录数据的日志条目。还有很多其他方法可以做到这一点。我在构造函数之前而不是在构造函数内部声明所有内容,以便我可以记录类型以及它们是否是私有(private)的。

必须使用日志的程序员将确切地知道如何使用它,并且如果他们想要创建或扩展这些类,他们可以这样做而不会因函数关闭而产生意外影响。

使用方法如下:

 var anotherNamespace = anotherNamespace || {};

 var anotherNamespace = new myNamespace.Log();

 ...

 anotherNamespace.log.msg("This is a test");

 ...

 anotherNamespace.log.data("Test msg with data", data);

当然,这里显然缺少一种显示所有数据的方法。但这可能在另一个类中,该类遍历 Log.log 数组并将 toString() 吐出到网页或文件中。这里的要点是类及其函数是简单的、可单元测试的并且仅是定义。

关于javascript - 为什么我的 javascript 代码在面试时不被接受?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9853027/

相关文章:

javascript - IE8(兼容模式)不会加载我的 Ajax 内容

javascript - Vue 中的无限更新循环

c# - "Access denied"尝试在客户端打开文件时

javascript - 添加和删​​除类 onClick 操作

javascript - 引用错误: addPpl is not defined

javascript - Google Maps Uncaught TypeError : b. has is not a function

javascript - Mysql AES_ENCRYPT => 客户端 JavaScript Aes.Ctr.decrypt 问题

javascript - 调整文本区域大小以适合所有内容

javascript - 如何阻止/允许访问 document.styleSheets 信息,这是什么原因

javascript - 等到对象创建 - (JavaScript/AngularJS)