Is there a way to print all methods of an object? [duplicate] - javascript

This question already has answers here:
How to display all methods of an object?
(11 answers)
Closed 3 years ago.
Is there a way to print all methods of an object in JavaScript?

Sure:
function getMethods(obj) {
var result = [];
for (var id in obj) {
try {
if (typeof(obj[id]) == "function") {
result.push(id + ": " + obj[id].toString());
}
} catch (err) {
result.push(id + ": inaccessible");
}
}
return result;
}
Using it:
alert(getMethods(document).join("\n"));

If you just want to look what is inside an object, you can print all object's keys. Some of them can be variables, some - methods.
The method is not very accurate, however it's really quick:
console.log(Object.keys(obj));

Here is an ES6 sample.
// Get the Object's methods names:
function getMethodsNames(obj = this) {
return Object.keys(obj)
.filter((key) => typeof obj[key] === 'function');
}
// Get the Object's methods (functions):
function getMethods(obj = this) {
return Object.keys(obj)
.filter((key) => typeof obj[key] === 'function')
.map((key) => obj[key]);
}
obj = this is an ES6 default parameter, you can pass in an Object or it will default to this.
Object.keys returns an Array of the Object's own enumerable properties.
Over the window Object it will return [..., 'localStorage', ...'location'].
(param) => ... is an ES6 arrow function, it's a shorthand for
function(param) {
return ...
}
with an implicit return.
Array.filter creates a new array with all elements that pass the test (typeof obj[key] === 'function').
Array.map creates a new array with the results of calling a provided function on every element in this array (return obj[key]).

Take a gander at this code:-
function writeLn(s)
{
//your code to write a line to stdout
WScript.Echo(s)
}
function Base() {}
Base.prototype.methodA = function() {}
Base.prototype.attribA = "hello"
var derived = new Base()
derived.methodB = function() {}
derived.attribB = "world";
function getMethods(obj)
{
var retVal = {}
for (var candidate in obj)
{
if (typeof(obj[candidate]) == "function")
retVal[candidate] = {func: obj[candidate], inherited: !obj.hasOwnProperty(candidate)}
}
return retVal
}
var result = getMethods(derived)
for (var name in result)
{
writeLn(name + " is " + (result[name].inherited ? "" : "not") + " inherited")
}
The getMethod function returns the set of methods along with whether the method is one that has been inherited from a prototype.
Note that if you intend to use this on objects that are supplied from the context such as browser/DOM object then it won't work IE.

From here:
Example 1: This example writes out all the properties of the "navigator" object, plus their values:
for (var myprop in navigator){
document.write(myprop+": "+navigator[myprop]+"<br>")
}
Just replace 'navigator' with whatever object you are interested in and you should be good to go.
As mentioned by Anthony in the comments section - This returns all attributes not just methods as the question asked for.
Oops! That'll teach me to try and answer a question in a language I don't know. Still, I think the code is useful - just not what was required.

Since methods in JavaScript are just properties that are functions, the for..in loop will enumerate them with an exception - it won't enumerate built-in methods. As far as I know, there is no way to enumerate built-in methods. And you can't declare your own methods or properties on an object that aren't enumerable this way.

Related

Can object method have own propertis?

For function I can make this:
uniqueInteger.counter = 0;
function uniqueInteger() {
return uniqueInteger.counter++; // Increment and return counter property
}
Can I do this also with object method?
Yes, you can, because functions are first class objects:
In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called. In brief, they are Function objects.
var object = {
x: function () { return this.x.value; }
};
object.x.value = 42;
document.write(object.x());
Objects methods are functions. You can do this for any function:
var a = function () { }
a.bar = "f";
for(property in a) {
console.log(a[property]);
}
// outputs f
However, please note that "own property" has a specific meaning in javascript, to the point that it's highly recommended to check if a property is object's own property when iterating through the properties (e.g. to ignore inherited properties).
o = new Object();
o.prop = 'exists';
o.hasOwnProperty('prop'); // returns true
o.hasOwnProperty('toString'); // returns false
o.hasOwnProperty('hasOwnProperty'); // returns false

