JavaScript 原型2
注意事项:
1.如果给某个对象的类型的原型添加了某个名为 a 的属性,而这个对象本身又有一个名为a 的同名属性,则在访问这个对象的属性a 时,对象本身的属性“覆盖”了型属性,但是原型属性并没有消失,当你用
delete 运算符将对象本身的属性a 删除时,对象的原型属性就恢复了可见性。利用这个特性,可以为对象的属性设定默认值。
function Person(name) { this.name = name; this.sayName = function () { alert("我的名字:" + name); } } Person.prototype.name = "hongda"; Person.prototype.sayName = function () { alert("My Name is hongda"); } var one = new Person("洪大"); console.dir(Person); console.dir(one); delete one.name; // one.name = undefined; console.dir(one);
2.实际上,将一个对象设置为一个类型的原型,相当于通过实例化这个类型,为对象建立只读副本,在任何时候对副本进行改变,都不会影响到原始对象,而对原始对象进行改变,则会影响到每一个副本,除非被改变的属性已经被副本自己的同名属性覆盖。用delete 操作将对象自己的同名属性删除,则可以恢复原型属性的可见性。
function Person(name) { this.name2 = name; this.sayName = function () { alert("我的名字:" + name); } } Person.prototype.name = "hongda"; Person.prototype.sayName = function () { alert("My Name is hongda"); } var one = new Person("洪大"); var two = new Person("洪大大"); two.name = "hongdada"; console.dir(one); console.dir(two); console.dir(Person);
一个对象副本进行修改时不会影响到类型和类型的原型
function Person(name) { this.name2 = name; this.sayName = function () { alert("我的名字:" + name); } } Person.prototype.name = "hongda"; Person.prototype.sayName = function () { alert("My Name is hongda"); } var one = new Person("洪大"); var two = new Person("洪大大"); console.dir(one); console.dir(two); Person.prototype.name = "hongda11"; console.dir(one); console.dir(two);
当类型的原型进行修改时将影响到每一个对象副本。
3.使用prototype进行继承
与反射集合使用
<script type="text/javascript"> var class1 = function () { } class1.prototype = { method: function () { alert("method"); }, method2: function () { alert(2); } } function class2() { } for (var p in class1.prototype) { class2.prototype[p] = class1.prototype[p]; } class2.prototype.method2 = function () { alert("method2"); } var obj1 = new class1(); var obj2 = new class2(); console.dir(obj1); console.dir(obj2); </script>
//为类添加静态方法inherit表示继承于某类 Function.prototype.inherit = function (baseClass) { for (var p in baseClass.prototype) { this.prototype[p] = baseClass.prototype[p]; } }
class2.inherit(class1);
在 prototype-1.3.1 框架中,首先为每个对象都定义了一个extend方法:
//为Object 类添加静态方法:extend Object.extend = function (destination, source) { for (property in source) { destination[property] = source[property]; } return destination; } //通过Object类为每个对象添加方法extend Object.prototype.extend = function (object) { return Object.extend.apply(this, [this, object]); }
<script type="text/javascript"> Object.extend = function (destination, source) { for (property in source) { destination[property] = source[property]; } return destination; } //通过Object类为每个对象添加方法extend Object.prototype.extend = function (object) { return Object.extend.apply(this, [this, object]); } var class1 = function () { } class1.prototype = { method: function () { alert("method"); }, method2: function () { alert(2); } } function class2() { } class2.prototype = (new class1()).extend({ method2: function () { alert("method2"); } }); var obj1 = new class1(); var obj2 = new class2(); obj1.method2();//2 obj2.method2();//method2 </script>
<script type="text/javascript"> Object.extend = function (destination, source) { for (property in source) { destination[property] = source[property]; } return destination; } //通过Object类为每个对象添加方法extend Object.prototype.extend = function (object) { return Object.extend.apply(this, [this, object]); } var class1 = function () { } class1.prototype = { method: function () { alert("method"); }, method2: function () { alert(2); } } function class2() { } class2.prototype = class1.prototype.extend({ method2: function () { alert("method2"); } }); var obj1 = new class1(); var obj2 = new class2(); obj1.method2();//method2 obj2.method2();//method2 </script>
注意这两个不一样
第一个是对类型的其中一个对象副本(new class1)进行了extend,并将其拷贝给了class2,类的原型没有改变。
第二个是对类(class1)的原型进行了修改