在什么时候原型Object出现在JavaScript中?

时间:2011-10-28 22:42:38

标签: javascript object prototype-programming

假设我有一个构造函数:

function Cat()
{
  this.tail = "long";
  this.colour = "black";
}

console.log(Cat.prototype); 
// returns an empty [object Object] with no properties (checked with `for...in` loop).

因此,此时Cat.prototype似乎没有tailcolour

var Charlie = new Cat();
console.log(Charlie.tail);

那么如果Charlie未在其原型中定义,Cat如何继承cat的属性。我假设原型对象的整个要点是镜像或存储将由Cat.prototype.eyes = brown的所有实例继承的构造函数的属性 - 这是错误的吗?

原型Object在什么时候填满了这些属性?或者只有在我明确设置for...in作为示例时才会发生这种情况?

此外,查询Object原型属性的正确方法是什么?它是Object.getOwnPropertyNames(Cat.prototype)循环吗?我想它不能是{{1}},因为它不会返回继承的属性。

5 个答案:

答案 0 :(得分:2)

您正在实例上直接定义tailcolour属性。 prototype对象上未定义这些属性。

顺便说一下,每个函数都有一个prototype属性,它是在创建函数本身时创建的。

答案 1 :(得分:1)

prototypethis完全分开。

this中的所有内容都不会被继承,prototype中的内容将会继承。 默认情况下,您继承自Object.prototype(为空)

function Cat()
{
  this.tail = "long";
  this.colour = "black";
}
Cat.prototype.getColour = function () {
  return this.colour;
}

WhiteCat.prototype = Cat.prototype;
WhiteCat.prototype.constructor = WhiteCat;

function WhiteCat(name){
  Cat.call(this);
  this.colour = "white";
}    

var c = new Cat();
console.log(c.getColour()); // "black"
var w = new WhiteCat();
console.log(w.getColour()); // "white"

答案 2 :(得分:1)

Javascript中的原型与您描述的原型略有不同。在这种情况下,Charlie确实有一个尾部,因为Charie是一个Cat,即他是Cat类Cat的实例。在Cat函数中,将tail属性添加到this.tail =行的所有猫。这完全是因为您使用Cat关键字调用了函数new。执行此操作时,javascript会创建一个新对象,然后使this指向该函数上下文中的该对象。

现在原型的工作方式不同,如果你去寻找一个对象中没有的属性或函数,它们最好被认为是一个链条。例如,如果尝试去:

Charlie.tickle_wiskers();

Javascript将在charlie对象中寻找名为tickle_wiskers的函数。如果它没有找到该函数,它将在Charlies原型中查找(如果未明确设置,则默认为Object.prototype)。最后,我可以通过这样的方式给所有猫起作用:

Cat.prototype.tickle_wiskers = function() { 
      alert('meow');
    }

答案 3 :(得分:0)

原型永远不会获得放在对象中的属性。该对象具有原型的成员,但原型没有该对象的成员。

对象不从原型继承任何东西,原型中的成员仍然只存在于原型中,它们只能从对象中访问。如果在创建对象后从protype中删除了某些内容,则无法再从该对象访问该成员。

函数具有prototype属性,当您使用new关键字将函数作为构造函数调用时,创建的对象将从函数中获取原型。

如果你在函数的原型中添加了一些东西,那么使用该函数创建的对象也可以访问它,即使你在将它添加到原型之前创建了它们:

function Cat() {}

var c = new Cat();

Cat.prototype.test = function() {
    alert('test');
};

c.test(); // alerts 'test'

答案 4 :(得分:0)

  

此外,查询Object原型属性的正确方法是什么?

var myProto = Object.getPrototypeOf(someObject);
var names = Object.getOwnPropertyNames(myProto);
names.forEach(function (name) {
  value = myProto[name];
  ...
});
  

或者只有在我明确设置Cat.prototype.eyes = brown作为示例时才会发生这种情况吗?

是的,仅在手动设置对象的[[Prototype]]时才设置属性。

但是,由于原型的每个“实例”都有一个指向原型对象的实时指针,因此这些更改将在创建对象后反映出来。

  

存储将由cat的所有实例继承的构造函数的属性?这是错误的吗?

我们不会在原型上存储对象的属性。我们存储我们想要在原型/构造函数的所有实例之间共享的属性(主要是方法)。