JavaScript: Недосказанное Нетскейпом
Не оставляя надежду найти аналог CollectGarbage в Netscape, я сегодня расковырял интерпретатор JavaScript’а своего браузера на предмет наличия всего недокументированного. Ковырять вручную было лениво и я сначала написал небольшую программку, вычесывающую все текстовое из файла, на Перле, а потом небольшой скриптик под JUnix, который проверил, что из найденного относится к JavaScript. Ничего похожего на вызов сборщика мусора я так и не нашел, зато нашел кое-что другое. Результатами хочу поделиться.
Script(string) — создает кусок JavaScript-кода, который можно вызвать как обычную функцию. Разница между этим конструктором и Function заключается в том, что из кода, созданного конструктором Script, нельзя получить доступ к arguments и прочим свойствам и методам, специфическим для функций.
Пример использования Script:
AX = new Script ("alert('TEST')")
AX () // Нaпечатает "TEST"
Call() — создает пустой объект типа Window. Практической пользы маловато, но, как это можно применить я могу придумать.
Пример того, что можно сделать с Call:
AX = window
AX.BX = "TEST"
alert (window.BX) // Напечатает "TEST"
window.BX = "TEST1"
AX = new Call()
AX.BX = window.BX
window.BX = "TEST2"
alert (AX.BX) // Напечатает "TEST2"
AX.open = window.open
AX.open ("about:blank") // Откроет новое окно
BX = {}
BX.open = window.open
BX.open ("about:blank") // Вызовет ошибку
With(object) — достаточно странная функция. Копирует объект на новое место. Конструктор не вызывается, операция сравнения без приведения утверждает, что был создан новый объект, но изменения в одном экземпляре вызывают изменения в другом. Вообще-то, можно ее вызвать, как конструктор без параметров, в этом случае она создаст объект типа Object.
Пример вызова функции With:
function probe ()
{
alert ('Create.')
this.let = let
this.val = val
}
function let (n)
{
this.val = n
}
AX = new probe() // Напечатает "Create"
BX = AX
alert (AX===BX) // Напечатает "true"
BX = With (AX)
BX.let ("TEST")
alert (AX.val) // Напечатает "TEST"
alert (AX===BX) // Напечатает "false"
Closure(function_object) — очень похожа на With, но с парой отличий. Во-первых, Closure работает только с объектами Function, а во-вторых, ее можно вызвать как конструктор. И вот тут начинается самое странное. Внимание на пример.
Пример вызова функции и конструктора Closure:
function let (n)
{
this.val = n
}
Function.prototype.let = let
AX = new Function ("","")
BX = AX
alert (AX===BX) // "true". Объекты одинаковые.
AX.let ("TEST1")
alert (BX.val) // "TEST1". И это логично.
BX = Closure (AX)
alert (AX===BX) // "false". Объекты разные.
AX.let ("OTHER")
alert (BX.val) // "TEST2". И это тоже логично.
BX = new Closure (AX)
alert (AX===BX) // "false". Объекты разные.
AX.let ("TEST2")
alert (BX.val) // "TEST2". И это странно.
Arguments(объект) — в принципе можно применять для дублирования массива аргументов. Если применить как функцию, а не как конструктор, то Netscape может обидится и сказать GPF. А вообще во время экспериментов с этим объектом мой NC 4.7 падал настолько часто, что можно сказать — это его больное место, трогать которое не рекомендуется.
Пример вызова конструктора Arguments:
AX = new Function ("", "return new Arguments(arguments)")
alert (AX("TEST1").length) // "1"
alert (AX("TEST1","TEST2").length) // "2"
Желающим испытать свое терпение и способности к обобщению, предлагается выяснить, какие функции несет каждый объект, свойство или метод из списка: __count__, __parent__, __proto__, __name__, __length__, __arity__, __call__, __caller__, __callee__. Кое-что совсем очевидно, но кое с чем придется серьезно помучиться. :))
Мое мнение — все, что я накопал, это усы от внутренней объектной модели браузера. Результат попытки упихать все, что только возможно, в объекты.
P.S. Мучал я Netscape версии 4.7. Как нибудь, надеюсь, руки дойдут до чего-нибудь более современного. Кстати, было бы интересно рассмотреть все эти, вырванные с мясом куски, на предмет дыр в безопасности и crash code.