在上一篇(一)中,创建了一个构造函数People():
function People(name,age,genger){
this.name=name;
this.age=age;
this.genger=genger;
this.sayName=function(){
alert(this.name);
};
}
此时我们只需要创建People的实例即可:
var peo=new People("胡歌",34,"男");
var peo1=new People("杨紫",28,"女");... ...
但是此时出现了一个新的问题,创建多少个People的实例sayName方法就执行了多少次,这样会很占据空间,所以我们需要将其以函数形式提取出来(因为执行多次来做一模一样的事是毫无意义的),但是不能直接提取到全局中来,因为这样会污染全局很不安全,所以需要用到原型:
关于原型:
我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype,这个属性对应着一个对象,以下结果输出为一个对象[object Object],即原型对象;
function MyClass(){
}
document.write(MyClass.prototype);
如果函数作为普通函数调用prototype没有任何作用,当以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性(__proto__),指向该构造函数的原型对象,可以通过__proto__来访问该属性:(结果输出为[object Object])
function MyClass(){
}
var mc=new MyClass();
document.write(mc.__proto__);
MyClass函数对象和通过MyClass创建的对象mc指向的[object Object]是同一个对象:
document.write(mc.__proto__==MyClass.prototype); //返回true
所以MyClass函数对象和通过MyClass创建的对象mc均指向一个对象[object Object],即原型对象
所以,针对文章开头的问题,可以将代码修改为:
function People(name,age,genger){
this.name=name;
this.age=age;
}
People.prototype.sayName=function(){
console.log(this.name);
};
即原型对象就相当于一个公共的区域,可以将所有的公共的部分存放在一块
hasOwnProperty检测
function Myclass(){
}
Myclass.prototype.name="原型里的name";
var mc =new Myclass();
console.log("name" in mc); //该结果返回true
可以用in来检查mc对象中是否含有name属性,以上mc中是不含name的,但是返回结果为true,因为如果对象中没有但原型中有,也会返回true,所以可以用对象的hasOwnProperty()方法来检测:
function Myclass(){
}
Myclass.prototype.name="原型里的name";
var mc =new Myclass();
// console.log("name" in mc);
console.log(mc.hasOwnProperty("name")); //该结果返回false
hasOwnProperty()方法从哪里来的?显然我们并没有定义,可以依次往下找:
console.log(mc.hasOwnProperty("hasOwnProperty")); //false
console.log(mc.__proto__.hasOwnProperty("hasOwnProperty")); //false
console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty")); //true
* 所以,原型对象也是对象,它也有原型,当我们使用一个对象的属性或方法时,会先在自身中寻找,如果没有则向原型中寻找,如果还没有则向原型的原型中寻找,直到找到Object,如果在Object中依然没有找到,则返回undefined,并不是无穷尽。