ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

javascript – ‘var webApp = {..}’和’var webApp = function(){..}’之间的区别是什么?

2019-06-22 09:19:21  阅读:172  来源: 互联网

标签:javascript javascript-objects modularity


我最近一直在尝试使用模块化JS,我仍然想知道我是否正在以“正确的方式”编写它.

例如,如果我有一个页面,其中有输入和提交按钮,应该在提交后显示数据(例如表格和图形),所以我在IFFE下编写代码,所以没有任何东西可以访问它,但是使用这样的对象变量:

var webApp = { ... } 

在其中我从DOM缓存元素,添加绑定事件和其他有用的功能.

这是我用于表单的真实代码,在加载数据时应该显示图形,表格和进度条,并且所有代码都在一个对象qwData中进行管理:

(function() {

    const qwData = {

        // Initialize functions
        init: function() {
            this.cacheDom();
            this.bindEvents();
        },
        // Cache vars 
        cacheDom: function() {
            this.dataDisplayed      = false;
            this.countUsers         = <?php echo $_SESSION['all_users_count_real']; ?>;
            this.customerMachines   = <?php echo $_SESSION['customer_statistics']['total_machines']; ?>;
            this.$form              = $('#frm');
            this.$alistToolbar      = this.$form.find('.alist-toolbar');
            this.start_date         = this.$form[0][9].value;
            this.end_date           = this.$form[0][10].value;
            this.dateCount          = this.countDays(this.start_date, this.end_date);
            this.show               = document.querySelector('#btn-show');
            this.downloadBtn        = document.querySelector('#download_summary_button');
            this.$dataContainer     = $('#qw-data-container');
            this.$qwTable           = $('#qwtable');
            this.$qwTbody           = this.$qwTable.find('tbody');
            this.$qwTd              = this.$qwTbody.find('td');
            this.qwChart            = echarts.init(document.getElementById('main-chart'));
            this.progressBar        = document.querySelector('.progress-bar');
            Object.defineProperty(this, "progress", {
                get: () => {
                   return this.progressPrecent || 0;
                },
                set: (value) => {

                    if( value != this.progressPrecent ) {
                      this.progressPrecent = value;
                      // this.setQwChartProgress(value);
                      this.setProgressBarValue(value);
                      this.setProgressButton(value);
                    }
                }, 
                  configurable: true
            });
            this.qwChartProgress    = this.progress;
        },
        // Bind click events (or any events..)
        bindEvents: function() {

            var that = this;

            // On click "Show" BTN
            this.show.onclick = this.sendData.bind(this);

            // On Change inputs
            this.$form.change(function(){
                that.updateDatesInputs(this);
            });

            // downloadQw
            this.downloadBtn.onclick = this.downloadQw.bind(this);
        },
        downloadQw: function(e){
            e.preventDefault();

            var customer = "<?php echo $_SESSION['company_name']; ?>";
            var filename = customer + "qws_"+ this.start_date + "-" + this.end_date + ".zip";

            $.ajax({
                url: "/aaa/api/download_csv.php",
                method: "GET",
                dataType : "json",
                data: { 
                    customer: customer,
                    filename: filename
                },
                success:function(result){
                if(result.status){
                    window.location.href="/aaa/api/download_csv.php?customer="+customer+"&filename="+filename+"&download=1";
                }
            },
                error:function(){
                }
            })
        },
        setQwChartProgress: function(value){
            if (value != 0) {
                // Show Chart Loading 
                this.qwChart.showLoading({
                    color: (value == 99) ? '#00b0f0' : '#fff',
                    text: value + '%' 
                });
            }
        },
        setProgressButton: function(value){

            if ( value >= 100 || value == 0 ){
                this.show.value     = 'Show';
            }
            else {
                this.show.value     = value +'%';
                // this.show.disabled   = true;
                this.disableShow();
            }
        },
        resetShowButton: function(){
            this.show.value = 'Show';
            this.disableShow();
        },
        disableShow: function(){
            // this.show.style.color = "grey";
            // this.show.disabled   = true;
            this.show.classList.add("isDisabled");
        }, 
        enableShow: function(){
            // this.show.style.color = "#66aa66";
            // this.show.disabled   = false;
            this.show.classList.remove("isDisabled");
        },
        updateDatesInputs: function(){
            this.start_date     = this.$form[0][9].value;
            this.end_date       = this.$form[0][11].value;
            this.dateCount      = this.countDays(this.start_date,this.end_date);
            // this.show.disabled   = false;
            this.enableShow();
            this.removeError();
        },
        removeError: function(){
            if (this.errors) {
                this.errors.remove();
                delete this.errors;
            }
        },
        countDays: function(date1, date2){

            // First we split the values to arrays date1[0] is the year, [1] the month and [2] the day
            var date1 = date1.split('-');
            var date2 = date2.split('-');

            // Now we convert the array to a Date object, which has several helpful methods
            date1 = new Date(date1[0], date1[1], date1[2]);
            date2 = new Date(date2[0], date2[1], date2[2]);

            // We use the getTime() method and get the unixtime (in milliseconds, but we want seconds, therefore we divide it through 1000)
            var date1_unixtime = parseInt(date1.getTime() / 1000);
            var date2_unixtime = parseInt(date2.getTime() / 1000);

            // This is the calculated difference in seconds
            var timeDifference = date2_unixtime - date1_unixtime;

            // in Hours
            var timeDifferenceInHours = timeDifference / 60 / 60;

            // and finaly, in days :)
            var timeDifferenceInDays = timeDifferenceInHours  / 24;

            if (timeDifferenceInDays > 0){
                return timeDifferenceInDays;
            } else {
                // alert('Error: The date are invalid.');
            }
        },
        // Get data, prevent submit defaults and submit. 
        sendData: function(e) {
            e.preventDefault();

            if (this.show.classList.contains('isDisabled')) {

                this.showErrorDiv("Please select a new date range before submitting.");
            } else {

                let that                = this;
                let estimatedTotalTime  = ( (this.countUsers*this.customerMachines)/777 ) * 0.098; 
                let estimatedTime       = estimatedTotalTime/99;
                let estimatedTimeMs     = estimatedTime*1000;
                let timer               = setInterval( function(){that.incrementProgress(timer);}, estimatedTime); 

                console.log('Total Time: ' + estimatedTotalTime + 's');
                console.log('Estimated Time for 1%: ' + estimatedTime + 's');

                $.ajax({
                    type: 'POST',
                    url: "/manageit/ajax.php?module=qw_module",
                    dataType: 'json',
                    data: {
                            start_ts: that.start_date,
                            stop_ts: that.end_date, 
                            submitted: true, 
                            company_name: "<?php echo $_SESSION['company_name']; ?>"
                    },
                    beforeSend: function() {

                        // Show Chart Loading 
                        that.qwChart.showLoading({ 
                            color: '#00b0f0', 
                            // text: that.qwChartProgress
                            text: ''
                        });

                        // If data div isn't displayed
                        if (!that.dataDisplayed) {
                            // Show divs loading
                            that.showMainDiv();
                        } else {
                            that.$qwTbody.slideUp('fast');
                            that.$qwTbody.html('');
                        }
                    },
                    complete: function(){},
                    success: function(result){

                        // Reset show btn
                        that.resetShowButton();

                        // Clear timer
                        clearInterval(timer);

                        // Set progressbar to 100%
                        that.setProgressBarTo100();

                        // Show Download Button
                        that.downloadBtn.style.display = 'inline-block';

                        // Insert Chart Data
                        that.insertChartData(result);

                        // Insert Table Data
                        that.insertTableData(result);
                    }
                });

                that.dataDisplayed = true;
            }
        },
        showErrorDiv: function(errorTxt){

            if (!this.errors){
                this.errors             = document.createElement("div");
                this.errors.className   = "qw_errors_div";
                this.errors.textContent = errorTxt;
                this.$alistToolbar.append(this.errors);
            } 
        },
        // Insert Data to Table
        insertTableData: function(json){

            let str = '';
            let isOdd = ' rowspan="2" ';

            for ( let i=1; i<9; i++ ) {

                str += '<tr>';

                for (let j = 0; j < 8; j++) {

                    if ((i%2 === 0) && (j==0)){
                        // do nada
                    } else {
                        str += '<td '; 
                        str += ((i % 2 !== 0)&&(j==0)) ? isOdd : '';
                        str += '> '; 
                        str += json[i][j]; 
                        str += '</td>';
                    }
                }
                str += '</tr>'; 
            }

            this.$qwTbody.html(str);

            this.$qwTbody.slideDown('fast', function(){
                if ($(this).is(':visible'))
                    $(this).css('display','table-row-group');
            });

            // Apply colors on table.
            this.tableHover();
        },
        tableHover: function(){

            this.$qwTd              = this.$qwTbody.find('td');
            var that =  this;

            this.$qwTd.eq(0).hover( function(){
                that.$qwTd.eq(0).css('background-color', '#f5f5f5');
                that.$qwTd.eq(0).parent().css('background-color', '#f5f5f5');
                that.$qwTd.eq(0).parent().next().css('background-color', '#f5f5f5');    
            }, function(){
                that.$qwTd.eq(0).css('background-color', '');
                that.$qwTd.eq(0).parent().css('background-color', '');
                that.$qwTd.eq(0).parent().next().css('background-color', '');   
            });

            this.$qwTd.eq(15).hover( function(){
                that.$qwTd.eq(15).css('background-color', '#f5f5f5');
                that.$qwTd.eq(15).parent().css('background-color', '#f5f5f5');
                that.$qwTd.eq(15).parent().next().css('background-color', '#f5f5f5');   
            }, function(){
                that.$qwTd.eq(15).css('background-color', '');
                that.$qwTd.eq(15).parent().css('background-color', '');
                that.$qwTd.eq(15).parent().next().css('background-color', '');  
            });

            this.$qwTd.eq(30).hover( function(){
                that.$qwTd.eq(30).css('background-color', '#f5f5f5');
                that.$qwTd.eq(30).parent().css('background-color', '#f5f5f5');
                that.$qwTd.eq(30).parent().next().css('background-color', '#f5f5f5');   
            }, function(){
                that.$qwTd.eq(30).css('background-color', '');
                that.$qwTd.eq(30).parent().css('background-color', '');
                that.$qwTd.eq(30).parent().next().css('background-color', '');  
            });

            this.$qwTd.eq(45).hover( function(){
                that.$qwTd.eq(45).css('background-color', '#f5f5f5');
                that.$qwTd.eq(45).parent().css('background-color', '#f5f5f5');
                that.$qwTd.eq(45).parent().next().css('background-color', '#f5f5f5');   
            }, function(){
                that.$qwTd.eq(45).css('background-color', '');
                that.$qwTd.eq(45).parent().css('background-color', '');
                that.$qwTd.eq(45).parent().next().css('background-color', '');  
            });
        },
        incrementProgress: function(timer){

            if (this.progress == 99)
                clearInterval(timer);
            else 
                this.progress++;
        },
        // Insert Data to Chart
        insertChartData: function(json){

            var posList = [
                'left', 'right', 'top', 'bottom',
                'inside',
                'insideTop', 'insideLeft', 'insideRight', 'insideBottom',
                'insideTopLeft', 'insideTopRight', 'insideBottomLeft', 'insideBottomRight'
            ];

            this.qwChart.configParameters = {
                rotate: {
                    min: -90,
                    max: 90
                },
                align: {
                    options: {
                        left: 'left',
                        center: 'center',
                        right: 'right'
                    }
                },
                verticalAlign: {
                    options: {
                        top: 'top',
                        middle: 'middle',
                        bottom: 'bottom'
                    }
                },
                position: {
                    options: echarts.util.reduce(posList, function (map, pos) {
                        map[pos] = pos;
                        return map;
                    }, {})
                },
                distance: {
                    min: 0,
                    max: 100
                }
            };

            this.qwChart.config = {
                rotate: 90,
                align: 'left',
                verticalAlign: 'middle',
                position: 'insideBottom',
                distance: 15,
                onChange: function () {
                    var labelOption = {
                        normal: {
                            rotate: this.qwChart.config.rotate,
                            align: this.qwChart.config.align,
                            verticalAlign: this.qwChart.config.verticalAlign,
                            position: this.qwChart.config.position,
                            distance: this.qwChart.config.distance
                        }
                    };
                    this.qwChart.setOption({
                        series: [{
                            label: labelOption
                        }, {
                            label: labelOption
                        }, {
                            label: labelOption
                        }]
                    });
                }
            };

            var labelOption = {
                normal: {
                    show: true,
                    position: this.qwChart.config.position,
                    distance: this.qwChart.config.distance,
                    align: this.qwChart.config.align,
                    verticalAlign: this.qwChart.config.verticalAlign,
                    rotate: this.qwChart.config.rotate,
                    // formatter: '{c}  {name|{a}}',
                    formatter: '{name|{a}}',
                    fontSize: 16,
                    rich: {
                        name: {
                            // textBorderColor: '#fff', 
                            // color: '#333',
                            // color: '#717171',
                            color: '#525252',
                            shadowColor: 'transparent', 
                            shadowBlur: 0, 
                            textBorderColor: 'transparent',
                            textBorderWidth: 0, 
                            textShadowColor: 'transparent', 
                            textShadowBlur: 0
                        }
                    }
                }
            };

            option = {
                color: ['#007bff', '#00b0f0', 'red', '#e5323e'],
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'shadow'
                    }
                },
                legend: {
                    data: ['Inactives / Viewers', 'Inactives / Viewers / Less than 1min per day', 'Light no Macro'] 
                },
                toolbox: {
                    show: true,
                    orient: 'vertical',
                    left: 'right',
                    top: 'center',
                    feature: {
                        mark: {show: true},
                        // dataView: {show: true, readOnly: false},
                        // magicType: {show: true, type: ['line', 'bar', 'stack', 'tiled']},
                        restore: {show: true},
                        saveAsImage: {show: true}
                    }
                },
                calculable: true,
                xAxis: [
                    {
                        type: 'category',
                        axisTick: {show: false},
                        data: ['Excel', 'Word', 'PowerPoint', 'All 3 Apps']
                    }
                ],
                yAxis: [
                    {
                        type: 'value', 
                        name: 'Score'
                    }
                ],
                series: [
                    {
                        name: 'Light no Macro',
                        type: 'bar',
                        label: labelOption,
                        color: 'red',
                        data: [ [3, json[7][7]] ]
                    },
                    {
                        name: 'Inactives / Viewers',
                        type: 'bar',
                        barGap: 0,
                        label: labelOption,
                        data: [ json[1][7], json[3][7], json[5][7], json[8][7] ]
                    },
                    {
                        name: 'Inactives / Viewers / Less than 1min per day',
                        type: 'bar',
                        label: labelOption,
                        data: [ json[2][7], json[4][7], json[6][7] ]
                    }
                ]
            };

            // Set charts options
            this.qwChart.setOption(option);
            // Hide Loading
            this.qwChart.hideLoading();
        },
        // Show Main div on submition (only)
        showMainDiv: function(){
            // Show all contatner div
            this.$dataContainer.slideDown('slow');
        },
        // Sets a new value for the progress bar
        setProgressBarValue: function(value){

            this.progressBar.style.width = this.returnNumWithPrecent(value);
        },
        returnNumWithPrecent: function(num){

            return num.toString() + '%';
        },
        setProgressBarTo100: function(){
            var that = this;
            // Show Download Button
            this.progress = 100;
            setTimeout(function () {
                // Show Download Button
                that.progress = 0;
            }, 1000);
        }
    }
    // run object
    qwData.init();
})();

