可以使用哪些技术在JavaScript中定义类,它们的权衡是什么?

懵懂的女人 提交于 2019-12-24 19:50:21

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

我喜欢在目前正在从事的大型项目中使用OOP。 我需要用JavaScript创建几个类,但是,如果我没记错的话,至少有两种方法可以做到这一点。 语法是什么,为什么要用这种方式呢?

我想避免使用第三方库-至少在一开始。
在寻找其他答案时,我找到了文章“ 使用JavaScript进行面向对象的编程”,第I部分:继承-文档JavaScript ,该文章讨论了JavaScript中的面向对象的编程。 有更好的继承方法吗?


#1楼

var Animal = function(options) {
    var name = options.name;
    var animal = {};

    animal.getName = function() {
        return name;
    };

    var somePrivateMethod = function() {

    };

    return animal;
};

// usage
var cat = Animal({name: 'tiger'});

#2楼

以下是迄今为止我在javascript中使用过的创建对象的方法

范例1:

obj = new Object();
obj.name = 'test';
obj.sayHello = function() {
    console.log('Hello '+ this.name);
}

范例2:

obj = {};
obj.name = 'test';
obj.sayHello = function() {
    console.log('Hello '+ this.name);
}
obj.sayHello();

范例3:

var obj = function(nameParam) {
    this.name = nameParam;
}
obj.prototype.sayHello = function() {
    console.log('Hello '+ this.name);
}

示例4: Object.create()的实际好处。 请参考[此链接]

var Obj = {
    init: function(nameParam) {
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};
var usrObj = Object.create(Obj);  // <== one level of inheritance

usrObj.init('Bob');
usrObj.sayHello();

示例5(自定义的Crockford's Object.create):

Object.build = function(o) {
   var initArgs = Array.prototype.slice.call(arguments,1)
   function F() {
      if((typeof o.init === 'function') && initArgs.length) {
         o.init.apply(this,initArgs)
      }
   }
   F.prototype = o
   return new F()
}
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}}  // For example

var userB = {
    init: function(nameParam) {
        this.id = MY_GLOBAL.nextId();
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};
var bob = Object.build(userB, 'Bob');  // Different from your code
bob.sayHello();


使用ES6 / ES2015随时更新答案

一个类的定义如下:

class Person { constructor(strName, numAge) { this.name = strName; this.age = numAge; } toString() { return '((Class::Person) named ' + this.name + ' & of age ' + this.age + ')'; } } let objPerson = new Person("Bob",33); console.log(objPerson.toString());

#3楼

您可能想使用折叠模式创建类型:

    // Here is the constructor section.
    var myType = function () {
        var N = {}, // Enclosed (private) members are here.
            X = this; // Exposed (public) members are here.

        (function ENCLOSED_FIELDS() {
            N.toggle = false;
            N.text = '';
        }());

        (function EXPOSED_FIELDS() {
            X.count = 0;
            X.numbers = [1, 2, 3];
        }());

        // The properties below have access to the enclosed fields.
        // Careful with functions exposed within the closure of the
        // constructor, each new instance will have it's own copy.
        (function EXPOSED_PROPERTIES_WITHIN_CONSTRUCTOR() {
            Object.defineProperty(X, 'toggle', {
                get: function () {
                    var before = N.toggle;
                    N.toggle = !N.toggle;
                    return before;
                }
            });

            Object.defineProperty(X, 'text', {
                get: function () {
                    return N.text;
                },
                set: function (value) {
                    N.text = value;
                }
            });
        }());
    };

    // Here is the prototype section.
    (function PROTOTYPE() {
        var P = myType.prototype;

        (function EXPOSED_PROPERTIES_WITHIN_PROTOTYPE() {
            Object.defineProperty(P, 'numberLength', {
                get: function () {
                    return this.numbers.length;
                }
            });
        }());

        (function EXPOSED_METHODS() {
            P.incrementNumbersByCount = function () {
                var i;
                for (i = 0; i < this.numbers.length; i++) {
                    this.numbers[i] += this.count;
                }
            };
            P.tweak = function () {
                if (this.toggle) {
                    this.count++;
                }
                this.text = 'tweaked';
            };
        }());
    }());

该代码将为您提供一个名为myType的类型。 它将具有称为切换文本的内部私有字段。 它还将具有以下暴露的成员:字段数字 ; 属性切换文本数字长度 ; 方法增量 NumbersByCounttweak

折叠模式在此处进行了详细说明: Javascript折叠模式


#4楼

ES2015课程

在ES2015规范中,您可以使用类语法,它只是原型系统的基础。

class Person {
  constructor(name) {
    this.name = name;
  }
  toString() {
    return `My name is ${ this.name }.`;
  }
}

class Employee extends Person {
  constructor(name, hours) {
    super(name);
    this.hours = hours;
  }
  toString() {
    return `${ super.toString() } I work ${ this.hours } hours.`;
  }
}

好处

主要优点是静态分析工具发现更容易针对此语法。 对于其他来自基于类的语言的人,使用该语言作为多语言也更容易。

注意事项

注意其当前的局限性。 要获得私有属性,必须使用Symbols或WeakMaps 。 在将来的版本中,很可能会将类扩展为包括这些缺少的功能。

支持

浏览器支持是不是现在(几乎每个人都只是支持IE)很不错,但你可以像现在transpiler使用这些功能巴贝尔

资源资源


#5楼

具有继承的基于对象的类

var baseObject = 
{
     // Replication / Constructor function
     new : function(){
         return Object.create(this);   
     },

    aProperty : null,
    aMethod : function(param){
      alert("Heres your " + param + "!");
    },
}


newObject = baseObject.new();
newObject.aProperty = "Hello";

anotherObject = Object.create(baseObject); 
anotherObject.aProperty = "There";

console.log(newObject.aProperty) // "Hello"
console.log(anotherObject.aProperty) // "There"
console.log(baseObject.aProperty) // null

简单,贴心,可以完成。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!