From 5efd50547e85715a1b8cabab658d903a381c61f0 Mon Sep 17 00:00:00 2001 From: Aleen Date: Sat, 14 Dec 2019 19:19:52 +0800 Subject: [PATCH] simulate object.create via ActiveXObject under IE8 #727 --- packages/core-js/internals/object-create.js | 47 ++++++++++++++++----- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/packages/core-js/internals/object-create.js b/packages/core-js/internals/object-create.js index 4d1964867392..1cf9acdac8e4 100644 --- a/packages/core-js/internals/object-create.js +++ b/packages/core-js/internals/object-create.js @@ -8,16 +8,33 @@ var sharedKey = require('../internals/shared-key'); var IE_PROTO = sharedKey('IE_PROTO'); var PROTOTYPE = 'prototype'; +var SCRIPT = 'script'; var EmptyConstructor = function () { /* empty */ }; +var scriptTag = function (content) { + var GT = '>'; + var LT = '<'; + return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT; +}; + +var NullProtoObject = function (ProtoObject) { + var length = enumBugKeys.length; + while (length--) delete ProtoObject[PROTOTYPE][enumBugKeys[length]]; + return ProtoObject; +}; + +// Create object with fake `null` prototype: use ActiveX Object with cleared prototype +var NullProtoObjectViaActiveX = function (activeXDocument) { + activeXDocument.write(scriptTag('')); + activeXDocument.close(); + var temp = activeXDocument.parentWindow.Object; + activeXDocument = null; // avoid memory leak + return NullProtoObject(temp); +}; // Create object with fake `null` prototype: use iframe Object with cleared prototype -var NullProtoObject = function () { +var NullProtoObjectViaIFrame = function () { // Thrash, waste and sodomy: IE GC bug var iframe = documentCreateElement('iframe'); - var length = enumBugKeys.length; - var GT = '>'; - var LT = '<'; - var SCRIPT = 'script'; var JS = 'java' + SCRIPT + ':'; var iframeDocument; iframe.style.display = 'none'; @@ -26,11 +43,9 @@ var NullProtoObject = function () { iframe.src = String(JS); iframeDocument = iframe.contentWindow.document; iframeDocument.open(); - iframeDocument.write(LT + SCRIPT + GT + 'document.F=Object' + LT + '/' + SCRIPT + GT); + iframeDocument.write(scriptTag('document.F=Object')); iframeDocument.close(); - NullProtoObject = iframeDocument.F; - while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]]; - return NullProtoObject(); + return NullProtoObject(iframeDocument.F); }; hiddenKeys[IE_PROTO] = true; @@ -45,6 +60,18 @@ module.exports = Object.create || function create(O, Properties) { EmptyConstructor[PROTOTYPE] = null; // add "__proto__" for Object.getPrototypeOf polyfill result[IE_PROTO] = O; - } else result = NullProtoObject(); + } else { + // Check for document.domain and active x support + // No need to use active x approach when document.domain is not set + // see https://github.com/es-shims/es5-shim/issues/150 + // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346 + var activeXDocument; + try { + /* global ActiveXObject */ + activeXDocument = document.domain && new ActiveXObject('htmlfile'); + } catch (error) { /* ignore */ } + + result = activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame(); + } return Properties === undefined ? result : defineProperties(result, Properties); };