但我看到other examples在函数下编写功能而不是对象:

webApp = function (){ ... };

像例子:

var Background = (function() {
  'use strict';
  // placeholder for cached DOM elements
  var DOM = {};
  /* =================== private methods ================= */
  // cache DOM elements
  function cacheDom() {
    DOM.$background = $('#background');
  }

  // coordinate async assembly of image element and rendering
  function loadImage() {
    var baseUrl = 'https://source.unsplash.com/category',
        cat     = 'nature',
        size    = '1920x1080';
    buildElement(`${baseUrl}/${cat}/${size}`)
      .then(render);
  }

  // assemble the image element
  function buildElement(source) {
    var deferred = $.Deferred(function (task) {
      var image = new Image();
      image.onload = function () {
        task.resolve(image);
      };
      image.onerror = function () {
        task.reject();
      };
      image.src = source;
    });
    return deferred.promise();
  }

  // render DOM
  function render(image) { 
    DOM.$background
      .append(image)
      .css('opacity', 1);
  }

  /* =================== public methods ================== */
  // main init method
  function init() {
    cacheDom();
    loadImage();
  }

  /* =============== export public methods =============== */
  return {
    init: init
  };
}());

我有两个问题:

>使用一个对象和它内部设置函数,变量,等等有什么区别:

var webApp = {…};

和一个具有相同特征的函数变量(只有一个
    语法写得不同).就像我粘贴的链接中的示例一样.

var webApp = function (){ ... };

>在一个对象/函数中编写所有代码(如图,表,进度条等有些分离元素)的代码是否正确?这应该更好地分离到不同的对象?如果有更好的方法来编写此类代码,请提及我应该研究的内容.

解决方法:

互联网教程的一个问题是它们徘徊在相关点之外,很少有作者让它们保持最新. JS领域的事情发展得非常快,5年前的行业标准(例如jQuery)现在看起来很奇怪,当你仍然偶然发现它时.

所以,要实践我为了省略而唠叨别人的好习惯:

JavaScript模块状态,2018年中期,快速变化,#deprecated

一团糟.

首先你有ES 6模块. ES 6更名为ES 2015,模块部分被取出并制作成一个单独的规范,这意味着浏览器可能符合ES 2015标准,但仍然没有本机模块.然而,3年后,每个具有相关全球市场份额的浏览器(chrome,android chrome,firefox,iOS Safari)至少实现了原生模块系统的基本版本(Edge,Opera等).我不清楚,因为我相信规范允许路径更宽容(我们将在一分钟内回到那里),但这里是语法,相对或绝对文件路径,需要扩展:

