2015-04-30 125 views
3

我一直在嘗試理解JavaScript中的繼承,到目前爲止,我已經閱讀了很多有關這方面的網站(包括javascript.info和Crockford的Javascript良好部分) - 但我可以似乎並不像Array繼承那麼簡單。JavaScript繼承和數組對象(需要理解的解釋)

也許如果我用一個例子來演示,有人可以糾正我,教我什麼我錯了。

function ExtendedArray() { 
    Array.call(this, arguments); 

    this.test = function() { 
     return 'something'; 
    } 
} 

//I think this is the most standard way to extend a class? 
ExtendedArray.prototype = []; 
ExtendedArray.prototype.constructor = ExtendedArray; 

$scope = {}; 

$scope.arr = new Array(1, 2, 3); 
$scope.concatArr = [].concat($scope.arr); 

$scope.x = new ExtendedArray(1, 2, 3); //empty | instanceof Array = true 
$scope.concatX = [].concat($scope.x);  //empty 

$scope.y = new ExtendedArray();   //instanceof Array = true 
$scope.y.push(1, 2, 3);     //works - elements are added! 
$scope.concatY = [].concat($scope.y); //concats it like a object 

這裏是一個JS-搗鼓相同:

http://jsfiddle.net/superasn/pq2j139c/

一些問題:

  1. 我該如何解決這個代碼,以便ExtendedArray表現爲陣列?你可以看到$scope.x是空的。爲什麼構造函數不工作?
  2. push函數起作用!?但然後concat失敗?如何使concat工作?
  3. 我看到有一些庫可以擴展類,是JS繼承的更好方法嗎?

您的建議表示讚賞!

+1

'[] .concat($ scope.x)'是不是** **空,它包含的一個實例'ExtendedArray'對象 – CodingIntrigue

+2

我剛剛從[這個問題]找到[這篇文章](http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/)( http://stackoverflow.com/questions/3261587/subclassing-javascript-arrays-typeerror-array-prototype-tostring-is-not-generi) - 似乎相關 – CodingIntrigue

+0

謝謝..是的,我也發現昨天的perfectionkills文章,它只是增加了我的困惑。當事情開始進入奇怪的領域時,我停止閱讀,他使用Iframes來實現像數組繼承一樣簡單的事情。我今天再給它一次。 – supersan

回答

0

你只是必須構造函數中調用[].push.apply(this, arguments);

angular.module('myApp', []) 
 
.controller('mainCtrl', ['$scope', function($scope) { 
 

 
    var __extends = this.__extends || function (d, b) { 
 
       for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 
 
       function __() { this.constructor = d; } 
 
       __.prototype = b.prototype; 
 
       d.prototype = new __(); 
 
      }; 
 
    
 
    function ExtendedArray() { 
 
     Array.call(this, arguments); 
 
     
 
     [].push.apply(this, arguments); 
 
     
 
     this.test = function() { 
 
      return 'something'; 
 
     } 
 
    } 
 
    
 
    __extends(ExtendedArray, Array); 
 

 
    $scope.arr = new Array(1, 2, 3); 
 
    $scope.concatArr = [].concat($scope.arr); 
 
    
 
    $scope.x = new ExtendedArray(1, 2, 3);  
 
    $scope.concatX = [].concat($scope.x); 
 
    
 
    $scope.y = new ExtendedArray();  
 
    $scope.y.push(1, 2, 3); 
 
    $scope.concatY = [].concat($scope.y); 
 
    
 
    $scope.isArray = function(v) { 
 
     return v instanceof Array; 
 
    } 
 
    
 
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="myApp" ng-controller="mainCtrl"> 
 
    <div class="content"> 
 
     Arr: Val = {{arr}}/Concat = {{concatArr}}/Is Array? {{isArray(arr)}} 
 
     
 
     <hr/> 
 

 
     X: Val = {{x}}/Concat = {{concatX}}/Is Array? {{isArray(x)}} 
 

 
     <hr/> 
 

 
     Y: Val = {{y}}/Concat = {{concatY}}/Is Array? {{isArray(y)}} 
 
     
 
    </div> 
 
</div>

+0

謝謝!第1部分正在工作!現在有兩個簡單的問題:調用'Array.call(this,arguments)的用法是什麼;'如果我們必須'推送'參數。其次,concat仍然不起作用。它仍然認爲它作爲一個項目..我如何使concat工作在一個正常的數組上工作的方式? – supersan

+2

'Array.call(this,arguments);'完全沒有做什麼。你應該刪除它。 – Bergi