5

I set the prototype of Array as an instance of my, I think book.aa will display "aa", but it displays "undefined", why? Thanks!

   <html>
    <head>
        <title>Array Properties</title>
        <h2>Array Properties</h2>
        <script type="text/javascript">
            function my() {
                this.aa = 'aa';
            }
            Array.prototype = new my();
            Array.prototype.bb = "bb";
            var book = new Array();  
            book[0] = "War and Peace";  

        </script>
    </head>
    <body bgcolor="lightblue">
        <script type="text/javascript">
            document.write(book.aa+book.bb);
        </script>
    </body>

    </html>

2 Answers 2

7

You cannot assign to Array.prototype because prototype is a read-only property of Array.

So when you write

Array.prototype = new my();

nothing happens. To see why, try

JSON.stringify(Object.getOwnPropertyDescriptor(Array, "prototype"))

The result is

"{"value":[],"writable":false,"enumerable":false,"configurable":false}"

Unless you are in strict mode, the assignment silently fails.

That's why -- and see http://jsfiddle.net/5Ysub/ -- if you execute

function my() {
    this.aa = 'aa';
}
Array.prototype = new my();
Array.prototype.bb = "bb";
var book = new Array();
book[0] = "War and Peace";
document.write(book.aa+book.bb);

You get

undefinedbb

The bb works because you have assigned to the real Array.prototype when you created and set the bb property.

It is a good thing that Array.prototype cannot be whacked, IMHO. :)

Sign up to request clarification or add additional context in comments.

Comments

0

Even if you could override Array.prototype directly like that, you would lose access to all the built-in methods such as splice, slice, push, shift, pop, unshift, sort, reverse and many others... So it would be terrible coding practice. But it doesn't work as Ray pointed out because it is read only.

This tiny code piece will demonstrate that Array.prototype cannot be overridden because the sort method will still execute:

<script type="text/javascript">
Array.prototype={};
var a=new Array(1,4,5,7,8);
a.sort();
alert(a.join(","));
</script>

If you want to override prototype properties for Array.prototype, you must do it one at a time like so: Array.prototype.aa='aa';

If you want to apply a large amount of properties to Array.prototype, then apply it through a loop. Here is some code I wrote for you which should accomplish exactly what you are trying to do:

<script type="text/javascript">
function my()
{
    this.aa = 'aa';
}
my.prototype.bb = "bb";
var instance = new my();
for(var j in instance)
{
    if(instance.hasOwnProperty(j) || j in my.prototype)
    {
        Array.prototype[j]=instance[j];
    }
}

var book=new Array();
book[0]="War and Peace";
alert(book.aa);//alerts "aa"
alert(book.bb);//alerts "bb"
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.