import Foo from './foo.js'; // Import default export from foo.js, alias to 'Foo'
import { Foo } from './foo.js'; // Import named export 'Foo' from foo.js

export default function () {}; // exports a function as default, importer aliases
const Foo = class Foo {};
export Foo; // exports named class Foo

它们比其他任何东西都有很多优点(首先,你不需要特殊的工具或构建过程),但由于它们是最新的,它们还没有在JavaScript生态系统中得到广泛使用.因为他们很快就会来,人们有工作要做,他们实施了各种其他模块模式/工具/系统.最早的一个是你的问题中的一个,但是这个模式虽然总比没有好,但却有足够的问题让人们开始环顾四周.

AMD模块

另一个早期的产品是require.js的异步模块定义.虽然它具有一些引人注目的技术优势,但它实际上已经死了.

Common.js模块

node.js使用它自己的基于common.js模块的模块系统(基本上已成为common.js的事实风格)爆炸到了场景.人们开始说“嘿,能够在浏览器中做到这一点也很棒”,因此,浏览器化. Browserify是一个工具,它将遍历您的依赖图并将需求表达式转换为浏览器可以处理的内容(基本上,通过创建require函数). Node的模块有点不适合浏览器,但是在一个标准上的融合优于八千万个竞争性的adhoc实现.人们看着这三个竞争模块模式/系统(你的问题中的一个,AMD,common.js),并说我们可以统一这些.从而

