javascript - 定义原型(prototype)属性的正确方法

标签 javascript constructor prototype

我有一个关于您如何定义原型(prototype)属性的问题。所以您不必编写“MyClass.prototype”。为了将每个属性添加到原型(prototype)中,人们创建了新对象并将其设置为原始对象。

像这样。

var MyClass = function() {}

MyClass.prototype = {
    sayHi : function() {
        alert('hi');
    }
}

但是如果您这样做,当您尝试从任何实例访问构造函数时可能会导致问题。

var o1 = new MyClass();

alert( o1 instanceof MyClass ); // true
alert( o1.constructor === MyClass ); // false !!!

o1.constructor 通常会指向 MyClass,但由于原始原型(prototype)已更改,因此不再指向。

我设法通过 MyClass.prototype.constructor = MyClass; 解决了这个问题,它再次正常工作。

问题是,改变原始原型(prototype)会导致哪些其他问题?

您如何定义原型(prototype)属性?

最佳答案

我通常使用简单的 defclass 函数在 JavaScript 中彻底创建“类”:

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

这个函数允许我创建类如下:

var MyClass = defclass({
    constructor: function () {},
    sayHi: function () {
        alert("hi");
    }
});

该方法具有以下优点:

  1. 所有原型(prototype)属性都封装在一个对象文字中。
  2. constructor 函数本身只是另一个原型(prototype)属性。
  3. 实例将始终具有正确的constructor 属性。

例如:

var o1 = new MyClass;
alert(o1 instanceof MyClass);      // true
alert(o1.constructor === MyClass); // true

您还可以轻松修改defclass 以支持继承:

function defclass(uber, body) {
    var base = uber.prototype;
    var prototype = Object.create(base);
    var constructor = body.call(prototype, base), prototype.constructor;
    constructor.prototype = prototype;
    return constructor;
}

然后您可以按如下方式使用它:

var Rectangle = defclass(Object, function () {
    this.constructor = function (width, height) {
        this.height = height;
        this.width = width;
    };

    this.area = function () {
        return this.width * this.height;
    };
});

继承也同样简单:

var Square = defclass(Rectangle, function (base) {
    this.constructor = function (side) {
        base.constructor.call(this, side, side);
    };
});

一切如期进行:

var sq = new Square(5);

alert(sq.area());                 // 25
alert(sq instanceof Square);      // true
alert(sq instanceof Rectangle);   // true
alert(sq.constructor === Square); // true

这就是所有人。

关于javascript - 定义原型(prototype)属性的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20644493/

相关文章:

javascript - 如何使用 jQuery AJAX 和 PHP 使用 <a> 标签将表单提交到 mySQL 数据库中?

javascript - [已修复]试图通过使用 JS/Jquery 声明来避免重复的 CSS

javascript - 将 JS foreach 传递给 JS post 而不使用表单

java - java中如何强制构造函数使用类自己的方法

c++ - 运算符重载中的显式构造?

javascript - 原型(prototype)函数和json符号函数的区别?

javascript - 在Javascript中按字母顺序对字符串进行排序

vb.net - VB中可以继承带参数的sub new(构造函数)吗?

prototype - 一个简单但功能强大的网站 map 设计工具?

javascript - JS - 将基类型转变为子类型