简体   繁体   English

如何在具有length属性的javascript中创建自定义对象以及添加和删除功能

[英]how to create a custom object in javascript with length property and add and remove functions

I want an object class in javascript that will be written in a separate js file. 我想要将用单独的js文件编写的javascript中的对象类。

This object class will be called Pages . 该对象类将称为Pages

the purpose of this object class is for me to manipulate the files property in html5 which is purely read-only. 这个对象类的目的是让我操作html5中的files属性,该属性完全是只读的。

See http://help.dottoro.com/ljslrhdh.php 参见http://help.dottoro.com/ljslrhdh.php

I want the following properties/functions in Pages 我想要页面中的以下属性/功能

  • Pages.length : is a read-only property. Pages.length:是只读属性。
  • Pages.add( key , value ) : is a function that will do an add like an associative array Pages.add( keyvalue ):是一个函数,将像关联数组一样进行添加
  • Pages.getByKey( key ) : is a function that will return the value associated with the key Pages.getByKey( key ):是一个函数,它将返回与键关联的值
  • Pages.getByIndex( index ) : is a function that will return the value associated with the index Pages.getByIndex( index ):是一个函数,它将返回与索引关联的值
  • Pages.removeAll() : is a function that will remove all the key-value pairs and therefore the length will be zero. Pages.removeAll():是一个将删除所有键值对的函数,因此长度为零。
  • Pages.removeByKey( key ) : is a function that will remove the corresponding key-value pair Pages.removeByKey( key ):是一个将删除对应的键值对的函数
  • Pages.removeByIndex( index ) : is a function that will remove the corresponding key-value pair Pages.removeByIndex( index ):是一个将删除对应的键值对的函数
  • a constructor 构造函数
  • Pages.createFrom( files ) : returns an instance of Pages object that will automatically create based on the files object as stated in the link above. Pages.createFrom( files ):返回一个Pages对象的实例,该实例将根据上述链接中所述的files对象自动创建。
  • Pages.indexExists( index ) : returns boolean if there is such an index Pages.indexExists( index ):如果存在这样的索引,则返回布尔值
  • Pages.keyExists( key ) : returns bookean if there is such a key-value pair Pages.keyExists( key ):如果有这样的键值对,则返回bookean

The most important characteristics are that: 最重要的特征是:

  1. whenever I add new key-value pair, it will be appended to the end of the Pages object. 每当我添加新的键值对时,它将被附加到Pages对象的末尾。
  2. the key-value pair can be accessed by either the key using .getByKey( key ) or the .getByIndex( index ) Eg, the first key-value pair can be accessed by index 0. 可以使用.getByKey( key )或.getByIndex( index )例如,通过键访问键值对,例如,可以通过索引0访问第一个键值对。
  3. whenever any existing key-value pair is removed or added, the length property is updated AND the indices are updated as well. 每当删除或添加任何现有的键值对时, 就会更新length属性,同时也会更新索引。 Eg, if there are 5 key-value pairs and I remove the 2nd one, the 3rd key-value pair now can be accessed using the index 1 and so on. 例如,如果有5个键值对,而我删除了第二个键值对,则现在可以使用索引1来访问第三个键值对,依此类推。

I do not need code for the various functions. 我不需要各种功能的代码。

I just need a skeleton structure of creating the above custom object class in javascript 我只需要在javascript中创建上述自定义对象类的框架结构

I read Set length property of JavaScript object and thought I need to do it as a function. 我阅读了JavaScript对象的Set length属性,并认为我需要将其作为一个函数来执行。

But then I saw some answers suggesting various improvements like this https://stackoverflow.com/a/6412732/80353 and https://stackoverflow.com/a/6412869/80353 about using Object.create 但是随后我看到了一些答案,提出了各种改进建议,例如关于使用Object.create的https://stackoverflow.com/a/6412732/80353https://stackoverflow.com/a/6412869/80353

so I am asking for the best template going forward, so that I can add new functions when needed. 因此,我要求最好的模板 ,以便在需要时添加新功能。

Here is the barebones of a structure I have used before, I have only tested this on the latest browsers - however it isn't using any techniques that should cause a problem. 这是我以前使用过的结构的准系统,我只在最新的浏览器上进行过测试-但是,它没有使用任何会引起问题的技术。 The only possible contention would be prototyping an object with an Array. 唯一可能的争用是使用Array制作对象原型。 But I don't see why this wouldn't work in older browsers: 但是我不明白为什么这在较旧的浏览器中不起作用:

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

The above is a bit odd from the point of view of a normal constructor, because it is constantly modifying it's prototype, this means the following doesn't work as expected: 从普通构造函数的角度来看,上述内容有些奇怪,因为它不断地修改其原型,这意味着以下内容无法按预期工作:

var a = new ArrayLike(1,2,3);
alert( a instanceof ArrayLike ); /// alerts FALSE

The benefits of extending from an Array are quite obvious though as you can now treat a like any array - so some of your work is done for you by core JS code. 从阵列扩展的优势是相当明显的,虽然你现在可以把a像任何阵列-所以你的一些工作是由核心JS代码为你做。 As you are implementing a system that uses keys however, it may be best to override most of the normal array operations so that you can keep a proper track of the keys that are in use in within the structure. 但是,在实现使用键的系统时,最好覆盖大多数常规数组操作,以便您可以正确跟踪结构中正在使用的键。

Anyway hope it helps, I've left you to work out the slightly tricky elements of reindexing the array as it should be straight forward with the way the above is setup. 无论如何希望它会有所帮助,我已经让您解决了重新索引数组的一些棘手元素,因为使用上述设置方法应该很直接。

Other enhancements 其他增强

With regards to setting certain properties to read-only, this is only truly possible in JavaScript 1.8+ - so it wont be backwards compatible to older browsers. 关于将某些属性设置为只读,这仅在JavaScript 1.8+中才真正可能-因此它不会向后兼容旧版浏览器。 You can achieve this using Object.defineProperty(obj, prop, descriptor) as mentioned in Felix Kling's comment. 您可以使用Felix Kling的注释中提到的Object.defineProperty(obj, prop, descriptor)来实现。 Using this it should be possible to affect things like .length and make them read-only. 使用它,应该有可能影响.length东西并使它们变为只读。 However, the more locked down you make your code, the less flexible and extensible it will be. 但是,编写代码的锁定越多,灵活性和可扩展性就越差。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM