Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript object output in console.log

I want to know from where does console.log get the name of the constructing function when printing an object. Also, does that actually effect anything code wise?

function F() { 
    this.test = 'ok';
}

var f = new F();

console.log( f );

The output of console.log (in Chrome) is: F {test: "ok"}

Where does the console.log get the F in F {test...?

If I change F.constructor, F.prototype, and f.constructor to something random, it still prints the original F:

function G() {
    this.fail = 'bad';
}

function F() { 
    this.test = 'ok';
}

F.prototype = G;
F.constructor = G;

var f = new F();

console.log( f );

The output is still the same - F {test: "ok"}

Is this information is simply kept privately by the browser, my question is does it affect JavaScript code in any way? That is, will it creep up during comparison or inheritance, after I override the constructor's prototype and constructor properties?

UPDATE

The original purpose was to do the following.

function Person ( _name ) {
    this.name = _name;
}

function Construct( _constructor, _args, _context ) {
    function F () {
        var context = _context || this;
        return _constructor.apply( context, _args );
    }

    /* I want to have the constructed object by identified 
       as _constructor and not a F */
    F.prototype = _constructor.prototype;

    return new F();
}

function Make ( _who ) {
    if ( 'person' === _who ) {
        /* Remove the first argument, who, and pass along all the rest.
           Constructors cannot be called with .apply so I have to use 
           this technique. */
        return Construct( Person, Array.prototype.slice.call( arguments, 1 ) );
    }
}

var dev = Make( 'person', 'John Doe' );

console.log( dev ); // prints `F {name: "John Doe"}`

As you can see, the resulting print of dev outputs F {name: "John Doe"}, which made me question whether I may run into problems later on if I'd like to make comparisons or inheritance with instances constructed in such a way.

like image 500
Vadym Avatar asked Feb 05 '14 22:02

Vadym


2 Answers

Changing F.prototype replaces the content of F, not the name. The old prototype object still exists and a reference to it is stored internally in each instance of the old F. You cam check it by calling f.__proto__´ (deprecated) or Object.getPrototypeOf(f).

Note that __proto__ is an accessor proterty (internally a getter, not a real property), so it cannot be changed.

like image 78
Johannes H. Avatar answered Sep 28 '22 19:09

Johannes H.


It's not difficult, because f is finally an instance of F and the order of scope resolving (this, prototype, ...) is obvious :-)

For example, you can run this code and you'll see that in this case it will print G:

function G() {
    this.fail = 'bad';
}

function F() { 
    this.test = 'ok';
}

F.prototype = G;
F.constructor = G;

var f = new F();  // Prints F

console.log(f);

f.prototype = G;  // Redefining f type info
f.constructor = G;

console.log(f);  // Prints G
like image 41
devlato Avatar answered Sep 28 '22 20:09

devlato