override object accessot javascript [duplicate]

This question already has answers here:
Is there an equivalent of the __noSuchMethod__ feature for properties, or a way to implement it in JS?
(6 answers)
Closed 7 years ago.
I would like to override accessor of a javascript object so that instead of override it should return a fixed value.
eg.
var obj = {};
console.log(obj.someProperty) //will print undefined expected value false
If a property is undefined there is no way to have it return false by default but it will be "falsey".
For example:
var obj = {};
if (!obj.someProperty) {
console.log("expression is falsey");
}
A more explicit way to test truthiness is to use the double bang operator:
var obj = {};
console.log(!!obj.someProperty) // print's undefined, but evaluates to false
But in short, what you are going after will not work because in JavaScript you cannot redefine undefined.
I would do this with the following:
var obj = {};
if (!obj.hasOwnProperty('itdoesnthavethis')) console.log('property is not there')
This will always return a boolean and will not check through the object's prototype chain for the property, just the object itself.
Read more here : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
With ES6 and its Proxy feature you can do something like this:
var obj = {};
obj = new Proxy(obj, {
get: function(target, prop) {
var pv = target[prop];
return pv === undefined ? false : pv;
}
});
that will essentially create proxy wrapper around your object handling property get operations.
With ES5 something like that is impossible to achieve for an arbitrary property.
But if set of properties is known you can design your own object class:
function MyObject() {}
MyObject.prototype.foo = false;
MyObject.prototype.bar = false;
MyObject.prototype.baz = false;
and use it as:
var obj = new MyObject();
console.log(obj.foo); // false
console.log(obj.bar); // false
console.log(obj.foobar); // undefined

How to iterate through functions defined in a javascript object

I have an object that defines a bunch of functions like this:
myObject = {
"item 1": function() {
return "I'm item 1";
},
"item 2": function() {
return "I'm item 2";
}
};
I want to write a function that calls all of the functions defined in this object without having to know the names of the functions or the number of functions. Is this possible?
In ECMAScript >=5.1 you can use the for .. in construct.
obj = {
test : function() {
console.log("test called");
}
};
for(idx in obj) {
obj[idx]();
}
You may want to check that the property is actually a function.
You can do this by first using a for-in loop to go through each of the objects properties. Then, after checking if the value is a function, you can call it.
for (var key in obj) {
if (typeof obj[key] === 'function') {
obj[key]();
}
}
You could either use Object.keys or a for-in loop depending on your needs.
Object.keys(obj); // ==> ["item-1", "item-2"]
Object.keys(obj).forEach(function (key) {
var fn = obj[key];
fn();
});
// or with a for-in loop
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
obj[key]();
}
}
Using Object.keys is arguably a bit more clear, but the for-in loop has better browser compatibility and possibly performance. For a more general comparison of object enumeration in JavaScript, refer to this question How do I enumerate the properties of a JavaScript object?.

Adding function to Object prototype causes function to show up in all 'for X in OBJ' loops

So, here's some sample javascript code:
Object.prototype.simpleFunction = function () {
return true;
}
var tempObject = {};
for (var temp in tempObject) {
console.log(temp);
}
Note that if you execute this, you'll get 'simpleFunction' output from the console.log commands in Google Chrome. (I'm using 19.0.1084.46m .)
However, the wide variety of related Object functions are not passed to the console.log.
How can I add functions onto the Object prototype without them showing up in my 'for property in object' loops?
Edit: I should have mentioned that the last thing I wanted was to throw another 'if' statement in there, as it'd mean I'd need to add it to ALL for loops. :(
Which is why you should always check hasOwnProperty:
for (var temp in tempObject) {
if (Object.prototype.hasOwnProperty(tempObject, temp)) {
console.log(temp);
}
}
Crockford advocates using Object.prototype.hasOwnProperty instead of tempObject.hasOwnProperty, just in case you override hasOwnProperty in your object.
In ES5, you can set it to not be enumerable:
Object.defineProperty(Object.prototype, 'simpleFunction', {
value: function() {
return true;
},
enumerable: false, // this is actually the default
});
Alternatively (in ES5), you can use Object.keys() to only get the object's own keys:
Object.keys(tempObject).forEach(function(key) {
console.log(key);
});
Do you mean something like:
for (var temp in tempObject) {
if (tempObject.hasOwnProperty(temp )) {
console.log(temp);
}
}
It's not possible to do this in javascript. You need to filter the results yourself. One potential method is to define your own prototype properties in another object:
var myObjectExt = {
sampleFunciton: function(){}
}
var p;
for(p in myObjectExt){
Object.prototype[p] = myObjectExt[p];
}
var obj = {};
for(p in obj){
if(myObjectExt[p])continue;
//do what you need
}
You can skip the inherited properties by doing this:
if (tempObject.hasOwnProperty(temp)) {
// property didn't come from the prototype chain
}
The bottom line is, you can't add functions to the prototype without having them being iterated using in.
You could define an external interface in which you always pass the object, e.g.
function simpleFunction(obj) {
}

Making primitive data types readOnly/nonConfig in JavaScript

Does anyone have any example implementation of making individual object props readOnly/non-configurable? I mean primitive data types. Have tried using ES5 Object API, but hitting a brick wall.
I can't show code, because it's still at that "messy" phase, but basically I'm iterating through an outside object which, itself, holds numeruos objects. Those objects each hold various primitive data types. I have made the outer objects readOnly, non-config, etc, but can't figure out how to do likewise for individual props, the innermost props.
So, if outer.inner.prop === "Hello", I want to make that value readOnly.
Thanks!
UPDATE
I just figured this out, it was all in the for loop I was using to iterate over props. Now I've actually get data descriptors for the props, even the primitive ones. :) Thanks all!
You have to iterate through the inner object, since there is no way to deep-freeze an object using standard ES5 methods.
function deepFreeze(obj) {
Object.keys(obj).forEach(function (key) {
if (typeof obj[key] == 'object')
deepFreeze(obj[key]);
});
Object.freeze(obj);
}
Edit:
Also works for defineProperty if you don't want to freeze:
function deepWriteProtect(obj) {
Object.keys(obj).forEach(function (key) {
if (typeof obj[key] == 'object')
deepWriteProtect(obj[key]);
Object.defineProperty(obj, key, { writable: false });
});
}
I'm not 100% sure I understand your question correctly, but from what I gather you are asking for private variables. If so, that can be easily achieved using closures.
function myClass(){
var mySecretProperty = 10;
this.getMySecretProperty = function(){
return mySecretProperty;
}
this.changeMySecretProperty = function(s){
// whatever logic you need for a setter method
mySecretProperty = s;
}
}
var myObj = new MyClass();
myObj.changeMySecretProperty(120);
myObj.getMySecretProperty(); // will return 120
myObj.mySecretProperty // will return undefined
Would the following (ES5) example help? It creates an empty constructor, with a getter for property a (and no setter, so de facto a is read only):
var Obj = function(){};
Obj.prototype = {
get a() {return 5;}
}
var x = new Obj;
alert(x.a); //=> 5
x.a = 6; //=> TypeError: setting a property that has only a getter
Not using ES5 you can do
var Obj = function(){
var a = 5;
if (!Obj.prototype.getA) {
Obj.prototype.getA = {
toString: function() {
return a;
}
};
}
}
var y = new Obj;
alert(y.getA); //=> 5
But that is not 100% failsafe: Obj.prototype.getA can be overwritten.
Here is a jsfiddle showing how you can use ES5 getter/setter definitions to make a property of an object something that can only be fetched. The code looks like this:
var object = {
get x() {
return 17;
}, set x() {
alert("You cannot set x!");
}
};
Of course the getter could obtain the value of the property ("x") from anywhere, like a closure from a constructor or something. The point is that the setter simply does not change the value, so attempts to change it:
object.x = 100;
will not have any effect.

Categories

Resources