Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';这种JavaScript编码风格有什么问题?(闭包与原型)_Javascript_Closures_Prototype - Fatal编程技术网

什么';这种JavaScript编码风格有什么问题?(闭包与原型)

什么';这种JavaScript编码风格有什么问题?(闭包与原型),javascript,closures,prototype,Javascript,Closures,Prototype,我们一直在讨论如何最好地处理JS应用程序中的对象,研究斯托扬·斯特凡诺夫的书,阅读无数关于“新”、“这个”、“原型”、“闭包”等的帖子(事实上,有这么多,而且他们有这么多相互竞争的理论,这表明没有完全明显的答案) 因此,让我们假设我们不关心私有数据。我们满足于相信用户和开发人员不会在我们定义的方式之外的对象中乱搞 考虑到这一点,这种技术有什么不对的地方(除了它似乎在挑战数十年的OO风格和历史之外) // namespace to isolate all PERSON's logic var PE

我们一直在讨论如何最好地处理JS应用程序中的对象,研究斯托扬·斯特凡诺夫的书,阅读无数关于“新”、“这个”、“原型”、“闭包”等的帖子(事实上,有这么多,而且他们有这么多相互竞争的理论,这表明没有完全明显的答案)

因此,让我们假设我们不关心私有数据。我们满足于相信用户和开发人员不会在我们定义的方式之外的对象中乱搞

考虑到这一点,这种技术有什么不对的地方(除了它似乎在挑战数十年的OO风格和历史之外)

// namespace to isolate all PERSON's logic
var PERSON = {};

// return an object which should only ever contain data.
// The Catch: it's 100% public

PERSON.constructor = function (name) {
     return {
         name: name
     } 
}

// methods that operate on a Person
// the thing we're operating on gets passed in

PERSON.sayHello = function (person) {
     alert (person.name); 
}

var p = PERSON.constructor ("Fred");
var q = PERSON.constructor ("Me");

// normally this coded like 'p.sayHello()'
PERSON.sayHello(p);
PERSON.sayHello(q);
显然:

  • 没有什么可以阻止某人在邪恶中变异“p” 方法,或者简单地说,人最终的逻辑遍布各地。(标准的“新”技术也是如此)
  • 将“p”传递给您需要的每个函数将是一个小麻烦 我想用它
  • 这是一种奇怪的方法
  • 但这些理由是否足以让我们放弃它?在积极方面:

  • 它是高效的,与具有重复函数声明的闭包相反(可以说)
  • 它似乎非常简单易懂,而不是摆弄 “这”无处不在

  • 关键点是前面提到的隐私问题。我知道我会因此受到抨击,但是,我在寻找任何反馈。干杯。

    它本身没有什么问题。但它确实放弃了使用Javascript原型系统所固有的许多优势

    • 您的对象除了知道它是一个对象文字外,对自身一无所知。因此,
      instanceof
      将无法帮助您识别其来源。你只能用鸭子打字
    • 您的方法本质上是名称空间的静态函数,您必须通过传入对象作为第一个参数来重复自己。通过使用原型对象,您可以利用动态分派,因此
      p.sayHello()
      可以为
      PERSON
      ANIMAL
      执行不同的操作,具体取决于Javascript知道的类型。这是多态性的一种形式。您的方法要求您在每次调用方法时对类型进行命名(可能会出错)
    • 实际上您不需要
      构造函数
      函数,因为函数已经是对象了。您的
      PERSON
      变量也可能是构造函数
    您在这里所做的是创建一个模块模式(比如名称空间)

    以下是另一种模式,它保留了您现有的功能,但提供了上述优势:

    function Person(name)
    {
        var p = Object.create(Person.prototype);
        p.name = name; // or other means of initialization, use of overloaded arguments, etc.
        return p;
    }
    Person.prototype.sayHello = function () { alert (this.name); }
    
    var p = Person("Fred"); // you can omit "new"
    var q = Person("Me");
    p.sayHello();
    q.sayHello();
    console.log(p instanceof Person); // true
    var people = ["Bob", "Will", "Mary", "Alandra"].map(Person);
            // people contains array of Person objects
    

    是的,我真的不明白为什么你试图回避构造函数方法,或者为什么他们甚至觉得需要在函数构造函数(Object.create和soon类)上添加语法糖分,而构造函数本身是一个优雅、灵活的,无论像Crockford这样的人因为不喜欢OOP而给出了多少站不住脚的理由(因为人们忘记使用新的关键字-认真的?),OOP都是完全合理的。JS是高度功能驱动的,其OOP机制也不例外。在我看来,与其躲着它,不如接受它

    首先,您的观点列在“显然”下。

  • 在JavaScript中几乎不值得一提。高度易变性是由设计决定的。我们不怕自己或其他JavaScript开发人员。private vs.public范例没有什么用处,因为它保护我们免于愚蠢,而是因为它更容易理解其他开发人员代码背后的意图

  • 调用的努力不是问题所在。当不清楚你为什么要做你在那里做的事情时,麻烦就来了。我真的看不出你想要实现什么,核心语言方法对你没有好处

  • 这是JavaScript。多年来,除了JS开发者之外,所有人都觉得很奇怪。如果你能找到一种更好的方法来解决某个领域的问题,而不是一个更典型的解决方案,那就别担心了。在尝试替换它之前,请确保您理解了更典型方法的要点,就像许多人从其他语言范式中使用JS时所做的那样。用JS做一些琐碎的事情是很容易的,但一旦你想得到更多面向对象的驱动,就要尽你所能了解核心语言的工作原理,这样你就可以对流行的观点持更多的怀疑态度,这些观点是由那些以JavaScript为生的人传播的,这些人让JavaScript变得更可怕,更充斥着致命的骗局比实际情况更糟

  • 现在将您的积分放在“正面”下,

  • 首先,重复的函数定义实际上只是重循环场景中需要担心的事情。如果您经常以足够快的速度生成大量的对象,使非原型公共方法定义成为一个性能问题,那么您可能会在短期内遇到非平凡对象的内存使用问题。然而,我用过去式说话,因为不管怎样,这都不再是一个真正相关的问题。在现代浏览器中,由于现代JIT编译器的工作方式,在其他函数中定义的函数实际上通常可以提高性能。不管您支持什么浏览器,每个对象定义几个func都不是问题,除非您希望有成千上万个对象

  • 关于简单易懂的问题,这对我来说并不重要,因为我不知道你在这里赢得了什么。现在,我不需要使用一个对象,而是必须同时使用对象和它的伪构造函数,如果我不看定义,这将向我暗示使用“new”关键字来构建对象的函数。如果我是你代码库的新手,我会是废物
    function Person(name){
        //var name = name; //<--this might be more clear but it would be redundant
        this.identifySelf = function(){ alert(name); }
    }
    
    var bob = new Person();
    bob.identifySelf();