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

标签 javascript closures prototype

我们一直在讨论如何最好地处理我们的 JS 应用程序中的对象,研究 Stoyan Stefanov 的书,阅读无休止的关于“new”、“this”、“prototype”、闭包等的 SO 帖子(事实上有这么多,而且他们有很多相互竞争的理论,这表明没有完全明显的答案)。

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

鉴于此,这种技术有什么问题(除了它似乎违背了数十年的 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);

显然:

  1. 没有什么可以阻止某人在 unholy 中变异“p” 方式,或者仅仅是 PERSON 的逻辑最终遍布整个地方。 (对于规范的"new"技术也是如此)。
  2. 将“p”传递给您创建的每个函数会是一个小麻烦 想使用它。
  3. 这是一个奇怪的方法

但这些理由足以驳回它吗?积极的一面:

  1. 高效,因为(可以说)与具有重复函数声明的闭包相反。
  2. 看起来非常简单易懂,而不是摆弄 “这个”无处不在。

关键是放弃隐私。我知道我会因此受到抨击,但是,正在寻找任何反馈。干杯。

最佳答案

它本身并没有什么错。但它确实放弃了许多使用 Javascript 原型(prototype)系统固有的优势。

  • 你的对象除了知道它是一个对象字面量外,对它自己一无所知。所以 instanceof 不会帮助你识别它的来源。您将只能使用鸭子打字。
  • 您的方法本质上是命名空间静态函数,您必须重复自己的操作,将对象作为第一个参数传递。通过拥有原型(prototype)对象,您可以利用动态调度,这样 p.sayHello() 可以为 PERSONANIMAL 取决于 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

关于javascript - 这种 JavaScript 编码风格有什么问题? (闭包与原型(prototype)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14719926/

相关文章:

swift - 如何在 Swift 中使用 associatedtype 的协议(protocol)闭包中使用 Void 类型

swift - 为什么闭包在 Swift 3 中默认都是非转义的而需要显式的 `self`?

javascript - 原型(prototype)和 __proto__,哪种说法是正确的?

javascript - Typescript:类型检查正确方法

JavaScript - 保留尾随零

javascript - Uncaught ReferenceError : $ is not defined python flask

ruby - 是否可以使用 block 定义 Ruby 单例方法?

javascript - 编辑日期对象Javascript

javascript - Visual Studio Code 自动完成已损坏

javascript - .fadein 与 javascript