マジでどうでもいいWebKitのバグを修正した(Function.prototype.toString編)
インターナルなDiscordで人に説明したやつをそのままコピーしたものです。
https://webkit.org/blog/15375/release-notes-for-safari-technology-preview-193/ の JavaScript の Resolved Issues にあるやつです。コミットは https://github.com/WebKit/WebKit/commit/1ff045b365bb63494783062033d5ef8a0c629cb7 です。
Function.prototype.toString
という関数はthis
の関数を文字列化して返します。そしてビルトイン関数に対してどういう文字列を返すべきか、というのは仕様に定められています。[1]
たとえば
Function.prototype.toString.call(Array.prototype.map)
は "function map() { [native code] }"
という文字列を返します。
さらに、アクセサプロパティのゲッター/セッター関数に対しては特別なルールがあります。function
のあとに get
をつけて出力する必要があるのです。たとえば Set.prototype.size
はアクセサプロパティなので
const getter = Object.getOwnPropertyDescriptor(Set.prototype, "size").get;
console.log(Function.prototype.toString.call(getter));
は "function get size () { [native code] } "
を出力します。
しかし、WebKitの実装には、この特別なルールに従わないビルトインのアクセサプロパティがいくつか存在しました。RegExp Legacy Features のプロパティたちなどがそうです[2]。
たとえば RegExp["$+"]
はアクセサプロパティですが
const getter = Object.getOwnPropertyDescriptor(RegExp, "$+").get;
console.log(Function.prototype.toString.call(getter));
は "function $+() { [native code] }"
と出力していました。これはゲッター関数に対する Function.prototype.toString
であるにも関わらず function
のあとに get
がないので仕様に違反しています。
なので、めっちゃわかりやすく言えば
const getter = Object.getOwnPropertyDescriptor(RegExp, "$+").get;
console.log(Function.prototype.toString.call(getter));
// 変更前: "function $+() { [native code] }"
// 変更後: "function get $+() { [native code] }"
ということです。なんじゃそりゃ。
ということで、今回自分の行った変更では、そのような一部のアクセサプロパティのゲッター・セッター関数に対する Function.prototype.toString
であっても function
のあとに get
をつけるように修正した、ということでした。マジでどうでもいいですね。
Discussion