但是还有一个问题,就是识别的问题,因为根本无法搞清楚他们到底是哪个对象的实例。
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