函数构造函数和原型构造函数有什么区别?

2024-03-21

我想知道这有什么区别

 MyClass = function() {};
 MyClass.prototype.Foo = function();

and this

 MyClass = {};
 MyClass.prototype.constructor = function() {};
 MyClass.prototype.Foo = function();

当涉及到在 JavaScript 中声明原型的构造函数时。

使用上有什么好处prototype.constructor超过常规功能?


看一下下面的图片,取自以下答案 https://stackoverflow.com/a/8096017/783743:

当你创建一个新函数时,JavaScript 也会自动创建一个新对象(原型):

  1. JavaScript 设置prototype构造函数的属性传递给原型对象。
  2. JavaScript 设置constructor原型对象的属性传递给构造函数。

因此,当你这样做时:

function Foo() {}

JavaScript 实际上是这样做的:

function Foo() {}
Foo.prototype = { constructor: Foo };

JavaScript 为什么要这样做?考虑一下当你创建一个实例时会发生什么Foo:

var foo = new Foo;

当您创建一个实例时Foo使用new关键字,JavaScript 实际上创建了一个实例Foo.prototype并不是Foo。这意味着foo继承属性Foo.prototype并不是Foo。为了明确这一点:

function Foo() {}

Foo.bar = true;

Foo.prototype.baz = true;

var foo = new Foo;

console.log(foo.bar); // undefined

console.log(foo.baz); // true

现在的优势是拥有constructor原型上的属性是当您创建一个实例时Foo,该实例继承了constructor来自原型的属性。因此,您可以使用它来找出对象的类型:

function Foo() {}
function Bar() {}

function test(obj) {
    switch (obj.constructor) {
    case Foo: console.log("It's a Foo."); break;
    case Bar: console.log("It's a Bar."); break;
    default:  console.log("It's something else.");
    }
}

test(new Foo);
test(new Bar);
test(new Object);

除此之外,没有什么特别之处constructor原型的属性。这只是一个普通的财产。用泰勒·德登的话来说:https://www.youtube.com/watch?v=4X2AvfSTi6Q https://www.youtube.com/watch?v=4X2AvfSTi6Q

由于它是一个普通属性,您可以决定根本不具有构造函数属性:

function Foo() {}
Foo.prototype = {}; // no constructor property

您可以决定让它指向其他一些函数:

function Foo() {}
function Bar() {}
Foo.prototype.constructor = Bar;

您可以决定让它指向函数以外的其他东西:

function Foo() {}
Foo.prototype.constructor = "I am not a function.";

然而,重点是它只是另一个原型属性。事实上,我们可以利用这一点来创建更清晰的代码。例如,这就是我们通常在 JavaScript 中创建“类”的方式。

function MyClass(a, b) {
    this.a = a;
    this.b = b;
}

MyClass.prototype.sum = function () {
    return this.a + this.b;
};

MyClass.prototype.diff = function () {
    return this.a - this.b;
};

不是很干净。但请注意,所有三个函数MyClass, sum and diff是原型函数:constructor, sum and diff分别。原型只是一个对象,JavaScript 中的对象字面量提供了一种很好的封装形式。我们可以利用这一点来编写更清晰的代码:

function defclass(prototype) {
    var constructor = prototype.constructor;
    constructor.prototype = prototype;
    return constructor;
}

var MyClass = defclass({
    constructor: function (a, b) {
        this.a = a;
        this.b = b;
    },
    sum: function () {
        return this.a + this.b;
    },
    diff: function () {
        return this.a - this.b;
    }
});

这样就干净多了。此外,它还向我们表明constructorproperty 只是一个普通的原型属性。希望这能回答你的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

函数构造函数和原型构造函数有什么区别? 的相关文章

