函数构造函数和原型构造函数有什么区别? [英] What's the difference between a function constructor and prototype constructor?

查看:135
本文介绍了函数构造函数和原型构造函数有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道两者之间的区别

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

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

在JavaScript中声明原型的构造函数时。



与常规函数相比,使用 prototype.constructor 有什么优势?

解决方案

看看下面的图片,取自



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

  function Foo(){} 
Foo.prototype = {}; //没有构造函数属性

您可以决定使其指向其他函数:

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

您可以决定使其指向功能以外的其他东西:

  function Foo(){} 
Foo.prototype.constructor =我不是函数。;

但是,关键是它只是另一个原型属性。实际上,我们可以利用它来创造更清晰的代码。例如,这就是我们通常在JavaScript中创建类的方式。

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

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

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

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

  function defclass(prototype){
var构造函数=原型.constructor;
constructor.prototype =原型;
返回构造函数;
}

var MyClass = defclass({
构造函数:function(a,b){
this.a = a;
this.b = b;
},
sum:函数(){
返回this.a + this.b;
},
diff:function(){
返回this.a-this.b;
}
});

这更干净了。此外,它还向我们展示了构造函数属性只是一个普通的原型属性。希望能回答您的问题。


I would like to know what the difference between this

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

and this

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

when it comes to declaring the constructor function for a prototype in JavaScript.

What is the advantage in using prototype.constructor over a regular function?

解决方案

Take a look at the following image, taken from the following answer:

When you create a new function, JavaScript automatically creates a new object (the prototype) as well:

  1. JavaScript sets the prototype property of the constructor function to the prototype object.
  2. JavaScript sets the constructor property of the prototype object to the constructor function.

Hence when you do this:

function Foo() {}

JavaScript actually does:

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

Why does JavaScript do this? Consider what happens when you create an instance of Foo:

var foo = new Foo;

When you create an instance of Foo using the new keyword, JavaScript actually creates an instance of Foo.prototype and not Foo. This means that foo inherits properties from Foo.prototype and not Foo. To make this point clear:

function Foo() {}

Foo.bar = true;

Foo.prototype.baz = true;

var foo = new Foo;

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

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

Now the advantage of having a constructor property on the prototype is that when you create an instance of Foo, the instance inherits the constructor property from the prototype. Hence you can use it to find out the type of an object:

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);

Beside that there's nothing really special about the constructor property of the prototype. It's just an ordinary property. In the words of Tyler Durden: https://www.youtube.com/watch?v=4X2AvfSTi6Q

Since it is an ordinary property you can decide not to have a constructor property at all:

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

You can decide to make it point to some other function:

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

You can decide to make it point to something other than a function:

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

However, the point is that it's just another prototype property. In fact, we could use this to our advantage to create cleaner code. For example, this is how we normally create "classes" in 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;
};

It's not very clean. Notice however that all three functions MyClass, sum and diff are prototype functions: constructor, sum and diff respectively. A prototype is just an object, and object literals in JavaScript provide a good form of encapsulation. We can use this to our advantage to write cleaner code:

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;
    }
});

That's much cleaner. In addition it shows us that the constructor property is just an ordinary prototype property. Hope that answers your question.

这篇关于函数构造函数和原型构造函数有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