JavaScript原型 - 困惑

时间:2016-04-26 21:05:26

标签: javascript oop properties prototype

我现在正在研究原型并认为我几乎就在那里,但我对一个主题感到有些困惑。

假设我们有:

function Animal(name, gender) {
  this.name = name;
  this.gender = gender;
}

function Cat(species) {
  this.species = species;
}

Cat.prototype.color = null;

Cat.prototype = new Animal();

我的问题是,为什么新属性需要prototype

为什么我们不能这样做:

Cat.color = null;

修改::

JS Heirarchy map

所有白色块都来自另一个SO帖子的uml图。我添加了橙色框以适应我提供的这个例子。我添加的这个图表是否仍然有意义?

我认为我的主要问题是我正在使函数构造函数和实际原型对象过于相似,而实际上它们是完全不同的东西。一个是功能,一个是对象。

编辑2

Revised Diagram 2

通过此图表,我试图澄清constructor属性如何与其进行交互以及它与之相关联的内容,更具体地说,它如何影响this的使用。对有效性的任何评论都会有所帮助。

3 个答案:

答案 0 :(得分:2)

好问题:

Cat.color = null;仅在Cat上设置颜色,如果您将其放在prototype任何'Cat'之后,您实例化之后也将包含color属性。

假设您有var tabby = new Cat('feline')之类的内容,而prototype tabby没有color

答案 1 :(得分:1)

要提醒的几件事情;

  1. 构造函数用于实例化新对象。如果构造函数具有使用前面的this.关键字定义的变量,那么这些将是实例化对象的属性。使用前面的var关键字定义的变量不是实例化对象的一部分。
  2. 由构造函数实例化的对象将其原型分配给构造函数的原型,因此它们可以直接访问构造函数的原型。这意味着他们可以在构造函数的原型中使用(共享)属性和函数,就好像它们是自己的一样。
  3. 当您考虑从构造函数实例化数千个对象时,原型非常有用。应该在构造函数中使用前面的this.定义每个对象的唯一属性,例如name,id,color或其他任何属性。例如this.namethis.color但是它们应该共享的功能应该在构造函数原型中定义,因为显然在每个实例化对象中为它们保留空间会浪费内存。 / LI>

答案 2 :(得分:1)

“Javascript中的所有内容都是对象”

有没有想过为什么你可以使用library(raster) library(gdalUtils) lon_vec <- rep(seq(-180,150,30),5) lat_vec <- sort(rep(seq(90,-30,-30),12), decreasing=T) #Download Worldclim Data and export as Tif for(i in 1:length(lon_vec)) { ras <- getData('worldclim', var='bio', res=0.5, lon=lon_vec[i], lat=lat_vec[i]) writeRaster(ras, filename=paste0("YourSubfolder/worldclim_lon_",lon_vec[i],"lat_",lat_vec[i],".tif")) } #Create list with all exported .tif iles ras_lst <- list.files("YourSubfolder/",full.names=T, pattern=".tif$") #Build virtual raster mosaic gdalbuildvrt(ras_lst, "YourSubfolder/worldclimMosaic.vrt") #Load virtual mosaic into R climatemosaic <- stack("YourSubfolder/worldclimMosaic.vrt") #Extract Mean Values gadmMEANS <- extract(climatemosaic, gadm, fun=mean, na.rm=TRUE, small=TRUE, layer=1, nl=19, sp=TRUE) 代表数字50而不写.toString()

因为它内置于Javascript中。所有Number.prototypes都有Number.toString = function(){....?方法。这个列表继续用于数组,对象,字符串等。

每次在JS中编写一个数字时,想象(没有真正调用构造函数)调用一个Number构造函数,类似于Animal&amp;的构造函数。猫。

这就是构造函数的作用。他们创建了(itsname).prototype的实例。这就是.toString制作function Animal()等内容的原因。

Animal.prototypefunction Animal()否则与function Cat()Animal.prototype无关。如果您实际使用Cat.prototype创建了一个新动物,然后更改了构造函数,则您刚制作的新动物将不会更新,因为它是在构造函数更改之前构造的。

假设您制作了new Animal()“霍布斯”

然后,当你说Cat时,你说Cat.prototype的所有对象都应该有一个'null'颜色值。这将更新你之前构建的Cats,因为现在当你试图找到Hobbe的颜色时,它会吐出Cat.prototype.color = null;,因为你没有在undefined给Hobbes自己的颜色,但是JS会回溯到Hobbe的function Cat()并发现该颜色实际上是Cat.prototype

希望有所帮助。