如何使用length属性在javascript中创建自定义对象以及添加和删除函数

如何使用length属性在javascript中创建自定义对象以及添加和删除函数,javascript,jquery,arrays,class,object,Javascript,Jquery,Arrays,Class,Object,我想要一个javascript中的对象类,它将被写入一个单独的js文件中 此对象类将被称为页面 这个对象类的目的是让我操作html5中纯只读的files属性 看 我希望页面中包含以下属性/函数 Pages.length:是只读属性 add(key,value):是一个像关联数组一样执行add的函数 getByKey(key):是一个返回与该键关联的值的函数 getByIndex(index):是一个返回与索引关联的值的函数 Pages.removeAll():是一个将删除所有键值对的函数,因此

我想要一个javascript中的对象类,它将被写入一个单独的js文件中

此对象类将被称为页面

这个对象类的目的是让我操作html5中纯只读的files属性

我希望页面中包含以下属性/函数

  • Pages.length:是只读属性
  • add(key,value):是一个像关联数组一样执行add的函数
  • getByKey(key):是一个返回与该键关联的值的函数
  • getByIndex(index):是一个返回与索引关联的值的函数
  • Pages.removeAll():是一个将删除所有键值对的函数,因此长度为零
  • removeByKey(key):是一个将删除相应键值对的函数
  • removeByIndex(index):是一个将删除相应键值对的函数
  • 构造器
  • createFrom(文件):返回Pages对象的实例,该实例将根据上面链接中所述的文件对象自动创建
  • indexExists(index):如果存在这样的索引,则返回布尔值
  • keyExists(key):如果存在这样的键值对,则返回bookean
最重要的特点是:

  • 每当我添加新的键值对时,它都会附加到Pages对象的末尾
  • 键-值对可以通过使用.getByKey(键)的键或.getByIndex(索引)的键访问,例如,第一个键-值对可以通过索引0访问
  • 无论何时删除或添加任何现有的键值对,长度属性都会更新,索引也会更新。例如,如果有5个键值对,我删除了第2个键值对,那么现在可以使用索引1访问第3个键值对,依此类推
  • 我不需要各种函数的代码

    我只需要一个用javascript创建上述自定义对象类的框架结构

    我读了,认为我需要把它作为一个函数

    但后来我看到了一些答案,这些答案提出了各种改进,比如使用Object.create


    因此,我要求提供最好的模板,以便在需要时添加新功能。

    这是我以前使用过的结构的基本框架,我只在最新的浏览器上进行了测试,但它没有使用任何会导致问题的技术。唯一可能的争论是使用数组对对象进行原型化。但我不明白为什么这在旧浏览器中不起作用:

    <script>
      "use strict";
    
      var ArrayLike = (function(){
        /// create a static reference to our constructor so that we can
        /// add methods to ArrayLike... if we like.
        var _static = function(){
          /// store some "private" values, and arrayify our arguments
          var _args = Array.prototype.slice.call( arguments ),
              _private = { byKey:{}, byIndex:{} }, 
              _public = this;
          /// make sure the user used the 'new' keyword.
          if ( _public instanceof _static ) {
            /// if we have arguments then push them onto ourselves
            if ( _args.length ) {
              _public.splice.apply(_public,[0,0].concat(_args));
            }
            /// Now that a new instance has been created, switch in an array 
            /// prototype ready for the next instance.
            _static.prototype = new Array();
            /// start adding our methods, bare in mind if you wish to
            /// stop any of the native array methods from working you'll 
            /// have to override them here.
            _public.add = function( key, value ){
              /// store the keys and indexes as references to themselves.
              _private.byKey[key] = _public.length;
              _private.byIndex[_public.length] = key;
              /// use the inherited push function from the array.
              _public.push( value );
            }
            /// an example function to show how get by key would work.
            _public.getByKey = function(key){
              if ( (key = _private.byKey[key]) || key === 0 ) {
                return _public[key] ? _public[key] : null;
              }
            }
            /// easy removeAll thanks to the array prototype.
            _public.removeAll = function(){
              _public.length = 0;
            }
            /// here I leave you to flesh out the methods that you 'want'.
            _public.removeByKey = function(){
    
            }
            /// I'll give you a clue that keeping your array index in order
            /// is going to be a manual process, so whenever you delete you
            /// will have to reindex.
            _private.reIndex = function(){
    
            }
          }
        }
        /// set-up the prototype as an array ready for creation
        _static.prototype = new Array();
        /// return the function that will be our constructor
        return _static;
      })();
    
    </script>
    
    从数组扩展的好处是非常明显的,因为您现在可以像对待任何数组一样对待
    a
    ,所以您的一些工作是通过核心JS代码来完成的。但是,在实现使用关键点的系统时,最好覆盖大多数常规阵列操作,以便能够正确跟踪结构中使用的关键点

    不管怎么说,希望它能有所帮助,我已经让您解决了重新为数组编制索引的稍微棘手的问题,因为按照上面的设置方式,它应该是直截了当的

    其他增强功能
    关于将某些属性设置为只读,这只有在JavaScript 1.8+中才真正可能实现,因此它不会向后兼容较旧的浏览器。您可以使用Felix Kling评论中提到的
    Object.defineProperty(obj、prop、descriptor)
    来实现这一点。使用此选项可以影响
    .length
    等内容,并使其成为只读。但是,代码越是被锁定,它的灵活性和可扩展性就越差。

    如何使用这些
    页面
    对象还不是很清楚。没有真正的模板,请将所有这些属性添加到
    页面。prototype
    。根据您希望支持的浏览器,
    defineProperty
    可能会让您感兴趣:。只有一种方法可以实现这一点,而且很难看。在数组中按索引存储,或在对象中按键存储。要同时实现这两个功能,需要有一个函数数组,在其中存储对象,并带有名称和值<代码>[{name:func1,value:function(){},{name:func2,value:function(){}]。然后,如果您想按名称调用任何对象,则必须在数组中循环查找具有正确名称的对象。。。另一种方法是保留函数的两个版本——一个按索引,一个按名称,并不断更新对index=bad的引用您的答案帮助了我。。当我有时间的时候,我也会给出我自己的答案。非常感谢。
    var a = new ArrayLike(1,2,3);
    alert( a instanceof ArrayLike ); /// alerts FALSE