通用模块定义

如果你看到野外的代码看起来像这样:

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // Node, CommonJS-like
        module.exports = factory(require('jquery'));
    } else {
        // Browser globals (root is window)
        root.returnExports = factory(root.jQuery);
    }
}(this, function ($) {

那你看过UMD了.请注意它如何检查它所处的环境是为AMD还是common.js设置的.变形金刚被编写为将这两种样式转换为遗留代码和易读性问题(这是一个相当的样板).

但是人们想要更多:他们希望能够在代码中表达他们所有的webapp依赖关系(包括css和图像),并使用一个工具进行分片并有选择地加载它.此时,本机模块规范还在草案中,人们希望使用该语法.因此

Webpack模块

Webpack目前是当前使用的事实系统(虽然很多人仍然使用browserify). Webpack的模块语法如下所示:

import Foo from 'foo'; // imports default export from foo.js somewhere on PATH

这看起来很熟悉吗?非常相似(但与原生模块略有不同). Webpack还可以执行以下操作:

import 'Something.css'; // commonly seen in react apps
import 'logo.svg'; // ditto

这很方便,随着人们转向组件化系统,能够在该组件的入口点文件中表达所有组件依赖关系是很好的.不幸的是,HTML导入本来可以让你在没有构建步骤的情况下进行本地操作,这可能会导致死亡.

与本机模块系统的不兼容性,细微(路径和文件扩展名)和粗略(导入非js资产)是不幸的,这意味着一个或另一个将不得不改变,因为我试图编写本机模块 – 最近基于应用程序,并且很难使用库(几乎没有一个提供本机模块的味道).

使用什么是一种自以为是的问题,但如果您使用框架,请使用该框架的其他用户常用的任何内容. Common.js和webpack很常见,有很多工具可以消耗它们,这可能是你最好的选择.另一件要注意的是动态导入,已经在多个浏览器中登陆.

对不起,这一切都让人感到困惑,你恰好在过渡期间输入了JavaScript.

标签:javascript,javascript-objects,modularity
来源: https://codeday.me/bug/20190622/1262305.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有