Beta

What Happened To My Object?

Description
Loading description...
Puzzles
  • Please sign in or sign up to leave a comment.
  • Voile Avatar

    You're also not checking if user functions would make visible changes on the object after going through the function.

    I'd say it's a really, really, really bad practice for this kata to have solutions that mutates the input mercilessly ;-)

  • Voile Avatar

    You are also mixing up the property of the properties of the object, and the object itself.

    A perfectly normal object can have all its properties frozen (writable: false). It's just a side effect that whenever you freeze/seal an object, it also applies to all the properties. When Object.isFrozen and the like is called, it checks about the object itself, and not its properties, and yet by how your tests are written, doing the latter will pass your weak tests just fine.

  • Voile Avatar

    For the purposes of this kata, the input object can only exist in one, single condition at a time. For example, if the input object is frozen, it is only frozen. It is not both sealed and frozen at the same time. It is just frozen.

    Since freeze > seal > preventExtensions strictly, your requirements are suggesting a different behaviour from the original functions in Object. Naming them the same is really asking for confusion.

    You should really name it something like isOnlyFrozen or something.

  • Voile Avatar

    There is no way to determine properties can be updated in an object if it has no properties to begin with (i.e {}).

    If all objects are supposed to be non-empty it should be mentioned in the descriptions.

  • ZED.CWT Avatar
    it("should not be sealed", function() {
      Test.assertEquals(isSealed(frozenObj), false);
    })
    

    but

    frozenObj = {a: 1, b: 2, c: 3};
    Object.freeze(frozenObj);
    Object.isSealed(frozenObj) === true
    

    An object is sealed if it is not extensible and if all its properties are non-configurable and therefore not removable (but not necessarily non-writable).

    • ajLapid718 Avatar

      Hmmm...interesting, interesting.

      From my understanding, in that particular case, Object.freeze() was invoked with frozenObj being passed in as the argument. This means that invoking isFrozen(frozenObj) would result in a return value of the boolean true. It is up to here where we are on the same page, it seems.

      Now, we're at the point where we have to determine if a frozen object should, in fact, be sealed. At the moment, the tests are written in a way where a frozen object cannot and should not also be considered sealed.

      Part of the reason for this is because, taking that same frozen object scenario, we cannot do this:

        let targetObj = {a: 1, b: 2, c: 3};
        Object.freeze(targetObj);
        targetObj["a"] = 77;
        targetObj; // {a: 1, b: 2, c: 3};
        // The overwriting of key "a" DOES NOT go through successfully;
      

      However, if the object was sealed instead, something different happens:

        let targetObj = {a: 1, b: 2, c: 3};
        Object.seal(targetObj);
        targetObj["a"] = 77;
        targetObj; // {a: 77, b: 2, c: 3};
        // The overwriting of key "a" DOES go through successfully;
      

      In both cases, when an object is frozen or when an object is sealed:

      • we cannot create/add a property;
      • we can read from the object;
      • we cannot delete a property from the object;

      Where they differ, as seen in the code blocks above, is the fact that a property on a frozen object cannot be updated/overwritten whereas a property on a sealed object can be updated/overwritten.

      For this distinct reason, it seemed to make more sense (to me) to consider a frozen object as solely frozen. In other words, the fact that we could essentially edit a sealed object but we are unable to edit a frozen object was enough grounds for me to separate the two conditions (frozen/sealed) instead of allowing the object to exist in multiple states/conditions.

      If this is bad practice, or if I'm completely off-the-mark and I am misunderstanding, please let me know! I want to make sure this is as on-point as possible.

      Thank you!

    • ZED.CWT Avatar

      You are... complicating the task... From https://msdn.microsoft.com/library/ff806188(v=vs.94).aspx (if msdn redirected to mdn, please clear your browser cache or enter secret mode, change the language to any other than English and try load again).

      Function Object is not extensible configurable of all properties are set to false writable of all properties are set to false
      Object.preventExtensions Yes No No
      Object.seal Yes Yes No
      Object.freeze Yes Yes Yes
      Function Is the object extensible? Are all configurable of all properties false? Are all writable of all DATA properties false?
      Object.isExtensible Yes No No
      Object.isSealed No Yes No
      Object.isFrozen No Yes Yes

      (Seems that discuss section md does not support tables...)

      Talking about 'best' practice, when we trying to exam the function of a builtin function, we should ONLY rely on the specfication. From ECMA-262 8th Edition / June 2017.

      19.1.2.15 Object.isSealed ( O )
      When the isSealed function is called with argument O, the following steps are taken:
          1. If Type(O) is not Object, return true.
          2. Return ? TestIntegrityLevel(O, "sealed").
      
      7.3.15 TestIntegrityLevel ( O, level )
      The abstract operation TestIntegrityLevel is used to determine if the set of own properties of an object are Fixed. This abstract operation performs the following steps:
          1. Type(O) is Object.
          2. Assert: level is either "sealed" or "frozen".
          3. Let status be ? IsExtensible(O).
          4. If status is true, return false.
          5. NOTE: If the object is extensible, none of its properties are examined.
          6. Let keys be ? O.[[OwnPropertyKeys]]().
          7. For each element k of keys, do
              a. Let currentDesc be ? O.[[GetOwnProperty]](k).
              b. If currentDesc is not undefined, then
                  i. currentDesc.[[Configurable]] is true, return false.
                  ii. If level is "frozen" and IsDataDescriptor(currentDesc) is true, then
                      1. If currentDesc.[[Writable]] is true, return false.
      8. Return true.