简体   繁体   English

为什么我不能覆盖`Array`(`Array.prototype`)的原型?

[英]Why can't I overwrite the prototype of `Array` (`Array.prototype`)?

I set the prototype of Array as an instance of my , I think book.aa will display "aa" , but it displays "undefined" , why? 我将Array的原型设置为my一个实例,我认为book.aa将显示"aa" ,但它显示"undefined" ,为什么? 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>

You cannot assign to Array.prototype because prototype is a read-only property of Array . 您无法分配给Array.prototype因为prototypeArray的只读属性。

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 这就是原因 - 并且看看http://jsfiddle.net/5Ysub/ - 如果你执行

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. bb有效,因为您在创建和设置bb属性时已分配给实际的 Array.prototype

It is a good thing that Array.prototype cannot be whacked, IMHO. 恕我直言,不能打击Array.prototype是一件好事。 :) :)

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. 即使你可以像这样直接覆盖Array.prototype,你也会失去对所有内置方法的访问权限,例如splice,slice,push,shift,pop,unshift,sort,reverse等等......所以它会是可怕的编码实践。 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: 这个微小的代码片段将证明无法覆盖Array.prototype,因为sort方法仍将执行:

<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'; 如果要覆盖Array.prototype的原型属性,则必须一次执行一次,如下所示: Array.prototype.aa='aa';

If you want to apply a large amount of properties to Array.prototype, then apply it through a loop. 如果要将大量属性应用于Array.prototype,请通过循环应用它。 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>

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

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