简体   繁体   English

无法扩展JavaScript原型

[英]Unable to extend javascript prototype

I am just playing around with the idea of subclassing with Javascript. 我只是在玩用Java子类化的想法。 I like to pretend that extending native objects (like Array, String etc) is a bad idea. 我喜欢假装扩展本地对象(例如Array,String等)是一个坏主意。 This, however true, is completely out of my understanding as to why. 无论如何,这都是我完全无法理解的原因。

Having said that, let's get on with it. 话虽如此,让我们继续吧。

What I'm trying to do is to extend Array (now, extend may not be right term for what I'm doing) 我正在尝试扩展数组(现在, extend可能不是我正在做的事情的正确术语)

I want to create my new class MyArray and I want to have 2 methods on it. 我想创建我的新类MyArray并希望有2个方法。 .add and .addMultiple . .add.addMultiple

So I implemented it like this. 所以我是这样实现的。

function MyArray(){
    var arr = Object.create(Array.prototype);
    return Array.apply(arr, arguments);
}

MyArray.prototype = Array.prototype;

MyArray.prototype.add = function(i){
    this.push(i);
}

MyArray.prototype.addMultiple = function(a){
    if(Array.isArray(a)){
        for(var i=0;i<a.length;i++){
            this.add(a[i]);
        }
    }
}

This works correctly, but if I do 这可以正常工作,但是如果我这样做

console.log(Array.prototype.addMultiple );
console.log(Array.prototype.add);

I get [Function] and [Function] . 我得到[Function][Function] So this means my code is modifying the native Array object. 因此,这意味着我的代码正在修改本机Array对象。 Something that I am trying to avoid. 我想避免的事情。 How do I change this code in a way that those two console.log s will give me undefined but I am still able to use native Array.prototype methods like .push ? 如何更改代码,以使这两个console.log可以给我undefined的方式,但是我仍然可以使用.push类的本机Array.prototype方法?

TIA TIA

You should setup proper prototypes chain: 您应该设置适当的原型链:

function MyArray(){
    Array.apply(this, arguments);
}

MyArray.prototype = Object.create(Array.prototype);

Object.create just creates new object with specified prototype, so after this operation following is true: Object.create只是使用指定的原型创建新对象,因此在执行此操作之后,以下条件为真:

MyArray.prototype !== Array.prototype; // true
Object.getPrototypeOf(MyArray.prototype) === Array.prototype; // true

This: 这个:

MyArray.prototype = Array.prototype; MyArray.prototype = Array.prototype;

results in MyArray.prototype pointing to the same object as Array.prototype. 导致MyArray.prototype指向与Array.prototype相同的对象。 So everything you do to MyArray.prototype after that will also be done to Array.prototype. 因此,之后对MyArray.prototype所做的所有操作也将对Array.prototype进行。

A way to solve this is to instead store a shallow copy of Array's prototype in MyArray: 解决此问题的一种方法是将Array原型的浅表副本存储在MyArray中:

MyArray.prototype = clone(Array.prototype); MyArray.prototype = clone(Array.prototype);

I copied that from here: 我从这里复制了它:

Copy prototype for inheritance? 复制原型进行继承?

use class extension 使用类扩展

 class MyArray extends Array { add(i) { this.push(i); return this; } addMultiple(a) { if (Array.isArray(a)) { for (var i = 0; i < a.length; i++) { this.add(a[i]); } } return this; } } var test = new MyArray(); test.addMultiple([1,2,3,4,5]).add(6).add(7); console.log(test, test.indexOf(6)); 

Object.create(Array.prototype);

This just creates a new object and return the objects. 这只是创建一个新对象并返回这些对象。

So as per your scenarios, you have just created array object and added some methods to your array object - MyArray. 因此,根据您的方案,您刚刚创建了数组对象,并向数组对象添加了一些方法-MyArray。 It will affect the native Array. 它将影响本机数组。

You're just modifying your cloned object. 您只是在修改克隆的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM