console.log 中的 JavaScript 对象输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21590205/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 21:15:29  来源:igfitidea点击:

JavaScript object output in console.log

javascriptclassnew-operatorconsole.log

提问by Vadym

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?

我想知道打印对象时console.log从哪里得到构造函数的名字。此外,这实际上会影响代码明智吗?

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

var f = new F();

console.log( f );

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

console.log(在 Chrome 中)的输出是: F {test: "ok"}

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

console.log 在哪里F输入F {test...

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

如果我将F.constructor,F.prototype和更改f.constructor为随机内容,它仍会打印原始内容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"}

输出还是一样的—— 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 prototypeand constructorproperties?

这些信息是否只是由浏览器保密,我的问题是它是否以任何方式影响 JavaScript 代码?也就是说,在我覆盖构造函数prototypeconstructor属性之后,它会在比较或继承过程中蔓延吗?

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 devoutputs 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.

如您所见,dev输出的结果打印F {name: "John Doe"},这让我怀疑如果我想与以这种方式构造的实例进行比较或继承,我是否会遇到问题。

采纳答案by Johannes H.

Changing F.prototypereplaces 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).

更改会F.prototype替换 的内容F,而不是名称。旧的原型对象仍然存在,并且对它的引用存储在旧的每个实例内部F。您可以通过调用f.__proto__'(已弃用)或 来检查它Object.getPrototypeOf(f)

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

请注意,这__proto__是一个访问器属性(在内部是一个 getter,而不是一个真正的属性),所以它不能被更改。

回答by devlato

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

这并不难,因为 f 最终是 F 的一个实例,并且范围解析的顺序(this、prototype、...)很明显:-)

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

例如,您可以运行此代码,您将看到在这种情况下它将打印 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

回答by Johannes H.

May I suggest another approach for the original intention? There is no problem with just using a different reference to the prototype object instead of the original one, so you can do

我可以建议另一种方法来实现初衷吗?使用对原型对象的不同引用而不是原始引用没有问题,因此您可以这样做

function construct(constructor, args, context) { //lowercase, as it's a function, not a class
    return new constructor(args);
}

This should create the right object in the first place, no need to swap any prototypes.

这应该首先创建正确的对象,无需交换任何原型。

回答by Index

Your creating a new instance of F, so the browser prints that in order to help you keep track of your logging. Even though you change the prototype would you still have to create a new "F" in order to get the object.

您创建了 F 的新实例,因此浏览器会打印该实例以帮助您跟踪日志记录。即使您更改了原型,您仍然必须创建一个新的“F”才能获取对象。

function A () { something: 123 }
new A();
console.log result: A {}
new B();
console.log result: ReferenceError: B is not defined

回答by Gabriel

object.constructor.nameis another way of getting the name of an object constructor.

object.constructor.name是另一种获取对象构造函数名称的方法。