javascript prototype本质

来源:互联网 发布:45型驱逐舰对比055知乎 编辑:程序博客网 时间:2024/05/22 16:06

将一个对象设置为一个类型的原型,相当于通过实例化这个类型,为对象建立只读副本,在任何时候对副本进行改变,都不会影响到原来对象,而对原来对象进行改变,会影响到每一个副本,除非被改变的属性已经被副本自己的同名属性覆盖。用delete操作将对象自己的同名属性删除,则可以恢复原型属性的可见性。

原型属性修改的正确方法.html

<html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"></head><body><script>function ClassA(){    this.onlyReady = true;}function ClassB(){}ClassB.prototype = new ClassA();var classB = new ClassB();alert("1.1没有进行任何修改之前的onlyReady:" + classB.onlyReady);//下面的做法不是修改原型属性的正确做法classB.onlyReady = false;  //这个是给classB对象添加一个同原型属性onlyReady一样的属性alert("2.1给classB对象添加同原型属性onlyReady一样的属性:" + classB.onlyReady);delete classB.onlyReady;alert("2.2删除classB对象同原型属性同名的onlyReady属性之后:" + classB.onlyReady);//正确修改原型属性ClassB.prototype.onlyReady = false;alert("3.1通过ClassB.prototype.属性名修改原型属性的值:" + classB.onlyReady);//classB.prototype.onlyReady = 5;//语法错误</script></body>

prototype的行为类似于C++中的静态域,将一个属性添加为prototype的属性,这个属性将被该类型创建的所有实例所共享,但是这种共享是只读的。在任何一个实例中只能够用自己的同名属性覆盖这个属性,而不能改变它。


采用prototype定义的属性和方法称为静态属性和静态方法,或者原型属性和原型方法,把用this定义的属性和方法称为共有属性和共有方法。

尽管采用prototype和采用this定义的属性和方法在对象调用的形式上是一致的,以致于在一段代码中甚至很难严格区分,但是用“静态”两个字还是很好的诠释了prototype的数据存储上的特质,即所有的实例共享唯一的副本。这一点和C++中的static成员非常相似,但是和C#不同,C#中的static方法的调用形式是通过类型的“.”运算符,这相当于JavaScript中的类属性和类方法。


通过prototype能够以一个对象为原型,安全地创建大量的实例,这就是prototype的真正含义,也是它的价值所在。由于prototype仅仅是以对象为原型给类型创建副本,因此它也具有很大的局限性。首先,它在类型的prototype域上并不是表现为一种值拷贝,而是一种引用拷贝,这带来了“副作用”。改变某个原型上引用类型的属性的属性值,将会彻底影响到这个类型创建的每一个实例。

原创粉丝点击