console.log中的JavaScript对象输出
我想知道打印对象时console.log从何处获取构造函数的名称。另外,这实际上会对代码产生影响吗console.log中的JavaScript对象输出,javascript,class,new-operator,console.log,Javascript,Class,New Operator,Console.log,我想知道打印对象时console.log从何处获取构造函数的名称。另外,这实际上会对代码产生影响吗 function F() { this.test = 'ok'; } var f = new F(); console.log( f ); console.log(在Chrome中)的输出为: F{test:“ok”} console.log从哪里获得F{test…中的F 如果我将F.constructor、F.prototype和F.constructor更改为随机值,它仍会打印
function F() {
this.test = 'ok';
}
var f = new F();
console.log( f );
console.log(在Chrome中)的输出为:
F{test:“ok”}
console.log从哪里获得F{test…
中的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 );
输出仍然相同-F{test:“ok”}
这些信息是否只是由浏览器私下保存的,我的问题是它是否会以任何方式影响JavaScript代码?也就是说,在我重写构造函数的原型和构造函数属性之后,它会在比较或继承过程中爬升吗
更新
最初的目的是做以下事情
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"}`
如您所见,dev
outputsF{name:“johndoe”}
,这让我怀疑,如果我想与以这种方式构造的实例进行比较或继承,以后是否会遇到问题。更改F.prototype
将替换F
的内容,而不是名称。旧的prototype对象仍然存在,并且对它的引用存储在每个inst的内部取消旧的F
。您可以通过调用(已弃用)或进行检查
请注意,\uuuuuuuuuuuuuuuuuuuuuuuuuuuu>是一个访问器保护(内部是一个getter,而不是一个不动产),因此它无法更改。您创建了一个新的F实例,因此浏览器会打印该实例以帮助您跟踪日志记录。即使您更改了原型,您仍然需要创建一个新的“F”为了得到目标
function A () { something: 123 }
new A();
console.log result: A {}
new B();
console.log result: ReferenceError: B is not defined
object.constructor.name
是获取对象构造函数名称的另一种方法。这并不难,因为f最终是f的一个实例,范围解析的顺序(这个,原型,…)很明显:-)
例如,您可以运行此代码,您将看到在本例中,它将打印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
我可以为原始意图提出另一种方法吗?只使用不同的引用来代替原始对象是没有问题的,所以您可以这样做
function construct(constructor, args, context) { //lowercase, as it's a function, not a class
return new constructor(args);
}
这应该首先创建正确的对象,不需要交换任何原型。这并不能完全回答问题……问题是:即使是构件已被替换,原型已被更改,浏览器为什么知道对象的类型?啊,那么,误解了这个问题。虽然是y,但不会进行编辑你已经得到了一个答案,我觉得这很好地解释了这个问题。如果你改变了object.constructor
(这样做没问题,效果也不错),正如OP所做的:)您的回答导致了以下结论:F.prototype=G;F.constructor=G;
是不必要的…@JohannesH。是的,因为您正在创建一个新实例:var F=new F();
请参见F
?问题是:如果对F的所有引用都已更改,浏览器如何知道这一点。(当然答案是“他们没有”,但重点是:最后一个实例在哪里?).vbrowser不会解析源代码来查找对象的初始创建,类型确实可以在运行时确定。@RokoC.Buljan此代码和OPs代码之间的区别是:devlato也在更改f.prototype
(这确实改变了对象的类型),OP没有改变。@JohannesH通常情况下,如果您将var f
分配给一个对象,控制台将尝试显示引用函数名(+object)。否则OP希望执行的操作,即:console.log(f.fail)
?任何原因都不会返回未定义的注意\uuuu proto\uuuu
和Object.getPrototypeOf
规范中指向对象.setPrototypeOf的链接。该函数虽然受到Mozilla的支持,但被认为是实验性的,因此也不鼓励使用P已经更改了prototype对象F.prototype=G;
暂时忽略它。让我们改为更改F.prototype.constructor=G;
。现在object.getPrototypeOf(F).constructor
或F.\uu prototype\uu.constructor
也是G
。但是console.log(F)
仍然打印F
。因此,我不知道这篇文章如何回答这个问题。@YK1这可能取决于浏览器。使用当前版本的Firefox,更改\uuuu proto\uuu
会为我更改输出。对我来说,更重要的是在编程上将F
识别为G。如果是这样的话,但是console.log会打印出来作为F,这是唯一的警告,我会很高兴的。@JohannesH:我明白了,是的,在更改了F.prototype.constructor=G;
firebug打印G
,但是chrome开发工具仍然打印F
。我添加了另一个答案,它针对您遇到的原始问题,而不是试图让您的解决方案工作。问题现在构造函数将接收一个数组['John Doe'],而不是字符串'John Doe'。我知道我可以用typeof checks解释这一点,但我希望Person的构造函数使用相同的签名。