繁体   English   中英

JavaScript:如何访问构造函数的原型?

[英]JavaScript: how to access the prototype of a constructor function?

可能对JS专家和忍者有愚蠢的问题,但这里有:

我对原型对象/对象属性的理解是,它是对象将来实例的蓝图。 鉴于此,一个对象的新创建实例是否应该与创建该对象的构造方法对象完全不同?

var x = new Object(); 
console.log(x === Object.prototype); // returns false. why?? 

*更新*

因此,理解到由于它们引用不同的东西而将返回false,我仍然发现new Object()和Object.prototype包含不同数量的属性。 因此,请提出以下问题:如何正确检查原型对象中的属性数量; 我如何遍历它们?

我对此感到困惑的原因是,如果我创建一个简单的构造函数:

function Circle(){
   this.tail = "yes, has tail";
}

并想要获取其拥有的属性数量,请执行以下操作:

console.log(Object.getOwnPropertyNames(Circle.prototype)); 
// returns "constructor", I expected it to return "tail"

===不能回答两个事物是否相等的问题,而是它们是否是对同一对象的引用。

您的示例中的xObject.prototype可能具有相同的属性,因此可以将它们称为等效属性,但是它们是两个不同的对象。

如果你这样做

x.foo = 3

它们现在不再等效,因为它们是两个不同的对象。 您更改了一个,但没有更改。

如果

x === Object.prototype

是真的,然后

x.foo === Object.prototype.foo

无论您为x.fooObject.prototype.foo分配什么,它都是相同的。

编辑:

 function Circle(){ this.tail = "yes, has tail"; } console.log(Object.getOwnPropertyNames(Circle.prototype)); // returns "constructor", I expected it to return "tail" 

Circle.prototype没有tail属性,因为您从未做过Circle.prototype.tail = ...; 您只能通过this.tail = ...;Circle 实例上定义tail this.tail = ...;

我仍然发现new Object()Object.prototype包含不同数量的属性。

您也在做getOwnPropertyNames 自己的属性是那些不是从原型继承属性,因此通过在x上使用该函数,您将明确排除Object.prototype所有属性。

hasOwnProperty的文档很好地解释了“拥有的财产”:

此方法可用于确定对象是否具有指定属性作为该对象的直接属性; in运算符不同,此方法不会检查对象的原型链。

console.log(Object.getPrototypeOf(x) === Object.prototype); // true

如果要获取指向对象原型链中下一个元素的隐藏属性[[Prototype]] ,请调用Object.getPrototypeOf

您还会误解原型链的工作原理。

对于任何给定的对象,如果您查找属性,它将首先查看该对象。 然后,它将(递归)查看对象[[Prototype]]值是否具有该属性。

原型链示例:

var o = new Object();
// o -> Object.prototype -> null
var a = new Array();
// a -> Array.prototype -> Object.prototype -> null
var Super = function () {};
var Child = function () {};
Child.prototype = Object.create(Super.prototype);
var c = new Child();
// c -> Child.prototype -> Super.prototype -> Object.prototype -> null

x是“对象”的实例。 您可能想检查x是否有一个Object作为构造函数。 原型不是构造函数。 尝试这个

var x = new Object(); 
console.log(x.constructor === Object);

关于您的更新:

this构造函数内与创建的实例new关键字,而不是prototype

因此,就您的摘要而言...

function Circle(){
   this.tail = "yes, has tail";
}

设置this.tail类似于:

var c = new Circle();
c.tail = "yes, has tail";

tail 只是实例的属性。

要在prototype上设置tail ,必须使用:

Circle.prototype.tail = "yes, has tail";

现在,“ Own”属性是直接在实例上设置的那些属性。 这些计数器和重写具有相同名称的prototype属性:

function Circle() {
    // give the instance its "own" `foo` property
    this.foo = 'qux';
}

Circle.prototype.foo = 'foo';
Circle.prototype.bar = 'bar';

var c = new Circle();

console.log(c.foo); // the overridden "qux", not the inherited "foo"
console.log(c.bar); // "bar", as inherited

// yet the prototype still persists to have its "own" `foo`
console.log(Circle.prototype.foo); // "foo"

// While the instance has keys for all involved properties
console.log(Object.keys(c)); // [ "foo", "bar" ]

// It also retains which are its "own"
console.log(Object.getOwnPropertyNames(c)); // [ "foo" ]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM