您的位置:首页 > 其它

prototype为对象添加属性和方法

2017-05-18 09:41 351 查看
可以通过prototype来为已经定义好的的"类"添加属性和方法。这里来了解一下prototype的基础知识。prototype是"构造函数"的属性,不是实例的属性.

示例:



function HiClass() {
this.sayHi = function(){
alert("hi");
}
}

var obj = new HiClass();
alert(HiClass.prototype);//outputs [object, object]
alert(obj.prototype);//outputs undefined




 

在用prototype的方式实现继承一个类的时候,要注意其可能覆盖别的prototype方式添加的属性和方法。如果HiClass.prototype.prop = 'value'是在HiClass.prototype = new HelloClass()之前则不会有prop属性,如果在执行HiClass.prototype = new HelloClass()之后,HiClass的实例中会有prop属性,这个应该很好理解。但是要注意代码中不要不小心存在这样的bug。

示例:



function HiClass() {
this.sayHi = function(){
alert("hi");
}
}

function HelloClass() {
this.sayHello = function(){
alert("hello");
}
}
//HiClass.prototype.prop = 'value';  //this.prop = function(){}写法是可以继承的,两种写法有区别滴
HiClass.prototype = new HelloClass();
HiClass.prototype.prop = 'value';

var obj = new HiClass();
obj.sayHello();
alert(obj.prop);




 

在JavaScript中有一个prototype链,在对一个对象实例上调用方法或者获取属性的时候,先看实例对应的类有没有对应的定义,没有的话会沿着prototype链一直找,找不到则为undefined。如果某类都有
定义,则调用本身的定义。Object.prototype.foo = function(){}会对所有以定义的方法起作用,javascript中Object对象是所有对象的基类


示例:



function Object2() {
this.sayHi = function(){
alert("hi Object2");
}
}

function Object3() {
this.sayHi = function(){
alert("hi Object3");
}

this.sayHello = function(){
alert("hello Object3");
}

}

Object2.prototype = new Object3();

var obj = new Object2();
obj.sayHi();  //hi Object2    调用obj.sayHi();的时候,sayHi在Object2里已经定义,则调用本身的定义。
obj.sayHello();  //hi Object3

Object.prototype.foo = function(){  //会对所有以定义的方法起作用,javascript中Object对象是所有对象的基类
alert("f00 Object");
};
obj.foo();  //f00 Object
Object2.foo(); //f00 Object
Object3.foo(); //f00 Object
a.foo();    //报错




 

如果在实例里添加的属性和方法与prototype里的属性和方法重名,相对于实例和prototype都有这个属性和方法,只是由于prototype链的访问顺序,先访问到实例中的属性和方法。如下面的例子说明了这一点



function Test(){};

Test.prototype.prop1 = 'prop value';

var obj = new Test();  //obj如果是一个方法又不一样喽;obj.prototype = new Test();不会继承滴

obj.prop1 = 'instance value';

alert(obj.prop1 );//outputs instance value

alert(obj.hasOwnProperty("prop1"));//outputs true

delete obj.prop1;alert(obj.prop1 ); //outputs prop value  由于prototype链的访问顺序,先访问到实例中的属性和方法,删除的是第一个属性
alert(obj.hasOwnProperty("prop1"));//outputs false
alert("prop1" in obj);//outputs true

delete Test.prototype.prop1;alert(obj.prop1 );//outputs undefined




 

再来看看一些构造函数和prototype的使用:



var myObj = {
prop1:'value1',
prop2:'value2'
}

Object.prototype.foo = function(){
alert("f00 Object");
};

//等价于
//var myObj = new Object();
//myObj.prop1 = 'value1';
//myObj.prop2 = 'value2';

alert(myObj.prop2);  //value2
myObj.foo();    // f00 Object




 

同时也可以如下的方式对prototype赋值,可以一次添加多个属性和方法



function TestCls(){

}
TestCls.prototype = {  //可以一次添加多个属性和方法
prop1:'value1',
prop2:'value2'
};
myObj = new TestCls();
alert(myObj.prop2);  //value2




 

上面的做法中有一个问题是改变prototype后,constructor也改变了。

所以要将prototype.constructor之前的值,比如第一个例子中要加上 HiClass.prototype.constructor=HiClass;constructor 属性返回对创建此对象的数组函数的引用



//上面的做法中有一个问题是改变prototype后,constructor也改变了。
//所以要将prototype.constructor之前的值,比如第一个例子中要加上 HiClass.prototype.constructor=HiClass
function HiClass() {
this.sayHi = function(){
alert("hi");
}
}

function HelloClass() {
this.sayHello = function(){
alert("hello");
}
}

HiClass.prototype = new HelloClass();
HiClass.prototype.constructor=HiClass  //constructor 属性返回对创建此对象的数组函数的引用。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: