timoxley / functional-javascript-workshop

A functional javascript workshop. No libraries required (i.e. no underscore), just ES5.
2.06k stars 438 forks source link

Basic: Call - duckCount function using call() -- a question about objects inheriting from Object.prototype #116

Open Choongkyu opened 9 years ago

Choongkyu commented 9 years ago

In the prompt for this exercise, we're asked a question: But what if an object doesn't inherit from Object.prototype?

// create an object with 'null' prototype.
var object = Object.create(null)
object.quack = function() {
  console.log('quack')
}

Object.getPrototypeOf(object) === Object.prototype // => false
Object.getPrototypeOf(object) === null             // => true

object.hasOwnProperty('quack')
// => TypeError: Object object has no method 'hasOwnProperty'

OK. I think I follow: if an object is created with this syntax, var object = Object.create(null) this object does not inherit from Object.prototype. Yet, in this problem, there's no need to create objects in said manner, as far as I can tell. Instead objects are defined as arguments passed into the duckCount function we're instructed to implement by module.exports. For example, logging the arguments shows that the function is called with the following syntax:

duckCount({ quack: true},{ quack: true, hasOwnProperty: [Function] }, { }, { } );

So I was wondering whether an object defined as "{quack: true}" inherits all the properties of Object.prototype or not and found that the following function shows that indeed none of the arguments inherit from Object.prototype:

function test(){return ({quack: true}.prototype == Object.create.prototype)};

So my question is which objects automatically inherit from Object.prototype? From the top sample code, it seemed as if the presentation suggested that the "null" argument in var object = Object.create(null) forced it to be an object that does not inherit properties from Object.prototype and that objects, if defined otherwise, generally inherit from Object.prototype.

Clearly, I'm mistaken and I was wondering if knowing which objects inherit from Object.prototype and which don't can be done through reasoning outside of memorizing a breakdown of object types as listed here.

It seems a bit cumbersome to have to memorize that breakdown and I was wondering if this can be further reduced to some single guiding principle on what determines an object's inheriting from Object.prototype or not. Thank you!

timoxley commented 9 years ago

So my question is which objects automatically inherit from Object.prototype?

By default all objects inherit from Object.prototype.

xaca commented 5 years ago

Hello, I have this code, and it pass. But when i use run, sometimes didn't pass.

Note: I know that the excersise said, don't use a counter, but i having problems using filters, because input was and object, not an array. :coffin:

function duckCount() {
      // SOLUTION GOES HERE      
      function validarArgumento(parametros, solucion)
      {
        if(parametros.length)
        {
          if('quack' in parametros[0])
          {           
            solucion++;
          }          
          return validarArgumento(parametros.slice(1),solucion);
        }
        else
        {
          return solucion;
        }
      }
      return validarArgumento(Array.from(arguments),0);
    }

    module.exports = duckCount

:ok_hand: Pass: [Arguments] { '0': { quack: true }, '1': { quack: undefined }, '2': { quack: undefined }, '3': { quack: true, hasOwnProperty: [Function: hasOwnProperty] }, '4': { quack: true }, '5': {}, '6': [Object: null prototype] { quack: undefined }, '7': { quack: undefined }, '8': {}, '9': {}, '10': [Object: null prototype] { quack: true }, '11': {}, '12': {}, '13': {}, '14': { quack: undefined }, '15': {}, '16': [Object: null prototype] { quack: true }, '17': [Object: null prototype] { quack: undefined } } submission: 'Matched 11 of 11 valid objects from 18 total.' solution: 'Matched 11 of 11 valid objects from 18 total.'

:no_entry_sign: Fail [Arguments] { '0': { quack: true }, '1': { quack: undefined }, '2': {}, '3': { quack: undefined }, '4': { quack: false }, '5': {}, '6': { quack: false }, '7': {}, '8': { quack: true, hasOwnProperty: [Function: hasOwnProperty] }, '9': [Object: null prototype] { quack: undefined }, '10': {}, '11': { quack: true, hasOwnProperty: [Function: hasOwnProperty] }, '12': {}, '13': { quack: undefined } } submission: 'Matched 10 of 9 valid objects from 14 total.' solution: 'Matched 9 of 9 valid objects from 14 total.'

:warning: Why one {} return true if I ask "quack" in params?

Also I'm thinking that the arguments are tricky, I'm started using

if(Object.getPrototypeOf(parametros[0]) === null && Object.prototype.hasOwnProperty.call(parametros[0], 'quack'))

Because the excersie says,

Do not match values inherited from prototypes.

But this was the answer:

{ quack: true } { quack: true, hasOwnProperty: [Function: hasOwnProperty] } {} { quack: undefined } {} { quack: true } { quack: true, hasOwnProperty: [Function: hasOwnProperty] } {} { quack: true } {} {} submission: 'Matched 0 of 6 valid objects from 11 total.'

My first try, without using a counter:

 function duckCount() {
      // SOLUTION GOES HERE      
      console.log(arguments);
      return Array.from(arguments).filter(
        (obj)=>((Object.getPrototypeOf(obj)===null)&&(Object.prototype.hasOwnProperty.call(obj, 'quack')))).length;
    }

    module.exports = duckCount

:no_entry_sign: Fail: [Arguments] { '0': { quack: true }, '1': [Object: null prototype] { quack: undefined }, '2': { quack: false }, '3': {}, '4': [Object: null prototype] { quack: true }, '5': { quack: undefined } } submission: 'Matched 2 of 5 valid objects from 6 total.'

Please help me to understant what happend.

hungdao-testing commented 1 year ago

Hi, I am not fully understand the meaning of the exercise

Do not match values inherited from prototypes

Would you @timoxley or experts guys could help give more explanation/example