0

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

这个对象类将被称为Pages

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

http://help.dottoro.com/ljslrhdh.php

我想要页面中的以下属性/功能

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

最重要的特点是:

  1. 每当我添加新的键值对时,它都会被附加到 Pages 对象的末尾。
  2. 键值对可以通过使用 .getByKey( key ) 或 .getByIndex( index ) 的键访问,例如,第一个键值对可以通过索引 0 访问。
  3. 每当删除或添加任何现有的键值对时,都会更新长度属性并更新索引。例如,如果有 5 个键值对并且我删除了第二个,那么现在可以使用索引 1 访问第三个键值对,依此类推。

我不需要各种功能的代码。

我只需要在javascript中创建上述自定义对象类的骨架结构

我阅读了 JavaScript 对象的 Set length 属性,并认为我需要将它作为一个函数来执行。

但是后来我看到了一些答案,这些答案暗示了有关使用 Object.create 的各种改进,例如https://stackoverflow.com/a/6412732/80353https://stackoverflow.com/a/6412869/80353

所以我要求最好的模板,以便我可以在需要时添加新功能。

4

1 回答 1

1

这是我以前使用过的结构的准系统,我只在最新的浏览器上对此进行了测试——但是它没有使用任何会导致问题的技术。唯一可能的争用是使用 Array 对对象进行原型设计。但我不明白为什么这在旧浏览器中不起作用:

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

从普通构造函数的角度来看,上述内容有点奇怪,因为它不断修改其原型,这意味着以下内容无法按预期工作:

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

从数组扩展的好处是非常明显的,因为您现在可以a像对待任何数组一样对待 - 所以您的一些工作是由核心 JS 代码为您完成的。但是,当您正在实现一个使用键的系统时,最好覆盖大多数正常的数组操作,以便您可以正确跟踪结构中正在使用的键。

无论如何希望它有所帮助,我已经让您解决重新索引数组的稍微棘手的元素,因为它应该与上述设置方式直接相关。

其他增强功能

关于将某些属性设置为只读,这只有在 JavaScript 1.8+ 中才能真正实现——因此它不会向后兼容旧版浏览器。Object.defineProperty(obj, prop, descriptor)您可以使用Felix Kling 的评论中提到的方法来实现这一点。使用它应该可以影响诸如.length并使它们只读之类的东西。但是,您对代码的锁定越多,它的灵活性和可扩展性就越差。

于 2012-09-28T08:46:04.420 回答