object-create.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. var anObject = require('../internals/an-object');
  2. var defineProperties = require('../internals/object-define-properties');
  3. var enumBugKeys = require('../internals/enum-bug-keys');
  4. var hiddenKeys = require('../internals/hidden-keys');
  5. var html = require('../internals/html');
  6. var documentCreateElement = require('../internals/document-create-element');
  7. var sharedKey = require('../internals/shared-key');
  8. var GT = '>';
  9. var LT = '<';
  10. var PROTOTYPE = 'prototype';
  11. var SCRIPT = 'script';
  12. var IE_PROTO = sharedKey('IE_PROTO');
  13. var EmptyConstructor = function () { /* empty */ };
  14. var scriptTag = function (content) {
  15. return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;
  16. };
  17. // Create object with fake `null` prototype: use ActiveX Object with cleared prototype
  18. var NullProtoObjectViaActiveX = function (activeXDocument) {
  19. activeXDocument.write(scriptTag(''));
  20. activeXDocument.close();
  21. var temp = activeXDocument.parentWindow.Object;
  22. activeXDocument = null; // avoid memory leak
  23. return temp;
  24. };
  25. // Create object with fake `null` prototype: use iframe Object with cleared prototype
  26. var NullProtoObjectViaIFrame = function () {
  27. // Thrash, waste and sodomy: IE GC bug
  28. var iframe = documentCreateElement('iframe');
  29. var JS = 'java' + SCRIPT + ':';
  30. var iframeDocument;
  31. iframe.style.display = 'none';
  32. html.appendChild(iframe);
  33. // https://github.com/zloirock/core-js/issues/475
  34. iframe.src = String(JS);
  35. iframeDocument = iframe.contentWindow.document;
  36. iframeDocument.open();
  37. iframeDocument.write(scriptTag('document.F=Object'));
  38. iframeDocument.close();
  39. return iframeDocument.F;
  40. };
  41. // Check for document.domain and active x support
  42. // No need to use active x approach when document.domain is not set
  43. // see https://github.com/es-shims/es5-shim/issues/150
  44. // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
  45. // avoid IE GC bug
  46. var activeXDocument;
  47. var NullProtoObject = function () {
  48. try {
  49. /* global ActiveXObject -- old IE */
  50. activeXDocument = document.domain && new ActiveXObject('htmlfile');
  51. } catch (error) { /* ignore */ }
  52. NullProtoObject = activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame();
  53. var length = enumBugKeys.length;
  54. while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]];
  55. return NullProtoObject();
  56. };
  57. hiddenKeys[IE_PROTO] = true;
  58. // `Object.create` method
  59. // https://tc39.es/ecma262/#sec-object.create
  60. module.exports = Object.create || function create(O, Properties) {
  61. var result;
  62. if (O !== null) {
  63. EmptyConstructor[PROTOTYPE] = anObject(O);
  64. result = new EmptyConstructor();
  65. EmptyConstructor[PROTOTYPE] = null;
  66. // add "__proto__" for Object.getPrototypeOf polyfill
  67. result[IE_PROTO] = O;
  68. } else result = NullProtoObject();
  69. return Properties === undefined ? result : defineProperties(result, Properties);
  70. };