0

我的问题与 JavaScript 继承有关,

var a = new Array();
var b = new Array();

a.prototype.max = function () {
 alert("Max");
}

b.max();

根据我的理解 b.max() 会给出错误说b 没有 max,但令人惊讶的是(对我来说)它在第 3 行给我一个错误a doesn't have prototype。当我执行typeof a 它给我 Object时,对象可以具有原型属性。我阅读 JavaScript 遵循原型继承,即基于实例的继承,所以我的问题是我创建了一个 Array 的实例,但原型属性仍未定义。

您能否解释一下我哪里出错了,或者我没有正确理解什么概念

4

5 回答 5

0

最好不要扩展像 Array 这样的东西,尤其是当您编写库或期望您的代码被许多其他程序重新使用时。

Object.prototype.somethingElse=22;
Array.prototype.something=22;
var arr=[1];
for(thing in arr){
  console.log(thing);//0, something,somethingElse
};

除了这个问题之外,您的代码可能会与 Array.prototype.max 的实现冲突的库一起使用。

在 iframe 或 Frame 中,max 函数不存在,因为 (i)frame 中的数组与主页上的数组不同。

而是编写一个可以call或将数组作为额外参数传递的函数:

function max(){
  console.log(this);//<=[1,2]
  return Math.max.apply(Math,this);
};
var arr = [1,2];
max.call(arr);//=2
于 2013-11-13T05:39:03.383 回答
0

它应该是这样的:

var a = new Array();
var b = new Array();

Array.prototype.max = function () {
 alert("Max");
}

b.max();
于 2013-11-13T05:07:00.207 回答
0
> var a = new Array();

a是 Array 对象的一个​​实例,只有Function 对象默认有原型属性。所有对象都有一个[[Prototype]]您无法访问的隐藏属性(除了通过非标准__proto__属性),并在构造它们时引用其构造函数的原型(或以其他方式通过 修改__proto__)。

因此,在尝试解决时:

a.prototype.max 

然后

a.prototype

未定义的,因此尝试获取未定义的最大属性会引发引用错误。

b也是 Array 的一个实例,它没有max属性。即使你这样做:

a.prototype = {max: function(){});

b仍然没有max属性,因为它继承自Array.prototype,而不是a.prototype

PS。请参阅ECMA-262 §15.3.2.1:“为每个函数自动创建原型属性,以提供函数将用作构造函数的可能性。”。

于 2013-11-13T05:07:16.027 回答
0

prototype属性是在函数对象本身上定义的,而不是在实例上。您可以在技术上更新Array.prototypewith youmax函数,但是当前帧(过去和现在)中的所有数组都将具有“max”方法。如果您希望与 3rd 方 JavaScript 一起工作,那么修改原生类的原型是不受欢迎的。如果您想从原生Array类继承,可以使用inherits下面列出的简单函数并调用父类构造函数。有关为什么这种继承方法比其他方法更受欢迎的更详细解释,请查看这篇关于继承函数如何工作的帖子

function inherits(childConstructor, parentConstructor){
    var TempConstructor = function(){};
    TempConstructor.prototype = parentConstructor.prototype; // Inherit parent prototype chain

    childConstructor.prototype = new TempConstructor(); // Create buffer object to prevent assignments directly to parent prototype reference.
    childConstructor.prototype.constructor = childConstructor; // Reset the constructor property back the the child constructor (currently set to TempConstructor )
};

var CustomArray = function(){
    // Normally the below line would suffice, but the native Array class is overloaded in that a cast (or call) returns a new array instance.
    //Array.apply(this, arguments);

    this.push.apply(this, arguments); // This will achive what we originally wanted from `Array.apply(this, arguments);`
}
inherits(CustomArray, Array);

CustomArray.prototype.max = function(){
    var length = this.length;

    if(!length){
        return;
    }

    var maxValue = this[0];

    for(var i = 1; i < length; ++i){
        var value = this[i];

        if(value > maxValue){
            maxValue = value;
        }
    }

    return maxValue;
}




var nativeArray0 = new Array();
var nativeArray1 = new Array(1, 3, 4, 9, 5, 0, 7, 11, 2);

var customArray0 = new CustomArray();
var customArray1 = new CustomArray('c', 'a', 'd', 'b', 'f', 'y', 'g', 'p');

alert('customArray0.max() = ' + customArray0.max());  // undefined
alert('customArray1.max() = ' + customArray1.max());  // y
alert('CustomArray.prototype.max.call(nativeArray1) = ' + CustomArray.prototype.max.call(nativeArray1)); // 11

alert('nativeArray0.length = ' + nativeArray0.length); // 0
alert('nativeArray1.length = ' + nativeArray1.length); // 9
alert('nativeArray1[3] = ' + nativeArray1[3]); // 9

alert('customArray0.length = ' + customArray0.length); // 0
alert('customArray1.length = ' + customArray1.length); // 8
alert('customArray1[3] = ' + customArray1[3]); // b
于 2013-11-13T07:59:33.480 回答
0

prototype属于函数对象,而不是每个对象。

所以Array.prototype是对的,a.prototype是错的。

于 2013-11-13T05:04:38.153 回答