Help us understand the problem. What is going on with this article?

JavaScriptのビルトインオブジェクトを拡張する

例えば、配列を拡張してrubyのようにfirstで1件目のエントリーを取得できるようにするにはどうすればよいか、
といったことを紹介します。

const arr = [1, 10, 100, 200]
arr.first // -> 1

拡張する方法を紹介する記事ですので、拡張している内容は特に重要ではありません。

注意

グローバルなものを変更してしまう内容を紹介しています。

一見便利に思えても、名前が衝突する可能性があったりしますので、実用するべきかどうかは慎重に検討してください。

(僕は個人の実装物でしかやりません)

そして、実装する内容も、本当に汎用的に使えるものに絞ったほうがよいです。

Mathオブジェクトに関数を拡張

この場合、単に好きなキー名に関数をアサインしてしまって大丈夫です。

Math.sum = (...numbers) => {
  return numbers.reduce((prev, current) => prev + current)
}

Math.sum(1, 10, 100) // -> 111

↑与えられた可変長引数の数値を全て合計して返す関数です。可変長引数やreduceの解説は省略。

Math.average = (...numbers) => {
  return Math.sum(...numbers) / numbers.length
}

Math.average(1, 10, 100) // -> 37

↑与えられた可変長引数の数値の平均を返す関数。さっきのsumを再利用。

Math.randomInt = (min, max) => {
  return Math.floor(Math.random() * (max + 1 - min)) + min
}

Math.randomInt(1, 100) // -> 55

↑第一引数〜第二引数の範囲で、ランダムに整数を返す関数。

Arrayのprototypeにgetter/setterを定義

prototypeを拡張する際は、definePropertyを使ってください。

Object.defineProperty(Array.prototype, 'first', {
  get () {
    return this[0]
  },
  set (value) {
    this[0] = value
  }
})

const arr = [1, 10, 100, 200]
arr.first // -> 1
arr.first = 5
arr.first // -> 5

配列の1件目にアクセスできるプロパティを実装してみました。

Arrayのprototypeに関数を拡張

同じくdefinePropertyを使い、valueに定義します。

Object.defineProperty(Array.prototype, 'random', {
  value () {
    return this[Math.randomInt(0, this.length - 1)]
  }
})

const arr = [1, 10, 100, 200]
arr.random() // -> 10
arr.random() // -> 200

↑配列内から一つのエントリーをランダムに取得します。さっきのrandomIntを再利用。

Object.defineProperty(Array.prototype, 'clear', {
  value () {
    return this.length = 0
  }
})

const arr = [1, 10, 100, 200]
arr.clear()
arr // -> []

↑配列を空にする関数です。

(配列はarr.length = 0で空にできますが、仕様を知っていないと何をしているか意味がわかりません。arr = []なら分かりやすいけど、別のオブジェクトになってしまうのでやっていることが全然変わってきます。なので明確な名前をつけて関数化しました。)

プリミティブ型のラッパーオブジェクトも拡張

手順は同じです。

Object.defineProperty(Number.prototype, 'half', {
  get () {
    return this / 2
  }
})
const num = 1280
console.log(num) // -> 1280
console.log(num.half) // -> 640
console.log(num.half.half) // -> 320
console.log(num.half.half.half) // -> 160

数値を半分にします。

補足

defineProperty

さきほどのdefinePropertyの第三引数で渡した記述子には、get, set, value以外にもありますので、詳しくは以下をご覧ください。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

Objectのprototype

もちろんMathArray以外でも同じ方法で拡張できますが、Objectのprototypeは変更するとあらゆるものに影響してしまうのでやめたほうが良いです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした