0

I use Array for instance.

let arr =[1, 2, 3, 4];


Array.prototype.a = function() {
    //code        
}
arr.a();  //return [2, 4, 6, 8]

Is it possible to create prototype property. And it's a function, it will double any element .

TTT
  • 53
  • 7
  • 2
    Yes, you may do so – CertainPerformance Mar 25 '20 at 08:15
  • 4
    @CertainPerformance - it's always good to get permission :p – Jaromanda X Mar 25 '20 at 08:15
  • I don't know how to get array – TTT Mar 25 '20 at 08:17
  • In 2020 unless you **must** develop pre-ES2015 code there is very little reason to use prototypes directly given now we have classes. – zerkms Mar 25 '20 at 08:17
  • 5
    You *could* do that, but usually [you *should not*](https://stackoverflow.com/questions/14034180/why-is-extending-native-objects-a-bad-practice) (unless you do it on your own types). – str Mar 25 '20 at 08:17
  • @TTT hint: use `this` – zerkms Mar 25 '20 at 08:20
  • 1
    Note that if you add something to `Array` prototype, then **all** arrays will have this `.a`, even ones that does not need it. It may lead to side effects – Justinas Mar 25 '20 at 08:21
  • @zerkms `this` will reference to Array, cant not get variable – TTT Mar 25 '20 at 08:27
  • 1
    @TTT `this` references to the value, `[1, 2, 3, 4]` in your case. – zerkms Mar 25 '20 at 08:28
  • @zerkms I think I make some mistake before. So this is not appropriate thing to do? – TTT Mar 25 '20 at 08:33
  • @TTT nope, instead - create a function that accepts an array and returns a new array. – zerkms Mar 25 '20 at 08:33
  • 1
    It's better to subclass Array: `class MyArray extends Array{ static get [Symbol.species](){return MyArray} a(){ return this.map(e => e*2) } }`, then use it like `const arr = MyArray.from([1, 2, 3, 4]); console.log(arr.a())` – FZs Mar 25 '20 at 08:34

1 Answers1

-1

Although you can modify the .prototype property of intrinsic (built-in) objects like Array, it is considered poor practice because other people might make assumptions that your change invalidates (eg. naming collisions). It's best to leave the intrinsics alone.

You can, however, use prototypical inheritance to extend intrinsic objects, without modifying them directly.

class MyArray extends Array {
    static [Symbol.species] = Array
    *[Symbol.iterator]() {
        for(let x = 0; x < this.length; x++) { yield this[x]*2 }
    }
}

const log = console.log
const arr = new MyArray(1,2,3)
console.log([...arr]) // 2,4,6
log(arr.map((i) => i) instanceof MyArray) // false
log(arr.map((i) => i) instanceof Array) // true

In versions of JavaScript prior to ES2015, subclassing intrinsic objects like Array was fraught with difficulty. The closest you could come to it was something like this:

function MyArray() {
    [].push.apply(this, arguments)
    //... plus tens of lines of code managing the `length` property 
}
Object.defineProperty(MyArray, Symbol.species, { value: Array })
MyArray.prototype = Object.create(Array.prototype)
MyArray.prototype[Symbol.iterator] = function*() {
    for (let x = 0; x < this.length; x++) {
        yield this[x] * 2
    }
}

const log = console.log
const arr = new MyArray(1,2,3)
log([...arr]) // 2,4,6
log(arr.map((el) => el) instanceof MyArray) // false
log(arr.map((el) => el) instanceof Array) // true
Ben Aston
  • 53,718
  • 65
  • 205
  • 331