我试着把我的头绕在原型上,我很想知道原型到底是什么。很多混淆都是由于不理解用于描述原型的元语言而造成的。
以下是我所知道的:
当我们创建带有属性的命名构造函数时,该构造函数主体内的属性由该构造函数创建的对象实例继承。在这里,我从名为Person的构造函数创建了一个名为person001的实例。
function Person(firstName,lastName) {
this.firstName = firstName;
this.lastName = lastName
}
undefined
var person001 = new Person("John","Doe");当我查看控制台中的对象实例并跟踪原型链时,我发现它位于两个不同的位置。它是dunder对象的构造器对象.
Person {firstName: "John", lastName: "Doe"}
firstName: "John"
lastName: "Doe"
__proto__:
constructor: ƒ Person(firstName,lastName)
__proto__: Object以及原型对象在同一个构造函数对象中的一个属性。
Person {firstName: "John", lastName: "Doe"}
firstName: "John"
lastName: "Doe"
__proto__:
constructor: ƒ Person(firstName,lastName)
arguments: null
caller: null
length: 2
name: "Person"
prototype:
constructor: ƒ Person(firstName,lastName)
__proto__: Object
__proto__: ƒ ()
[[FunctionLocation]]: script.js:76
[[Scopes]]: Scopes[1]
__proto__: Object当我使用命名构造函数的.prototype属性添加属性时,我将该属性添加到prototype对象,而不是构造函数。添加的属性将位于prototype属性的对象中的构造函数旁边。这里,我使用构造函数Person的prototype属性添加了一个名为age的属性。
Person.prototype.age = 0; 现在我又添加了一个属性,那么原型到底是什么呢?
当我在对象实例person001上运行person001方法时,它会返回我认为类似于原型对象的内容。它有3个属性--一个构造函数、我添加的属性和隐式dunder对象。
Object.getPrototypeOf(person001);
{age: 0, constructor: ƒ}
age: 0
constructor: ƒ Person(firstName,lastName)
__proto__: Object 那么原型是什么呢?它是原型对象{构造函数,附加属性}吗?还是仅仅是原型对象的构造函数?
提前感谢您的协助。
发布于 2019-10-16 08:26:39
当你做obj = new Person时,游戏中有三个玩家:
新创建的对象obj
Person
Person.prototype下的特殊隐藏对象
它们之间的关系如下:
obj.__proto__ === Person.prototype
Person.prototype.constructor === Person说明:
function Person(firstName,lastName) {
this.firstName = firstName;
this.lastName = lastName
}
var person1 = new Person("John","Doe");
var person2 = new Person("Ann","Smith");
Person.prototype.age = 42;

发布于 2019-10-16 06:31:23
说您已经为一个人创建了一个构造函数,然后为其创建了两个实例:
const Person = function(name) {
this.name = name;
this.speak = () => console.log('My name is ' + this.name)
};
const john = new Person('John');
const mary = new Person('Mary');
john.speak();
mary.speak();
现在,您创建的每个人都有一个不同的名称,他们都可以使用这个名称,因为他们共享来自某个父对象的相同属性。
但玛丽不仅会说话。她会唱歌。但约翰不能。
const Person = function(name) {
this.name = name;
this.speak = () => console.log('My name is ' + this.name)
};
const john = new Person('John');
const mary = new Person('Mary');
john.speak();
mary.speak();
mary.sing = () => console.log('♪♪♪ Lalalalalala ♪♪♪');
mary.sing();
john.sing(); // John is such a bad singer, that this throws an error !
如果你后来意识到你的人不仅需要说话,而且还需要走路,那该怎么办?您需要引用他们的共同父母,以便告诉他们要一条龙地走。这就是原型。Mary和John都有一个共同的原型,并在内心深处引用了该原型(这是__proto__,供朋友和家人使用)。
const Person = function(name) {
this.name = name;
this.speak = () => console.log('My name is ' + this.name)
};
const john = new Person('John');
const mary = new Person('Mary');
john.speak();
mary.speak();
Person.prototype.walk = () => console.log('I am walking alright');
john.walk();
mary.walk();
// That is the same as:
john.__proto__.walk()
mary.__proto__.walk()
现在约翰摔倒了,走路也有困难。
const Person = function(name) {
this.name = name;
this.speak = () => console.log('My name is ' + this.name)
};
const john = new Person('John');
const mary = new Person('Mary');
john.speak();
mary.speak();
Person.prototype.walk = () => console.log('I am walking alright');
// John's infamous accident
john.walk = () => console.log('My leg hurts so bad...');
john.walk();
mary.walk();
实例有它自己的属性,我们使用它。
它没有,我们看看它的__proto__,如果它存在的话就使用它。
希望这能有所帮助!
发布于 2019-10-16 06:50:20
首先,原型只是一个对象。JS中的几乎所有对象(除了例如。当您使用Object.create(null))有一些原型和原型可以链接。
示例:当使用文字[]创建数组时,数组实例连接到对象(也是数组实例btw)。定义数组的属性(如map等),它本身连接到另一个原型(对象实例),该原型(对象实例)定义像toString这样的对象的属性。这些属性通常是函数。现在,当您访问像[].hasOwnProperty这样的对象的一个属性时,引擎会查找原型链来查找它。它从您的[]实例开始,没有找到它,继续到原型(数组),也没有成功,所以移到最后一个原型(对象实例),在那里它终于找到了。
正如您所看到的,prototype链总是在某个地方结束,所以如果您试图在链中的最后一个原型上检索原型,您将得到null。
现在回到构造函数。首先要注意的是,这些只是正常的函数-实例的实际“创建者”是关键字new。现在,每个函数都有一个prototype属性,它告诉您:使用该函数创建的每个对象都将得到原型--连接到函数的prototype属性中的任何内容。默认情况下,每个函数都在此属性中包含对象实例,这意味着您从该函数创建的每个对象都将是原型--连接到此实例,因此将“继承”类似于toString的属性。
在本例中,您可以看到函数的prototype属性与实例的原型之间的连接。
function A() {}
var a = new A();
a.__proto__ == A.prototype; // is true最后,函数的constructor属性的prototype属性告诉您,在使用带有new关键字的函数时,将使用哪个函数来创建新实例。这一口可归结为:
function A() {}
A == A.prototype.constructor; // is true这是对自身的一种引用。在ES6之前创建自己的继承链时,这个属性是可选的,但是为了正确起见还是这样做的。
那么什么是原型呢?它只是一个对象,通过一个特殊的原型连接连接到其他对象实例,使它能够访问预定义的属性。这是在JS中进行继承的一种方法。
https://stackoverflow.com/questions/58406799
复制相似问题