刚开始接触对象原型时大脑就开始起义了,脑子就转不灵清了。就感觉怎么着这个概念就是灌输不进去,俗称断路。后面找了很多资料,最主要的还是要借助于《JavaScript语言精髓》这本书,让我对这此豁然开朗,希望说的不对的地方请给予指正,谢谢。
一、什么是原型?
原型包含一个对象("prototype"对象),是构造函数特有的属性。将所有实例对象共享的属性和方法放在里面,不需要共享的属性和方法则放在构造函数里面。它能继承私有和共享属性和方法。
二、prototype实例
首先创建一个构造函数,具有name属性。
function Person(name){
this.name = name;
}
构造函数创建好之后,我想创建两个实例,并且输出他们的name值。
var p1 = new Person("张三");
var p2 = new Person("李四");
console.log(p1.name+","+p2.name); /* 输出张三,李四*/
那现在我想给p1张三在添加一个eat属性,我要他可以吃饭(food),那既然你张三都可以吃饭,那我李四要要吃饭,那我也输出p2.eat,但是结果是undefined……如下所示。
p1.eat = "food";
console.log(p1.eat); /* 输出food */
console.log(p2.eat); /* 输出undefined */
原来是张三自己偷偷摸摸的去吃饭,没让李四知道,哎╮(╯▽╰)╭。那既然这样,Person就不得不添加一个共用属性eat了,得让大家一起吃饭呀。
Person.prototype.eat = "food";
console.log(p1.eat); /* 输出food */
console.log(p2.eat); /* 输出food,我也可以吃饭了…… */
添加Person.prototype.eat = "food"这个以后,eat属性就被添加到原型库中,eat属性就可以共享了(李四说“太好了,我也可以吃饭了o(≧v≦)o~~”)。这个属性和方法(方法类似处理)的问题就解决了,那如果出现两个对象Person和Student,Person还是具有构造函数的name属性和用prototype添加的eat属性,我想让Student继承Person中所有的属性和方法,请看第三点。
三、prototype继承实例
首先创建Person和Student构造函数(为了方便看,构造函数和实例输出一起写了)。
function Person(name){
this.name = name;
}
Person.prototype.eat = "food";
function Student(name,eat){
Person.apply(this,arguments); /* 继承构造函数,即私有属性 */
}
var s1 = new Student("王五","food");
console.log(s1.name); /* 输出 王五 */
console.log(s1.eat); /* undefined */
Student要继承Person中的属性,添加Person.apply(this,arguments) (标注:apply中this表示实例化的对象s1,arguments是new Student()中的参数,这是系统执行的),表示Student继承Person中属性。创建一个实例s1,s1输出正常,为什么s1.eat输出undefined?Person中不是已经添加了eat属性吗?为什么还不行呢?我找啊找,最终发现原来是Person.apply(this,arguments)只能继承构造函数中的属性,哎,真是弱爆了。那我想要继承原型中的属性怎么办?那容易,请看下面代码。
Student.prototype = new Person(); /* 继承原型,即共享属性 */
var s1 = new Student("王五","food");
console.log(s1.name); /* 输出 王五 */
console.log(s1.eat); /* 输出 food */
添加一个Student.prototype = new Person()就可以了。
这里做一个特别解释:
Student具有prototype这个属性的原因是因为它是一个function一个构造函数,前面我提到过,这个是构造函数特有的属性。如果student是这样的。
var student = {
name: "张三"
}
那就要报错了,说student不是一个function。这个是大家特别注意的。
还有为什么要new Person()呢,这个和java中类似,但是在javascript中只针对于构造函数(构造函数中函数命名和类命名类似,首字母要大写),其他不需要new。
有哪里讲解的不好或者是不正确的地方,希望大家能第一时间反馈给我,希望和大家共同进步,谢谢。