gpt4 book ai didi

Javascript原型(prototype)和调用之间的区别

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:47:33 25 4
gpt4 key购买 nike

我正在学习javascript并感到困惑。 here 上的示例其中有如下示例: -

// define the Person Class
function Person() {}

Person.prototype.walk = function(){
alert ('I am walking!');
};
Person.prototype.sayHello = function(){
alert ('hello');
};

// define the Student class
function Student() {
// Call the parent constructor
Person.call(this);// <---- Confusion
}

// inherit Person
Student.prototype = new Person(); //<---- Confusion

// correct the constructor pointer because it points to Person
Student.prototype.constructor = Student;

// replace the sayHello method
Student.prototype.sayHello = function(){
alert('hi, I am a student');
}

// add sayGoodBye method
Student.prototype.sayGoodBye = function(){
alert('goodBye');
}

var student1 = new Student();
student1.sayHello();
student1.walk();
student1.sayGoodBye();

// check inheritance
alert(student1 instanceof Person); // true
alert(student1 instanceof Student); // true

现在,我对这两行感到困惑( <---- )。当我说 Person.call(this); ,这只是说明继承 Person 类的属性......对吗?

那么这是在做什么呢?
  // inherit Person
Student.prototype = new Person(); //<---- Confusion

据我所知, .prototype还继承所有属性?

最佳答案

为了解释它,首先让我们记住构造函数在 JavaScript 中是如何工作的:

function Guide(a) {
this.a = a;
}
Guide.prototype.q = "Life, the Universe, and Everything";

var g = new Guide(42);
console.log(g.q); // "Life, the Universe, and Everything"
console.log(g.a); // 42

当我们做 new Guide(42) , new运算符创建一个新对象并使用 Guide.prototype 为其分配一个原型(prototype)。属性(property)。然后 new来电 Guide ,将该新对象作为 this 传入. Guide使用 this向新对象添加不在其原型(prototype)上的属性。然后 new表达式完成,其结果是它创建的新对象。

当我们查看 g.q , 因为 g对象没有自己的名为 q 的属性,JavaScript 引擎查看 g的原型(prototype),它(再次)在创建时被分配。该原型(prototype)具有 q属性,因此引擎使用它的值。

相比之下,当我们查看 g.a , g对象有自己的属性,称为 a ,因此直接使用该值。

有了这个基础,我们来看看 StudentParent :
function Student() {
// Call the parent constructor
Person.call(this);// <---- Confusion
}

当我们调用 new Student() ,在对 Student 的调用中, this是(再次)由 new 创建的新对象运算符,具有 Student.prototype作为其底层原型(prototype)。但是 Parent函数没有机会对这个新对象做任何事情。所以那条线的作用是给 Parent有机会对通过原型(prototype)无法做到的新对象做任何需要做的事情,比如我们的 Guide之前分配给 this.a 的函数.在技​​术方面, Parent.call(this);调用 Parent功能,确保 this调用 Parent是传递给 call 的值(在这种情况下,就是对 this 的调用的 Student ——例如,新对象)。如果你熟悉基于类的语言,这就像做 super(); (那是 Java,但你明白了)在派生构造函数中:它为基构造函数提供了初始化对象的机会。
// inherit Person
Student.prototype = new Person(); //<---- Confusion

由于 Student应该继承自 Person ,该代码所做的是创建原型(prototype),该原型(prototype)将分配给通过 new Student 创建的对象.它创建的对象是 Person目的。

FWIW,该代码没有完全正确地实现构造链(它调用 Person 比它应该更频繁[创建 Student.prototype 时调用 Student 时],并且未能设置 constructor)。

更正确的创建方法 Studentprototype属性,如果我们要调用 Parent来自 Student ,看起来像这样:
function derive(child, parent) {
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor();
}

derive(Student, Parent);

这样,我们就得到了一个基于 Parent.prototype 的原型(prototype)。但没有调用 Parent .这是一个非此即彼的选择:要么调用 Parent创建 Student.prototype , 或调用 ParentStudent 内,但不要两者都做。使用构造函数构建层次结构时,通常希望从子构造函数调用父级,而不是在创建子原型(prototype)时。当使用直接对象继承(没有构造函数)时,当然你用另一种方式。

如果您对 JavaScript 中的继承感兴趣,我编写了一个名为 Lineage 的帮助脚本。你可能想看看,特别是即使你不使用 Lineage , this discussion在其 wiki 页面上可能有助于理解继承层次结构。

关于Javascript原型(prototype)和调用之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19631180/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com