Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Permission denied to access property 'toString'

Tags:

javascript

I'm trying to find a generic way of getting the name of Constructors. My goal is to create a Convention over configuration framework for KnockoutJS

My idea is to iterate over all objects in the window and when I find the contructor i'm looking for then I can use the index to get the name of the contructor

The code sofar

(function() {
    constructors = {};
    window.findConstructorName = function(instance) {
        var constructor = instance.constructor;
        var name = constructors[constructor];
        if(name !== undefined) {
            return name;
        }

        var traversed = [];
        var nestedFind = function(root) {       
            if(typeof root == "function" || traversed[root]) {
                return       
            }

            traversed[root] = true;
            for(var index in root) {               
                if(root[index] == constructor) {
                    return index;
                }


                var found = nestedFind(root[index]);  
                if(found !== undefined) {
                    return found;
                }
            }
        }

        name = nestedFind(window);
        constructors[constructor] = name;
        return name;
    }
})();

var MyApp = {};
MyApp.Foo = function() {
};

var instance = new MyApp.Foo();
console.log(findConstructorName(instance));     

The problem is that I get a Permission denied to access property 'toString' Exception, and i cant even try catch so see which object is causing the problem

Fiddle http://jsfiddle.net/4ZwaV/

Final version in this fiddle http://jsfiddle.net/2Uvd5/8/

Check here for the embryo of my Convention over configuration plugin https://github.com/AndersMalmgren/Knockout.BindingConventions

like image 366
Anders Avatar asked Dec 13 '12 17:12

Anders


1 Answers

  • Edit2:

JSFiddle

This solves everything except for one thing: var MyApp = {}; doesn't add it to the window-object. Changing that to window.MyApp = {}; makes it completely working (even within an IFrame).


  • Edit1:

JSFiddle

Adding to the array by setting the key name requires the key name to be a string so Javascript will automatically call. toString() on your suggested keyname which will fail for certain objects. Instead use .push() to add elements of any type to an array and then .indexOf() to check if it already exists.

Do note that the jsFiddle still breaks because of being placed in an iframe. Opening it in a new tab solves that.


My previous answer (which proved to be invalid when I tried to verify it in your jsFiddle):

You need to check if the constructor is an exact Object. If it is then calling .toString() on it will cause a security exception which I found to be kinda hard to debug. Here's a function I use to get the type of an object in a var-dumper I use.

function GetTypeOfObject(obj) {
    if (obj.constructor === window.Object)
        return '[object]';
    else
        return obj.constructor.toString();
}
like image 187
Martijn Hols Avatar answered Oct 27 '22 23:10

Martijn Hols