Function.prototype Javascript

时间:2015-11-11 16:05:26

标签: javascript

下面是我为了解Function.prototype

而编写的示例JS代码
<script>

    function Foo() {

    }

    Foo.prototype = {
        a: 9
    };

    var x = new Foo();
    var y = new Foo();

    console.log('x : ' + x.a + '\n');
    console.log('y : ' + y.a + '\n');

    x.a = 1;

    console.log('x : ' + x.a + '\n');
    console.log('y : ' + y.a + '\n');


</script>

我原以为执行上面的代码会导致输出

x:9 y:9 x:1 y:1

但实际输出是

x:9 y:9 x:1 y:9

有人可以解释为什么最后一个console.log打印9而不是1。

3 个答案:

答案 0 :(得分:3)

x.a = 1;不会更改prototype属性。它只为x分配了一个新的“本地”属性,它隐藏了原型上定义的属性。

x.a === 1; //true because x.a === 1;
y.a === 9; //true because y.__proto__.a === 9;

您可以使用Foo.prototype.a = 1;更改prototype属性。但是让我这样说:这种原型的使用至少是不常见的。通常,原型包含方法,而不包含实例之间共享的属性。对象的属性,通常在实例本身上定义。定义(或模拟)静态属性的一种常用方法如下:

Foo.a = 9;

然后,每当您想要使用或更改它时,您都可以简单地参考Foo.a

答案 1 :(得分:2)

因为x和y是单独的实例。您可以将变量x和y设置为相同的实例

<script>

function Foo() {

}

Foo.prototype = {
    a: 9
};

var x = new Foo();
var y = x;
// the same is:
// var x, y;
// x = y = new Foo();

console.log('x : ' + x.a + '\n');
console.log('y : ' + y.a + '\n');

x.a = 1;

console.log('x : ' + x.a + '\n');
console.log('y : ' + y.a + '\n');


</script>

写下你的期望。

答案 2 :(得分:2)

您只是在对象的一个​​实例('x')上更改属性,而不是在原型上。

要使原型继承起作用,您必须将其设置在原型对象本身上,然后两个实例都将进行更改。

    <script>

    function Foo() {

    }

    Foo.prototype = {
        a: 9
    };

    var x = new Foo(); // x.a === 9
    var y = new Foo(); // y.a === 9

    console.log('x : ' + x.a + '\n'); // === x: 9
    console.log('y : ' + y.a + '\n'); // === y: 9

    x.a = 1; // changed only for the 'x' instance

    console.log('x : ' + x.a + '\n'); // === x: 1, because you changed it
    console.log('y : ' + y.a + '\n'); // y: 9, because it inherited from the prototype.

</script>

如果您希望两个实例(实例x和实例y)都具有=== 9,那么您需要修改原型。

Foo.prototype = { a: 1 };
var x = new Foo(); // x.a === 1
var y = new Foo(); // y.a === 1

修改对象的实例不会修改原始对象的原型,只修改它的特定实例。