但是还有一个问题,就是识别的问题,因为根本无法搞清楚他们到底是哪个对象的实例。
1.构造函数
function CreateObject(name,age){ //创建一个对象,使用构造函数的对象都是Object this.name=name; //添加一个属性 this.age=age; this.run=function(){ //添加一个方法 return this.name+this.age+'运行中...' } } var box=new CreateObject('link',200); //实例化 var box1=new CreateObject('html',300);//实例化 alert(box.run()); alert(box1.run());
1.构造函数没有new Object,是因为后台自动var obj=new Object();
2.this就相当于obj。
3.构造函数不需要返回对象引用,它是后台自动返回的。
ps:
构造函数也是函数,函数名必须首字母大写,CreateObject(name,age)
必须new构造函数方法名,new CreateObject('link',200);
必须使用new运算符
2.原型
我们创建的每个函数都有一个Prototype(原型),这个属性是一个对象,它的用途就是包含可以由特定类型的所有实例共享的属性和方法。
可以理解成:prototype通过调用构造函数而创建的那个对象的原型对象。
使用原型的好处可以让所有对象实例共享它所包含的属性和方法,也就是说,不必在构造函数中定义对象信息,而是可以直接将这些信息添加到原型中。
function Box(){} //构造函数函数体内什么都没有,这里如果有,也叫做实例函数,实例方法 Box.prototype.name="link"; //原型属性 Box.prototype.age=25; Box.prototype.run=function(){ //原型方法 return this.name+this.age+"运行中..." } var Box1=new Box(); var Box2=new Box(); alert(Box1.run()) //如果是实例方法,不同的实例化,他们的方法地址是不一样的,是唯一的 //如果是原型方法,那么他们地址是共享的,大家都是一样 alert(Box1.run()==Box2.run()) //true
如果是实例方法,不同的实例化,他们的方法地址是不一样的,是唯一的。
如果是原型方法,那么他们地址是共享的,大家都是一样。
为了进一步了解构造函数的声明方式和原型模式的声明方式,我们通过图示来了解一下。
在原型模式声明中,多于两个属性都是创建对象时自动生成 __proto__属性是实例指向原型对象的一个指针,
它的作用就是指向构造函数的原型属性constructor。通过这两个属性,就可以访问到原型里的属性和方法了。
ps:IE浏览器在脚本访问__proto__会不能识别,火狐和谷歌级其他浏览器可以识别,虽然可以输出,但是无法获取内部信息。
判断一个对象是否指向了构造函数的原型对象,可以使用isPrototypeOf()方法来测试。
alert(Box.prototype.isPrototypeOf(Box1)); //弹出true alert(Object.prototype.isPrototypeOf(Box1)); //弹出true
原型模式的执行流程:
1.先查询构造函数实例里的属性和方法,如果有,立即返回。
2.如果构造函数实例里没有,就去它的原型对象里去找,如果有,立即返回。
虽然我们可以通过对象实例访问保存原型中的值,但是不能访问通过对象实例通过对象实例重写原型中的值。
function Box(){} //构造函数函数体内什么都没有,这里如果有,也叫做实例函数,实例方法 Box.prototype.name="link"; //原型属性 Box.prototype.age=25; Box.prototype.run=function(){ //原型方法 return this.name+this.age+"运行中..." } var Box1=new Box(); var Box2=new Box(); Box1.name="html"; //实例属性,并没有重写原型属性 alert(Box1.name); //就近原则 弹出html