Проблема с некоторыми из хост-объектов (т. Е. Любых не собственных объектов) в IE (и не только IE) заключается в том, что они не наследуются от Function.prototype
(и часто ни от верхнего уровня Object.prototype
). Некоторые хост-объекты, которые могут выглядеть как функции , на самом деле не имеют ничего общего с функциями, за исключением того, что они могут быть вызваны. Тот факт, что эти объекты не наследуются от Function.prototype
, означает, что они не могут быть идентифицированы как функции с оператором instanceof
; что их конструктор не ссылается Function
; и что им не хватает всех Function.prototype.*
методов, таких как call
или apply
. Даже их внутреннее свойство [[Class]] может не совпадать со свойством «Function», как и с любым собственным объектом (обратите внимание, что [[Class]] может быть выведен из результата Object.prototype.toString
value).
Это действительно ожидается, поскольку хост-объекты не требуются для реализации многих вещей, которые делают нативные объекты (согласно ECMA-262, 3-е изд.). Допускается, чтобы хост-объект допустил ошибку при вызове метода (например, hostObject.hostMethod()
); или при передаче его в качестве операнда стандартным операторам, таким как delete
(например, delete hostObject.hostMethod
). Как вы можете видеть, вызываемые объекты хоста также НЕ ДОЛЖНЫ наследоваться от нативного Function.prototype
.
Такое непредсказуемое (но в то же время совершенно совместимое) поведение на самом деле является одной из основных причин, почему рекомендуется расширение объектов хоста по сравнению с .
Но вернемся к вашей call
проблеме:)
Особенность этих "хитрых" хост-объектов IE заключается в том, что они часто реализуют внутренний метод [[Call]], и для них можно вызывать call
и apply
, хотя не напрямую .
Вот шаблон для эмуляции apply
вызова объекта, у которого его нет:
function f(){ return arguments };
Function.prototype.apply.call(f, null, [1,2,3]); // [1,2,3]
null
может быть заменен любым контекстным объектом, который должен вызываться, конечно.
И пример apply
вызова для хост-объекта, который не имеет call
:
// should work in IE6, even though `alert` has no `call` there
Function.prototype.call.call(alert, window, 'test');
Применение его к вашему коду
// Calls Master.initialize borrowing from Function.prototype
Function.prototype.apply.call(Master.initialize, Master, [1,"VC2"]);