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
JavaScript object output in console.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 F
in F {test...
?
console.log 在哪里F
输入F {test...
?
If I change F.constructor
, F.prototype
, and f.constructor
to 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 prototype
and constructor
properties?
这些信息是否只是由浏览器保密,我的问题是它是否以任何方式影响 JavaScript 代码?也就是说,在我覆盖构造函数prototype
和constructor
属性之后,它会在比较或继承过程中蔓延吗?
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.
如您所见,dev
输出的结果打印F {name: "John Doe"}
,这让我怀疑如果我想与以这种方式构造的实例进行比较或继承,我是否会遇到问题。
采纳答案by Johannes H.
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)
.
更改会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.name
is another way of getting the name of an object constructor.
object.constructor.name
是另一种获取对象构造函数名称的方法。