Moving from `prototype` and `new` to a closure-and-exposure pattern

前端 未结 4 1647
礼貌的吻别
礼貌的吻别 2021-01-21 14:07

I have been re-factoring someone else\'s JavaScript code.

BEFORE:

function SomeObj(flag) {
    var _private = true;
    this.flag = (fla         


        
4条回答
  •  旧巷少年郎
    2021-01-21 15:03

    What else I have lost by foregoing prototype?

    I'm sure someone can provide an answer, but I'll at least give it a shot. There are at least two reasons to use prototype:

    1. prototype methods can be used statically
    2. They are created only once

    Creating a method as an object member means that it is created for every instance of the object. That's more memory per object, and it slows down object creation (hence your efficiency). People tend to say that prototype methods are like class methods whereas member methods are like object methods, but this is very misleading since methods in the prototype chain can still use the object instance.

    You can define the prototype as an object itself, so you may like the syntax better (but it's not all that different):

    SomeObj.prototype = {
        method1: function () {},
        method2: function () {}
    }
    

    Your argument that it seems less controlled is valid to me. I get that it is weird to have two blocks involved in creating an object. However, it's a bit spurious in that there is nothing stopping someone from overwriting the prototype of your other object anyway.

    //Your code
    var SomeObj = function (flag) { //...
    
    //Sneaky person's code
    delete SomeObj.reset;
    SomeObj.prototype.reset = function () { /* what now? */ }
    

    Foregoing new

    If you're only going to be creating specific object instances on the fly via {} notation, it's not really different from using new anyway. You would need to use new to create multiple instances of the same object from a class (function) definition. This is not unusual as it applies to any object oriented programming language, and it has to do with reuse.

    For your current application, this may work great. However, if you came up with some awesome plugin that was reusable across contexts, it could get annoying to have to rewrite it a lot. I think that you are looking for something like require.js, which allows you to define "modules" that you can import with the require function. You define a module within a define function closure, so you get to keep the constructor and prototype definitions wrapped together anyway, and no one else can touch them until they've imported that module.

    Advantages of closure vs. prototype

    They are not mutually exclusive:

    var attachTo = {};
    ;(function (attachTo, window, document, undefined) {
        Plugin = function () { /* constructor */ };
        Plugin.prototype = { /* prototype methods */ };
    
        attachTo.plugin = Plugin;
    })(attachTo, window, document);
    var plugin = new (attachTo.plugin);
    

    http://jsfiddle.net/ExplosionPIlls/HPjV7/1/

提交回复
热议问题