Javascript 通过对象文本与模块模式、代码组织优势和;欺骗

Javascript 通过对象文本与模块模式、代码组织优势和;欺骗,javascript,Javascript,你更喜欢哪一种?它们的优缺点是什么?。 就我个人而言,我发现singleton很难阅读和维护,很多上下文更改(这),总是以通过var self=this(或者像$这样的代理)缓存正确的上下文结束(proxy)+我将始终有一个全局变量(singleton),而在第二种方法中,若模块不需要公开任何API,我可以避免创建全局变量 简单示例:(用户单击“添加到购物车”,一些ajax会被触发,并且成功创建html(通知) Html <div class="cart"> <a hr

你更喜欢哪一种?它们的优缺点是什么?。 就我个人而言,我发现singleton很难阅读和维护,很多上下文更改(这),总是以通过
var self=this
(或者像
$这样的代理)缓存正确的上下文结束(proxy
)+我将始终有一个全局变量(singleton),而在第二种方法中,若模块不需要公开任何API,我可以避免创建全局变量

简单示例:
(用户单击“添加到购物车”,一些ajax会被触发,并且成功创建html(通知)
Html

<div class="cart">
    <a href="#" data-product-id="200"> Add to cart </a>
</div>
单例-对象文字(同一示例)


虽然Singleton vs.Module Pattern是一个合理的问题,但根据您给出的示例,这个问题应该被改写为Singleton vs,因为这不是模块模式本身,而是模块模式所包含的生命,它让cruft远离您的
购物车
Singleton。即使这样,这也不是一个vs类的问题——生活和单身都可以一起使用。生命的目的只是为了把东西排除在全球范围之外

所以…,您可以将您的单例代码打包到IIFE中,如下所示

;(function(){
  var Cart = {
    settings: {
      // Your code ...
  };

  Cart.init();
})();
在本例中,您以单例编写代码,但将其包装在IIFE中,并且不使用全局作用域。iLife完全独立于您选择如何编写和组织代码。对于单例与模块模式问题,您需要一个不同的示例。

iLife(立即调用的函数表达式):

(function() {
    console.log('run this in your browser console')
})()
var module = (function () {
    var privateScopeVar = 1 // scope of the IIF  

    // the 'this' context in this scope is the global object (e.g. window)

    // returns literal object who's method's scopes are lexically bound 
    // to the IIF scope
    return {
      publicMethod: () => privateScopeVar // publicMethod scope can access IIF scope 
    }
})()
var singleInstance = { firstName: 'Greg' }
var singleInstance = singleInstance || { firstName: 'Greg' }
const singleInstance = { 
    firstName: 'Greg', 
    called: false, 
    init: () => { 
        if (!this.called) {
            console.log('only once')
            this.called = true
        }
    } 
}

// of course singleInstance.called = false; singleInstance.init() is always possible
模块模式:

(function() {
    console.log('run this in your browser console')
})()
var module = (function () {
    var privateScopeVar = 1 // scope of the IIF  

    // the 'this' context in this scope is the global object (e.g. window)

    // returns literal object who's method's scopes are lexically bound 
    // to the IIF scope
    return {
      publicMethod: () => privateScopeVar // publicMethod scope can access IIF scope 
    }
})()
var singleInstance = { firstName: 'Greg' }
var singleInstance = singleInstance || { firstName: 'Greg' }
const singleInstance = { 
    firstName: 'Greg', 
    called: false, 
    init: () => { 
        if (!this.called) {
            console.log('only once')
            this.called = true
        }
    } 
}

// of course singleInstance.called = false; singleInstance.init() is always possible
单例文字+如果在EcmaScrip5中包含/导入多次则无法覆盖的单例文字:

(function() {
    console.log('run this in your browser console')
})()
var module = (function () {
    var privateScopeVar = 1 // scope of the IIF  

    // the 'this' context in this scope is the global object (e.g. window)

    // returns literal object who's method's scopes are lexically bound 
    // to the IIF scope
    return {
      publicMethod: () => privateScopeVar // publicMethod scope can access IIF scope 
    }
})()
var singleInstance = { firstName: 'Greg' }
var singleInstance = singleInstance || { firstName: 'Greg' }
const singleInstance = { 
    firstName: 'Greg', 
    called: false, 
    init: () => { 
        if (!this.called) {
            console.log('only once')
            this.called = true
        }
    } 
}

// of course singleInstance.called = false; singleInstance.init() is always possible
在EcmaScrip6中不能多次重写或初始化的单例文字:

(function() {
    console.log('run this in your browser console')
})()
var module = (function () {
    var privateScopeVar = 1 // scope of the IIF  

    // the 'this' context in this scope is the global object (e.g. window)

    // returns literal object who's method's scopes are lexically bound 
    // to the IIF scope
    return {
      publicMethod: () => privateScopeVar // publicMethod scope can access IIF scope 
    }
})()
var singleInstance = { firstName: 'Greg' }
var singleInstance = singleInstance || { firstName: 'Greg' }
const singleInstance = { 
    firstName: 'Greg', 
    called: false, 
    init: () => { 
        if (!this.called) {
            console.log('only once')
            this.called = true
        }
    } 
}

// of course singleInstance.called = false; singleInstance.init() is always possible
IIF内部的单例(提供私有状态)


模块模式还可以实现单例,对象文本不一定需要变量:
({…}).init()你更喜欢哪一个-没关系,你可以在需要的时候使用(甚至结合使用)。相互之间的利弊是什么你的问题中已经提到了他们。