Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/412.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 为什么要替换构造函数';s的原型是否反映在对象中?_Javascript - Fatal编程技术网

Javascript 为什么要替换构造函数';s的原型是否反映在对象中?

Javascript 为什么要替换构造函数';s的原型是否反映在对象中?,javascript,Javascript,如果我只使用obj.prototype.property=val,一切都会正常,代码如下 function animal() {} var frog = new animal(); animal.prototype.color = 'Green'; console.log(frog.color); // 'Green' function animal() {} var frog = new animal(); animal.prototype = { color: 'Green' };

如果我只使用obj.prototype.property=val,一切都会正常,代码如下

function animal() {}
var frog = new animal();
animal.prototype.color = 'Green';
console.log(frog.color);
// 'Green'
function animal() {}
var frog = new animal();
animal.prototype = {
    color: 'Green'
};
console.log(frog.color);
// 'undefined' -- why?
但是,如果我在new关键字之后使用
obj.prototype={key:val}
,它将给我一个
未定义的
,代码如下

function animal() {}
var frog = new animal();
animal.prototype.color = 'Green';
console.log(frog.color);
// 'Green'
function animal() {}
var frog = new animal();
animal.prototype = {
    color: 'Green'
};
console.log(frog.color);
// 'undefined' -- why?
如果我改变让原型出现在新关键字之前的顺序,那就没问题了,这么奇怪,为什么?因为我们知道一个对象的原型允许我们向该对象的所有实例(甚至是现有实例)添加属性,对吗

代码式

function animal() {}
var frog = new animal();
animal.prototype.color = 'Green';
console.log(frog.color);
// 'Green'
function animal() {}
var frog = new animal();
animal.prototype = {
    color: 'Green'
};
console.log(frog.color);
// 'undefined' -- why?
function animal() {}
animal.prototype = {
    color: 'Green'
};
var frog = new animal();
console.log(frog.color);
// 'Green'

因为您正在指定一个全新的对象
prototype
不是对象的
[[prototype]]
<代码>新建使用此属性设置内部属性。因此,对
new
使用的
prototype
对象的引用与稍后指定的对象不同。您不应该覆盖
prototype
属性,而应该始终扩展它,如第一个示例中所示:

function Animal(){}
var frog = new Animal();
Animal.prototype.color = 'green';
console.log(frog.color); // green

使用
new
关键字创建新对象时,新创建对象的内部
[[Property]]
对象将设置为构造函数的原型对象

function animal() {}
var frog = new animal();

console.log(Object.getPrototypeOf(frog) === animal.prototype);
# true

animal.prototype = {
    color: 'Green'
};

console.log(Object.getPrototypeOf(frog) === animal.prototype);
# false

console.log(frog.color);
在第一个
控制台.log
中,它打印
true
,因为
new
已将
动物的
原型
对象设置为
青蛙的内部
[[prototype]]
对象。但是,当您为
动物
原型
指定其他对象时,
青蛙
的内部
[[prototype]]
对象仍然引用旧对象,该对象没有
颜色
属性。这就是它打印未定义的
的原因

当您更改顺序时,当遇到
new
语句时,它将获取
animal
prototype
对象(即您指定的新对象),并创建
frog
对象。这就是为什么它具有
color
属性

现在,你可能想知道为什么第一个案例效果很好。因为

animal.prototype.color = 'Green';

不是用其他对象替换
animal.prototype
,而是对
animal.prototype
对象进行变异(或扩充,如果您愿意的话)。因此,
frog
的内部
[[Prototype]]
属性仍然与
animal.Prototype
对象相同。

因为如果您首先分配一个新的
Prototype
对象,那么
new
将抓取该新对象。如果您稍后再做,那么就太晚了,
new
已经使用了函数默认具有的
prototype
属性。thx White先生,您说不应该覆盖原型吗?但是将a{}分配给prototype是非常方便的,如果不方便,我将再次制作prototype.a,prototype.b,但这不是为了方便,而是为了效果,正如您所看到的。您可以做的是
extend(Animal.prototype,{color:'green'})
并从npm获取
extend
,或下划线或其他内容。以下答案的可能重复可能有助于您理解原型和构造函数的作用。您的问题已经得到了回答,但是在原型上添加一个实例特定的属性表明您可能不理解原型是什么:非常感谢,您编辑我的帖子真是太好了,谢谢。