From 22681a0c61b2a52404699da7c2e155ecaa51234c Mon Sep 17 00:00:00 2001 From: Passakorn Rattanaprapan Date: Mon, 1 Feb 2021 18:06:54 +0700 Subject: [PATCH] Setting a property on an object's prototype with function --- dist/nested-property.js | 24 +++++++++++++----------- index.js | 4 ++-- package-lock.json | 2 +- test/set.spec.js | 20 ++++++++++++++++++++ 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/dist/nested-property.js b/dist/nested-property.js index 97a589b..fca9da0 100644 --- a/dist/nested-property.js +++ b/dist/nested-property.js @@ -11,17 +11,19 @@ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "functi function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } - function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } -function isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } +function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } -function _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } @@ -32,23 +34,23 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g var ARRAY_WILDCARD = "+"; var PATH_DELIMITER = "."; -var ObjectPrototypeMutationError = -/*#__PURE__*/ -function (_Error) { +var ObjectPrototypeMutationError = /*#__PURE__*/function (_Error) { _inherits(ObjectPrototypeMutationError, _Error); + var _super = _createSuper(ObjectPrototypeMutationError); + function ObjectPrototypeMutationError(params) { var _this; _classCallCheck(this, ObjectPrototypeMutationError); - _this = _possibleConstructorReturn(this, _getPrototypeOf(ObjectPrototypeMutationError).call(this, params)); + _this = _super.call(this, params); _this.name = "ObjectPrototypeMutationError"; return _this; } return ObjectPrototypeMutationError; -}(_wrapNativeSuper(Error)); +}( /*#__PURE__*/_wrapNativeSuper(Error)); module.exports = { set: setNestedProperty, @@ -159,7 +161,7 @@ function setNestedProperty(object, property, value) { } if (typeof property == "number") { - object[property] = value; + object[property] = typeof value === "function" ? value(currentObject[currentProperty]) : value; return object[property]; } @@ -181,7 +183,7 @@ function setNestedProperty(object, property, value) { } if (isLastSegment(segments, index)) { - currentObject[currentProperty] = value; + currentObject[currentProperty] = typeof value === "function" ? value(currentObject[currentProperty]) : value; } return currentObject[currentProperty]; diff --git a/index.js b/index.js index 92ddf89..04f0639 100644 --- a/index.js +++ b/index.js @@ -124,7 +124,7 @@ function setNestedProperty(object, property, value) { } if (typeof property == "number") { - object[property] = value; + object[property] = typeof value === "function" ? value(currentObject[currentProperty]) : value; return object[property]; } @@ -146,7 +146,7 @@ function setNestedProperty(object, property, value) { } if (isLastSegment(segments, index)) { - currentObject[currentProperty] = value; + currentObject[currentProperty] = typeof value === "function" ? value(currentObject[currentProperty]) : value; } return currentObject[currentProperty]; diff --git a/package-lock.json b/package-lock.json index 59aaa67..9314ee8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "nested-property", - "version": "3.0.0", + "version": "4.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/test/set.spec.js b/test/set.spec.js index 802e555..80e401c 100644 --- a/test/set.spec.js +++ b/test/set.spec.js @@ -398,4 +398,24 @@ describe("nested-property.set()", function () { }).to.throw(sut.ObjectPrototypeMutationError); }); }); + + describe("When setting a property on an object's prototype with function", () => { + let newObj, protoObj; + + beforeEach(function () { + protoObj = { + a: 1 + }; + newObj = Object.create(protoObj); + + sut.set(newObj, "__proto__.a", function (value) { + return value * 2; + }); + }); + + it("Then mutates the prototype", function () { + expect(protoObj.hasOwnProperty("a")).to.be.true; + expect(protoObj.a).to.be.eql(2); + }); + }); });