随机推荐

  • 非常纠结 cocoapods / ruby​​ 设置

    这工作正常 然后突然就不行了 我希望我知道为什么 真的卡住了 在网上找不到任何东西 我正在开发一个 ObjectiveC 项目 我尝试用以下方法重置一切 sudo gem uninstall ruby sudo gem uninstall
  • 实体框架花费大量时间初始化模型

    我面临 EF 花费大量时间 跨越数小时 来初始化模型的问题 该模型如下所示 大约有 20 个类从 A1 派生 大约 30 个类从 A2 派生 我必须从 TPT 战略转向 TPH 战略解决问题 https stackoverflow com
  • Swift 中的 NSExpression 计算器

    我正在尝试复制需要用Objective C写计算器 https stackoverflow com questions 15090475 need to write calculator in objective c在 Swift 中 但我
  • 使用 ArrayList 将文本文件拆分并存储到数组中

    我一直在开发一个测验应用程序 它使用文本文件来存储问题 问题的格式如下 QUESTION CHOICE A CHOICE B CHOICE C CHOICE D ANSWER 我希望它读取每一行并将其分成 6 个不同的部分 作为分割字符串并
  • 为什么这个 Flexbox 布局在 Safari 中会被破坏?

    所以我在 CSS 中设计了这个 想法是有一个标题 其余部分作为可滚动内容 有一个链接到现场演示在底部 Alas in Safari it is broken and looks like this 可以看到 表头的高度计算错误 导致绿框溢出
  • 与 React 一起使用时如何检测 keyPress 上的“Enter”键

    我正在使用 ReactJs 来开发我的应用程序 我试图通过处理 onKeyPress 事件在按下 Enter 时提交输入文本 它检测其他输入 但不输入 我尝试过不同的方法 event key event charCode event key
  • Cassandra RandomPartitioner 版本 1.2.3

    我使用 apt 在 debian 上安装 Cassandra 1 2 3 我之前使用的是 tarball 1 1 7 安装 安装后 我将 cassandra yaml 中的分区器从 Murmur3Partitioner 更改为 Random
  • Expo.FileSystem.downloadAsync 不显示下载通知

    我正在使用世博会FileSystem下载 pdf 文件 API 响应进入 success 函数 但是 我无法向用户显示下载的文件 预期的行为应该就像我们通常在状态栏上看到通知图标一样 单击图标会打开您的文件 FileSystem downl
  • DNS 服务器管理的域列表[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我们有一台运行 Ensim 的服务器 这是一个类似 Plesk 的旧工具 让我们的行为就像是一个网络主机一样 多年来 我们慢慢退出了托管业务 但我们的
  • Oracle默认的日期格式是YYYY-MM-DD,为什么?

    Oracle 的默认日期格式是 YYYY MM DD 这意味着如果我这样做 select some date from some table I lose我约会的时间部分 是的 我知道你可以通过以下方式 解决 这个问题 alter sess
  • 是否可以获得“this”指针的地址?

    我读到了this是一个右值 我们无法通过应用来获取它的地址 this 在我的代码中 我尝试使用引用绑定this 我想知道哪种方式可以给出地址this 还是两者都错了 到底是什么this 左值 右值 关键字还是其他什么 void MyStri
  • 数独求解算法 C++

    我花了几天时间尝试制作一个数独解决程序 但我被这些方法所困扰 我在这里找到了这个算法 但我不太理解它 从第一个空单元格开始 并在其中输入 1 检查整个板子 看看是否有冲突 如果板上存在冲突 请将当前单元格中的数字加 1 因此将 1 更改为
  • SQL NOT IN 可能存在性能问题

    我正在尝试重构几段旧代码 我已经重构了下面的当前代码并突出显示了NOT IN语句导致性能问题 我正在尝试重写NOT IN具有左外连接的部分 如果可能的话 任何人都可以帮忙 或者建议更好的方法吗 SELECT left unique id 1
  • 有没有流畅的WPF项目? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 作为我不断尝试使用 WPF XAML 的一部分 我对 UI 编码中流畅界面的应用产生了兴趣 我知道 Fluent Silverlight http c
  • 在 BeforeClose 事件期间保存 Word 文档时,并不总是触发 Shutdown 事件

    我有一个 Microsoft Word 插件 使用VSTO and c 对于每个文档 我使用文档 ShutDown 事件来清理我的父对象 并使用 BeforeClose 事件来对我的父对象进行预关闭验证 我的验证需要保存文档并尝试在 Bef
  • 在 Android 中选择 EGL 配置的正确方法是什么?

    我正在使用自己的 GLSurfaceView 并且一段时间以来一直在努力解决与 EGL 配置选择器相关的崩溃问题 似乎通过调用请求 RGB 565setEGLConfigChooser 5 6 5 0 16 0 应该是最受支持的 然而 使用
  • 上课需要记忆吗?

    class Test int x int main cout lt lt sizeof Test return 0 输出 4我只是想问 即使我没有创建 Test 类的任何对象 为什么它会打印 4 sizeof X 是字节数X创建时需要 致电
  • 使用 Apache AGE 制作最短路径

    我一直在阅读 Jasper Blues 的博客文章 使用 NEO4J 进行摇滚式流量路由 https medium com neo4j rock n roll traffic routing with neo4j 3a4b863c6030但
  • 我应该如何在 axios GET 请求中发送 JWT 令牌? [复制]

    这个问题在这里已经有答案了 我是 Vue js 新手 想要在组件中向受限 api 发出请求 computed token return this store getters getToken created axios get this B
  • 函数构造函数和原型构造函数有什么区别?

    我想知道这有什么区别 MyClass function MyClass prototype Foo function and this MyClass MyClass prototype constructor function MyCla