javascript subclassing native objects

You can subclass native object, the most often sub-classed object is the Object class itself. 

 

Let's first see some cases that you do with sub-classing the object class. 

 

 

Object.prototype.keys1 = function () {
  var keys1 = [];
  for (var i in this) {
    keys1.push(i);
  }
  return keys1;

};
 

 

However, the gotchas above is that when you call keys1(), it may returns more properties than youmight expect it to returns. let's see the example below.

 

 

          var obj = { a: 1, b: 2, c: 3 };
          assert(obj.keys1().length != 3, "The 3 existing properties plus the new keys method keys1, and others");
 

 

so you might take care of which properties are on the actual object rather than on inherited prototyped object.

 

 

Below is the improved version.

 

 

Object.prototype.keys = function () {
  var keys = [];
  for (var i in this) {
    if (this.hasOwnProperty(i)) {
      keys.push(i);
    }
  }
  return keys;
};
 

 

And below is the test code 

 

 

          var obj = { a: 1, b: 2, c: 3 };
          assert(obj.keys().length == 3, "Only the 3 exiting properties are included.");
 

 

 

Extending the Array.

 

 

due to some reason, the IE does not support directly sub-classing the Array, because the property of length of Array is immutable. but  you can take the following workaround.

 

 

/**
* @MyArray now fake the interface of Array, but it does not inherit from Array directly now.
*/
function MyArray() { }
// this length property is to simulate the Array length property, of which is essential to simulate native array object

MyArray.prototype.length = 0;

(function () {
 var methods = ['push', 'pop', 'shift', 'unshift', 'slice', 'splice', 'join'];

  for (var i = 0; i < methods.length; i++) { 
    (function(name) { 
       MyArray.prototype[name] = function() { 
         return Array.prototype[name].apply(this, arguments);
       };
    })(methods[i]);
  }
})();

 

 

and then you can do the test via the following code. 

 

 

          var mine = new MyArray();

          mine.push(1, 2, 3);
          assert(mine.length == 3, "All the items are on our sub-classed array.");
          assert(!(mine instanceof Array), "We are sub-classing array, though");
 

 

 

Extending numbers

 

 

You might think you can override the number class so that you can add extra functions to the function literal; However, this is not always true, because of the way how the Javascript engine parse numbers and its properties of the number, it might not work as you expected, as illustrated in the following example. 

 

 

 

Number.prototype.add = new function (num) {
  return this + num;
}
 

 

 

 

and the following code shows the tests and its results.

 

 

          var n = 5;
          assert(n.add(3) == 8, "It works fine if the number is an varaible.");
          alert((5).add(3) == 8, " Also works if a number is wrapping in parenthesis.");
  

 

Following is the full code. 

 

/**************************************
*@Summary
* This shows how you can subclass some native object from javascript
*
*  this utilize this feature to extend the element in the HTML
*
* @Usage:
*   


* @TODO:
* test it 
***************************************/

/** 
* First attempt to subclass the native Array object
*
* @Comment: there are some restriction by the IE explorer in that it simply does not allow the Array type to be inherted, the reason is becaue the length property is immutable
*/
//function MyArray() { }

//MyArray.prototype = new Array();

//var mine = new MyArray();
//mine.push(1, 2, 3);

//assert(mine.length == 3, "All the items are on our sub-classed array.");
//assert(mine instanceof Array, "Verify that we implement Array functionality.");


Object.prototype.keys1 = function () {
  var keys1 = [];
  for (var i in this) {
    keys1.push(i);
  }
  return keys1;

};

Object.prototype.keys = function () {
  var keys = [];
  for (var i in this) {
    if (this.hasOwnProperty(i)) {
      keys.push(i);
    }
  }
  return keys;
};



/**
* @MyArray now fake the interface of Array, but it does not inherit from Array directly now.
*/
function MyArray() { }
// this length property is to simulate the Array length property, of which is essential to simulate native array object

MyArray.prototype.length = 0;

(function () {
 var methods = ['push', 'pop', 'shift', 'unshift', 'slice', 'splice', 'join'];

  for (var i = 0; i < methods.length; i++) { 
    (function(name) { 
       MyArray.prototype[name] = function() { 
         return Array.prototype[name].apply(this, arguments);
       };
    })(methods[i]);
  }
})();



Number.prototype.add = new function (num) {
  return this + num;
}
 

 

 

and its harnessed test.

 

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript" src="../unit.js"></script>
    <script type="text/javascript" src="subclassnative.js"></script>
    <script type="text/javascript">

      var mine = new MyArray();
      mine.push(1, 2, 3);


      window.onload = function () {
        test("subclass native methods test", function () {
          var mine = new MyArray();

          mine.push(1, 2, 3);
          assert(mine.length == 3, "All the items are on our sub-classed array.");
          assert(!(mine instanceof Array), "We are sub-classing array, though");
        });



        test("subclass native method test2", function () {
          var obj = { a: 1, b: 2, c: 3 };
          assert(obj.keys1().length == 5, "The 3 existing properties plus the new keys method keys1, and keys");
          assert(obj.keys().length == 3, "Only the 3 exiting properties are included.");
          // does not work, cause syntax error
          //        assert(5.add(3) == 8, "Doesnot work, cause syntax error.");
          var n = 5;
          assert(n.add(3) == 8, "It works fine if the number is an varaible.");
          alert((5).add(3) == 8, " Also works if a number is wrapping in parenthesis.");

        }
        );
      }

    </script>

    <style type="text/css" >
      #results li.pass { color: Green }
      #results li.fail { color: Red }
    </style>

</head>
<body>
<ul id="results" />
</body>
</html>
 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值