0

My homework is like: Write a "keys" function that gets passed an object and returns an array of the object's properties. Be sure to screen out the object's methods. The keys array only has names of the object's name/value pairs. Because of cross browser issues(non-support in older browsers), the Objectkeys method cannot be used. Your function should provide the same service for all the browsers.

My initial code is as below:

function keys(obj){
  var key="";
  var i = 0;
  var array = [];
  for(i = 1; i<arguments.length; i++){
     for(key in arguments[i]){
         if(obj.hasOwnProperty&&(!_.isArray(obj))){
             obj[key]=arguments[i][key];
         }
     }
  }
  for(var j = 0; j < obj.length; j++){
     for(key in obj[j]){
        array[j] = obj[j];
     }
  }
 return array;
 }

I'm pretty sure that my function has a lot of problems. Could you please help me with it? Thank you!

  • What problems are you noting with this code? – Scott Sauyet Aug 21 '13 at 01:03
  • I don't know myself. But I can feel my code is not the solution. – Penghan Yang Aug 21 '13 at 01:08
  • We could give you the solution, but that would be cheating, wouldn't it? Help us help you by explaining what approaches you have tried, and why. For example, what are all those loops for? What did you have in mind when you wrote them? – bfavaretto Aug 21 '13 at 01:13
  • I want to have a thing to first get all of the arguments merged into one single object. Then I want to get every property of this object into an array. Is this the right thought about how to solve the problem? – Penghan Yang Aug 21 '13 at 01:18
  • @bfavaretto - I think based on some of the stuff Penghan has shown here, Penghan really needs to be researching and looking at more valid, good code. This looks like a collection of messes taken from all over the place with very minimal understanding. I pointed Penghan to the MDN cross-browser implementation for study. – netpoetica Aug 21 '13 at 01:19
  • Well, I'm back too late. I hope the answers you got helped you understand the solution! – bfavaretto Aug 21 '13 at 03:01

3 Answers3

1

There are a lot of problems with your code. The answer you need is here in the MDN though: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

That function does EXACTLY what your professor asked, and it does it cross-browser. There is what is called a poly-fill, or cross-browser implementation of object.keys listed under "Compatability". Try to sort out that code to figure out what it's doing :)

Here are some problems with your own code that I see right off the bat - it's probably not working code, I just wanted to give you some guidance of things you did incorrectly:

// Name your function something useful and descriptive.
function getKeysAsArray(obj){
  // For starters, dont name a variable "array" - bad practice.
  var key="",
      i = 0,
      results = [];

  // First foor loop unnecessary, do not use arguments here
  // because you already know the name of your argument.
     for(key in obj){
         // See if this browser supports has OwnProperty by using typeof
         // which will fail gracefully, vs what u did which will stop the
         // script from running
         if(typeof Object.hasOwnProperty === 'function'){
             // You probably shouldn't be using underscore _
             if(obj.hasOwnProperty && !(obj instanceof Array)){
                 results.push(obj[key]);
             }
         }
     }

  return results;
}
netpoetica
  • 3,375
  • 4
  • 27
  • 37
  • Thank you very much. Is "typeof Object.hasOwnProperty === 'function'" aimed to check whether the browser has the ".hasOwnProperty" method? – Penghan Yang Aug 21 '13 at 01:24
  • @PenghanYang that is correct - typeof operator will allow you to look through the scope of the object without breaking if the first level is undefined. For example, if you tried to say if(myObject.property) and myObject was undefined, you would get an error. But if you say, if(typeof myObject.property === 'string'), and myObject was not defined, you would just get a false in your if statement. – netpoetica Aug 21 '13 at 12:43
1

ok here i go...

function objProps(x){
var arr=[];
for (var k in x) if(typeof x[k] !='function' && x.hasOwnProperty(k)) {arr.push(k);}
return arr;
}

this code works as expected. call it with object...

get its only keys out that are NOT Functions.

Muhammad Umer
  • 17,263
  • 19
  • 97
  • 168
1

This is the solution:

function keys(obj) {
    var hasOwnProperty = Object.prototype.hasOwnProperty;

    var properties = [];

    for (var property in obj)
        if (hasOwnProperty.call(obj, property)
            && typeof obj[property] !== "function")
                properties.push(property);

    return properties;
}

Line by line the above code does the following:

  1. Create an empty array properties to hold the names of all the properties of obj.
  2. For each property property of obj do:
    1. If the property property belongs to obj and
    2. If obj[property] is not a function then:
      1. Add the property property to the properties array.
  3. Return the properties array.

See the demo: http://jsfiddle.net/qVgVn/

Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
  • Very deep explaination. Thank you so much! – Penghan Yang Aug 21 '13 at 05:02
  • @PenghanYang Check out http://stackoverflow.com/a/8159434/802397 so you can get an understanding of what Aadit is doing with hasOwnProperty.call - essentially, in some browsers (IE old), certain host objects will not have a hasOwnProperty function, even though it is available in the JS implementation. You can get it by calling it from global Object.prototype.hasOwnProperty and then using it with call() to apply it to the current object. – netpoetica Aug 21 '13 at 12:52
  • @Keith In addition any object which doesn't eventually inherit from `Object.prototype` will in all probability not have the `hasOwnProperty` method. For example objects created by calling `Object.create(null)` don't have the `hasOwnProperty` function. Also not to mention that people can override the `hasOwnProperty` method: `{ hasOwnProperty: function () { alert("Trolled ya!"); } }`. – Aadit M Shah Aug 21 '13 at 13:00