首页 > 代码库 > js中原型的重新赋值后的变化

js中原型的重新赋值后的变化

以前总是认为,在构造函数的原型发生改变的时候,所有的构造实例,无论是新的还是已经创建过的,其跟原型相关的属性值都会发生改变,今天发现不是这样的……

function CreateUser(){        }        CreateUser.prototype.name = "one";        var user1 = new CreateUser();        CreateUser.prototype = {            name:"two",            age:22,            active:function(){                return CreateUser.prototype.name;            }        }        var user2 = new CreateUser();        alert(user1.name);//one        alert(user2.name);//two        alert(user1.active());//Uncaught TypeError: undefined is not a function 

我们看一下上边的弹出结果,第一个是one,第二个是two,而第三个是Uncaught TypeError: undefined is not a function 

也就是说新定义的原型对象并没有将原始的原型对象覆盖,原始的原型对象依旧在内存当中。

然后,重新理了一下思路,觉得正确的理解应该是这样的,

一:新创建一个构造函数的时候,该构造函数有一个prototype属性指向该函数的原型对象,然后每一个构造实例也都有一个指针(内部属性)指向该构造函数的原型对象,也就是构造函数中的prototype中存储的引用地址跟构造实例中的指针存储的引用地址是相同的。

二:上述例子中的CreateUser.prototype的重新赋值,是将CreateUser.prototype总保存的引用地址更改为新创建对象的地址,这个并不能表明原始的原型对象的覆盖,原始的原型对象依旧保存在内存当中;也就能够说明user1.name为什么还是one了,因为其包含的引用地址依旧是原始构造函数的,且指向对象并未覆盖。

三:新创将的构造函数实例中的指针包含的引用地址是跟CreateUser.prototype中的引用地址相同的,所以也就能够说明为什么user2.name是two,因为在创建user2对象的时候

  CreateUser.prototype中的引用地址已经发生改变;

下边出一个小测试,跟上边的原理是一样的,如果你理解了,说明上边的你也理解了:

var arr = [1,2,3,4,5];var arr1 = arr;arr = [6,7,8,9,10];alert(arr1[0]);//1

 

js中原型的重新赋值后的变化