Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript-理解Object.create和Object.call(this)_Javascript_Inheritance - Fatal编程技术网

Javascript-理解Object.create和Object.call(this)

Javascript-理解Object.create和Object.call(this),javascript,inheritance,Javascript,Inheritance,我正试图完全掌握Object.create上的MDN文档,但我还有几个问题没有解决 以下是MDN提供的示例代码 function Shape() { this.x = 0; this.y = 0; } // superclass method Shape.prototype.move = function(x, y) { this.x += x; this.y += y; console.info("Shape moved."); }; // Rectangl

我正试图完全掌握Object.create上的MDN文档,但我还有几个问题没有解决

以下是MDN提供的示例代码

function Shape() {
  this.x = 0;
  this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

// Rectangle - subclass
function Rectangle() {
  Shape.call(this); // call super constructor.
}

// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();
我不懂的一句话是形状。叫(这个)。我已经查找了Object.call(这个),但找不到任何关于它的文档。这行代码在做什么

同样,这一行:Rectangle.prototype.constructor=Rectangle;将构造函数设置为矩形有什么好处

最后,为什么有人要实现使用Object.create()而不是这样做:

Rectangle.prototype = new Shape()
谢谢

.call()
是所有函数对象上的方法<代码>形状是一个函数,因此它具有该方法。
.call()的文档

代码
Shape.call(this)
表示调用Shape函数,当您调用它时,使该函数的
this
指针指向this的当前值。

这行代码的目的是调用基本对象的构造函数

function Rectangle() {
  Shape.call(this);
}

设置此选项:

 Rectangle.prototype.constructor = Rectangle
对象存储创建它的构造函数的位置。其他代码可以使用它来调用这个类的构造函数,当尝试从它继承时,当尝试创建这个类型的另一个对象时(不知道它是什么类型-假设它不需要任何参数),以及类似的各种函数



Object.create()
有许多用途,但在您的特定代码示例中,它用于创建一个新对象,该对象具有特定对象的原型,该原型对继承非常有用。您可以阅读更多信息。

这是一种面向对象的结构,因此在开始之前您应该了解OOP。如果你已经这么做了,让我解释一下发生了什么:

您正在创建的矩形“类”继承了形状“类”

因此,函数Rectangle调用Shape构造函数,然后Rectangle类将属性x和y初始化为0,与Shape类完全相同

行“Rectangle.prototype.constructor=Rectangle;”仅声明矩形类构造函数就是您刚才声明的函数

因此,在开发矩形的新实例时,您将编写以下代码:

var myRectangle = new Rectangle();
当您这样做时,它将调用矩形构造函数,它将自动调用矩形函数,这个函数将调用形状构造函数,然后您的矩形对象将具有属性x和y

试着在浏览器中调试一下,你就会明白我在说什么了

在,C#中,等效代码如下所示:

public class Shape
{
    public int X { get; set; }
    public int Y { get; set; }

    public Shape()
    {
        this.X = 0;
        this.Y = 0;
    }

    public void Move(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }
}

public class Rectangle : Shape // inherits the class Shape
{
    public Rectangle() : base() // inherits the Rectangles constructor from Shape's constructor
    {

    }
}

由于Javascript不是一种原生的面向对象编程语言,您需要进行这些“黑客”来创建“类”(我一直在使用引号,因为它只是一个类的模拟),并进行其他黑客操作来继承这些类等。

当函数执行时,
this
关键字指向上下文-调用函数的对象。
的值可以使用
函数.prototype上的call()或apply()方法显式指定。这些函数有2个参数;第一个是对象,它将成为
this
的值。使用call()或apply()时,将使用参数对象作为上下文调用函数(函数作为对象的方法调用)

您还需要了解,当函数用作构造函数时,将创建一个对象,并使用新创建的对象作为其
值来执行函数。新创建的对象还继承构造函数的
prototype
属性的方法和属性

在您的示例中,
矩形
构造函数试图继承
形状
构造函数的属性和方法

function Rectangle() {
  Shape.call(this);
}
创建
Rectangle
实例时,调用
Shape
函数,将新创建的
Rectangle
实例作为其
此值。
Shape
函数中的所有初始化代码都在新创建的
Rectangle
实例上运行

Rectangle.prototype.constructor = Rectangle;
创建函数时,会自动创建其
原型
属性。
prototype
属性是一个对象,它有一个指向构造函数的
constructor
对象。 create(proto)创建一个新对象,其原型是提供给它的参数的值。
Rectangle.prototype=Object.create(Shape.prototype)
实际上创建了一个新对象,该对象继承了
Shape.prototype
的方法,并且该对象被分配给
Rectangle.prototype
。这将覆盖自动创建的原始
prototype
对象。因此,您需要使用需要查找的
Rectangle.prototype.constructor=Rectangle

prototype
对象上显式定义
constructor
属性
Shape
只是一个函数,一个构造函数,而
这个
是显式传递的。这一行与其他语言中的“super”类似。引入OP中没有的概念并使用OP没有表示他们理解的编程语言对它们进行说明并没有特别的帮助。“当函数执行时,this关键字指向执行上下文”-绝对没有。与函数完全不同,函数是特定执行上下文的一个组件。
Rectangle.prototype.constructor = Rectangle;