简体   繁体   中英

Change Array.prototype in node.js

I want to make some functions available to all my arrays.

For instance, I want a function to remove duplicates:

Array.prototype.uniq = function () {
  return Array.from(new Set(this));
};

But I want to make this function work in my entire node.js project.

Will it work if I just put it in server.js which is run when I type npm start ?

It would be great if it also works on the client. Is it possible or should I consider server and client strictly separated from one another?

Is it bad practice to extend Array.prototype like this? I just think it seems stupid to write the code many times.

Another options could be to use

function uniquify(arr) {
  return Array.from(new Set(arr));
}

but array.uniq() seems better than uniquify(array) .

First: If you're going to add properties to Array.prototype , don't add them via simple assignment. Doing so creates enumerable properties, and code that relies on arrays not having any enumerable properties by default will break.

So use defineProperty instead:

Object.defineProperty(Array.prototype, "uniq", {
    value: function uniq() {
      return Array.from(new Set(this));
    }
});

To your questions:

Will it work if I just put it in server.js which is run when I type npm start ?

I'm not sure what server.js you're talking about, but if you're talking about modifying files that are built-in parts of Node or npm rather than parts of your project, I strongly recommend not doing so.

It would be great if it also works on the client. Is it possible or should I consider server and client strictly separated from one another?

They're completely separate. If you want to do this on the client, you'll need to include script adding uniq on the client.

Is it bad practice to extend Array.prototype like this? I just think it seems stupid to write the code many times.

There are two camps of thought on that:

  1. Yes, it's bad. You're likely to run into naming conflicts with someone else adding their own, different uniq . Combining code from multiple sources is getting very, very common, increasing the odds of those problems. Future versions of the language may add uniq . Since the committee steering the language (TC-39) tries to steer around potential conflicts, if your client-side library became popular, it would make their work harder. (MooTools has, more than once.)

  2. No, it's not bad, it's what prototypes are for. Naming conflicts can be handled if and when. TC-39 can lump it.

You'll have to make your own decision about whether to do it.

Another option is to extend the array class so that you can get the best of both worlds...

You can add whatever methods you want to your extended newArray class while not polluting the global namespace.

As far as in the browser -- you'll have to do the same thing, though it depends on if you are transpiling ES6 to ES5, limiting yourself to ES6 browsers or if you are looking for a way to make things work in ES5 as well.

Using a factory function to return your newArray type would be one approach -- being mindful to make sure that whatever methods you add are not iterable.

There is a discussion of it here:

Extending Array with ES6 classes

It is considered "bad practice" to manipulate the array prototype.

I (personally) do not think it is so bad to do it with something that has a very "unique" name, but then unique names are hard to come by.

It is much better to have some utility functions that you can call and use when you want to.

For such kind of methods that you want to use multiple times in your application you can create a file like:

appUtils.js

var appUtils = {};

appUtils.getUniqueArray = function () {
  return Array.from(new Set(this));
};

// can add other methods as well

and you can require this file wherever you want to use this function. If you have other reusable methods then can add them as well like above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM