基于实例的 JavaScript 继承
Instance based JavaScript Inheritance
我的问题与JavaScript继承有关,
var a = new Array();
var b = new Array();
a.prototype.max = function () {
alert("Max");
}
b.max();
根据我的理解,b.max() 会给出错误说 b 没有最大值,但令人惊讶的是(对我来说)它在第 3 行 a 没有原型时给了我错误。 当我做类型a时,它给了我对象,对象可以具有原型属性。我阅读JavaScript遵循原型继承,即基于实例的继承,所以我的问题是我已经创建了一个Array实例,但原型属性仍然没有定义。
你能解释一下我哪里出错了,或者我没有正确理解什么概念吗
> var a = new Array();
a
是 Array 对象的实例,默认情况下只有函数对象具有原型属性。所有对象都有一个隐藏的 [[Prototype]]
属性,您无法访问该属性(通过非标准 __proto__
属性除外),并在构造它们时引用其构造函数的原型(或通过 __proto__
进行修改)。
因此,在尝试解决时:
a.prototype.max
然后
a.prototype
未定义,因此尝试获取未定义的max 属性会引发引用错误。
b
也是 Array 的一个实例,但它没有 max 属性。即使您这样做:
a.prototype = {max: function(){});
b
仍然没有 max 属性,因为它继承自 Array.prototype
,而不是 a.prototype
。
附言。请参阅 ECMA-262 §15.3.2.1:"为每个函数自动创建一个原型属性,以提供将该函数用作构造函数的可能性。
prototype
属于函数对象,而不是每个对象。
所以Array.prototype
是对的,a.prototype
错的。
它应该是这样的:
var a = new Array();
var b = new Array();
Array.prototype.max = function () {
alert("Max");
}
b.max();
最好不要扩展像 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) 帧中的数组与主页上的数组不同。
而是编写一个函数,您可以call
数组或将数组作为额外的参数传递:
function max(){
console.log(this);//<=[1,2]
return Math.max.apply(Math,this);
};
var arr = [1,2];
max.call(arr);//=2
prototype
属性是在函数对象本身而不是实例上定义的。从技术上讲,您可以使用max
函数更新Array.prototype
,但是当前帧(过去和现在)中的所有数组都将具有"max"方法。 如果您希望与第三方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
- 以jquery方式继承Javascript
- JavaScript对象不是从原型链继承的
- 数据与Javascript中的继承冲突
- JavaScript对象继承问题
- Javascript嵌套函数属性继承
- 从类构造函数继承javascript
- Loaded()内容赢得't继承javascript
- 原型继承JavaScript在不同函数中使用变量
- 通过调用祖先函数继承JavaScript
- 如何从核心OpenERP 6.1继承javascript
- 安全地继承JavaScript中的原型
- 对经典和原型继承Javascript的混淆
- 不同文件中构造函数之间的部分继承(JavaScript)
- TypeScript:如何继承javascript构造函数
- 在c++中继承JavaScript函数
- 我如何继承javascript函数
- 通过__proto__原型来继承JavaScript是否不好
- 原型继承-Javascript原型:替换与添加
- 原型继承 - JavaScript 公开原型属性
- 多重继承 - JavaScript hasOwnProperty