Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 通过Object.setPrototypeOf()向函数的原型添加属性时,对象为空 让我们考虑下面的代码,_Javascript_Object_Prototype - Fatal编程技术网

Javascript 通过Object.setPrototypeOf()向函数的原型添加属性时,对象为空 让我们考虑下面的代码,

Javascript 通过Object.setPrototypeOf()向函数的原型添加属性时,对象为空 让我们考虑下面的代码,,javascript,object,prototype,Javascript,Object,Prototype,设f=函数(){ 这是a=1; 这是b=2; } 设o=新的f(); f、 原型c=3; log(Object.getPrototypeOf(o))当您Object.setPrototypeOf(f,…)时,链实际上是3长: o的原型是f。f的原型是{c:3} 因此,你们的例子并不完全相同: 1) 在第一个示例中,您将属性c直接添加到f实例将使用的原型中,因此o的原型包含c,因为f是o的构造函数 在最后两个示例中,您将c添加到f的proto中,因此使用创建了原型f。请记住,函数也只是对象,您正在

设f=函数(){
这是a=1;
这是b=2;
}
设o=新的f();
f、 原型c=3;

log(Object.getPrototypeOf(o))
当您
Object.setPrototypeOf(f,…)
时,链实际上是3长:

o
的原型是
f
f
的原型是
{c:3}

因此,你们的例子并不完全相同:

1) 在第一个示例中,您将属性
c
直接添加到
f
实例将使用的原型中,因此
o
的原型包含
c
,因为
f
o
的构造函数

在最后两个示例中,您将
c
添加到
f
的proto中,因此使用创建了原型
f
。请记住,函数也只是对象,您正在设置用作构造函数的函数的原型。因此
o
的proto包含
f
的proto,其中包含
c

2) 在第二个示例中,您获取prototypeof()
o
。 在第三步中,您将获得prototypeof()
f
。因此,只有第三个示例再次显示
c

3) 如果您检查chrome中的元素,您会看到第二个示例的构造函数是
f
,因为您询问
o
的proto

在第三个示例中,您将看到构造函数是
Object
,因为您询问
f
的proto,它已设置为Object
{c}
,并将proto从
o
跳过
f

我知道这可能是一个令人困惑的解释

PPS:如果您想要继承,请坚持使用
child.prototype=Object.create(parent.prototype);child.constructor=child
或ES6 class
class child扩展父级
时,可以使用它将我个人的困惑降至最低

var first=函数first(){
this.value='第一个函数';
};
//before.prototype.extra,函数的第一个inherist。
log('first-before的构造函数:',first.constructor);
first.prototype.extra='使用.prototype.extra'实现;
//在.prototype.extra之后,first仍然从函数继承,我们没有将任何内容更改为first本身。
log('first after:'的构造函数,first.constructor);
//当第一个被用作原型时,实例将得到“额外的”。
//阿卡,一切从一开始就是天生的。
var first_instance=new first();
log('extra on instance of first:',first_instance.extra);
//f本身没有额外的属性,只有first do的实例。
log('extra on first本身:',first.extra);
console.log('----');
var second=函数second(){
this.value='第二个函数';
};
//在setPrototypeOf之前,函数的第二个inherist,如上所示。
log('console.constructor of second before:',second.constructor);
setPrototypeOf(第二个,{extra:'用.setPrototypeOf()实现);
//在对象的第二个inherist setPrototypeOf之后,我们打破了默认的继承链。
log('console.constructor of second after:',second.constructor);
//通过这样做,我们有效地将秒变成了一个对象。
//它不再是函数,因此我们不能使用.call()或.apply()等函数方法
log('second是对象,而不是函数:function.apply',second.apply);
log('second是object,而不是function:object.hasOwnProperty',second.hasOwnProperty');
//当第二个被用作原型时,实例将不会得到“额外的”。
var second_instance=new second();
log('extra on instance of second:',second_instance.extra);
//second本身确实有额外的属性,因为我们在second使用的原型上分配了它。当使用second作为原型时,则不会。

log('extra on second本身:',second.extra)obj={}
然后是
obj.foo=1
obj={bar:2}
,则代码>没有太大区别。您正在修改现有对象或替换它
o
维护对原始的引用。因此,就添加原型的这两种方式(setPrototypeOf和.prototype)而言,它有什么区别呢?我在回答中对此进行了扩展,但假设上面的代码有
obj2=obj
。如果您执行
obj.foo=1
操作,您就是在“更改”
obj2
,因为它实际上只是对同一对象的新引用。但是
obj={bar:2}
将保持
obj2
不变,因为现在
obj
obj2
指向不同的对象。哇,我不知道obj={}语法不会修改另一个对象,我知道对象。assign()和用于复制的扩展运算符,但是,请不要阅读这种使对象保持不变的方法,谢谢,现在让我再看看代码。我仍在尝试将其与设置原型的这两种方法联系起来。我遇到的另一件事是,在执行setPrototypeOf()时,它替换了完整的原型属性,其中as.prototype可以添加到它上,这里我可以将您关于引用和复制的解释联系起来感谢您的解释,我会慢慢地看一遍,然后再给你回复。:)在你的句子中我有点困惑,“在第一个例子中,你将属性c直接添加到f实例将使用的原型中”我的假设是setPrototypeOf(f)和f.prototype都将用一些属性设置该函数的原型。是的,我编辑了该行5次。:/这是很难解释的部分
f
o
的原型。但是
f
也有一个原型,因为它是一个对象。setPrototypeOf()将设置
f
的原型。因此,
f
的原型就是用它创建的<代码>o
但是,未创建