声明:
概念性介绍会简单穿插,以过程式分析问题为主,便于提高实践的意义。
前言:
面向对象,早已烂熟于耳,以java为最,php5.6之后更是扩展了面向对象式开发(起先引入对象概念,没当个大方向,这下无心插柳柳成荫,繁盛起来了),js也基于对象式开发了。。。
开扒:
但是,JS没有类的概念,是构造函数和原型链的方式来体现的。
我这里仅通过1个例子(有点懒~),尽量全面的分析下实现过程。
/*=================定义“类”=================*/
/*=======父类Foo=======*/
function Foo(name,age){
this.name = name; //this是当前 [调用FOO()构造函数的] 对象,如果有子类Bar继承则代表子类对象
this.age = age; //this.参数名,则意味着各个对象,有属于自己的名字和年龄
} //如上,是对象间差异化、独立性的体现
/*父类Foo的原型*/
Foo.prototype = { //在此定义Foo对象公有的方法/属性,以节省内存、便于维护(性能上:如果把sayHi()方法定义在了Foo(name,age)构造函数中,等于说每new一个Foo或子类对象,每个对象在堆内存就会多占点空间来存放sayHi()方法,耗内存啊。)
sayHi:function(){ //公有方法
alert("Hi,I'm "+this.name);
},
guess:888 //公有属性
};
/*=======子类Bar=======*/
function Bar(name,age,sex){
Foo.call(this,name,age); //等同于Foo.apply(this,[name,age]);你要初始化的东东,父类搞好了,只管调用
this.sex = sex; //Bar对象本身的特有属性
}
/*子类Bar的原型是个Foo对象*/
Bar.prototype = new Foo(); //Bar的原型类=Foo对象,意味着Bar对象能调到本身没有却在(Foo对象或者Foo.prototype)中存在的属性或方法
//创建并调用
var bar = new Bar('Lin',18,'male');
bar.sayHi();
运行效果:
案例补充说明:
1)var bar = new Bar('Lin',18,'male');
解释:
new 一个 Bar对象,名为bar.
bar就继承了Foo类的属性和Foo原型上的方法。
2)bar.sayHi(); //可调
解释:
bar对象,首先自身查找是否有sayHi()方法,没有则bar.__proto__得到Bar.prototype;
在Bar.prototype这个原型对象中继续查找,而前面我们已指定Bar.prototype = new Foo();
则意味着是在Foo对象中查找,然而Foo对象本身没有sayHi()方法;
则调用(new Foo()).__proto__得到原型对象Foo.prototype;
继续在该原型对象Foo.prototype中查找sayHi()方法;
终于找到了!!!返回结果吧。
扩展:
如果依然没找到,就会Foo.prototype.__proto__得到Object.prototype,
Object.prototype本身没有sayHi()方法,就会
Object.prototype.__proto__得到null.
null是最顶级的对象。在该对象中,查无此方法,就报错了;查无此属性,就undefined.
涉及术语:
原型链
各构造函数,各有与之相对应的原型;
类之间的继承,就暗暗的把原型间的关系统筹在了一起。
顶层原型上方法或属性的查找过程,就是依靠着原型间的这种关系,一层一层的向上查找的。
原型继承
Bar.prototype = new Foo();
借用继承
Foo.call(this,name,age); //Foo.apply(this,[name,age]);
组合继承
function Bar(name,age,sex){
Foo.call(this,name,age);
this.sex = sex;
}
Bar.prototype = new Foo();
现象式总结:
仅是原型继承,子类Bar确实可调用(父类Foo的属性和原型上的方法)了,但实例化出来的Bar对象就不独立了。意味着某个对象对Foo构造函数中的属性或方法的修改,会影响到其他对象调用的结果.
简言之,子类可调父类了,但是实例化的对象不独立。
仅是借用继承,子类bar实例化的对象是独立的,对象间不受影响,但父类原型上的方法调不了了.
推荐组合继承,既保证了对象间的独立性,又能调用到父类的原型上的方法。
福利:
1.原型链图示(网上找的,看懂即可跳过上述内容)
该图把原型和构造函数间的关系理的很清楚,可在Google浏览器的console运行demo并查看对象下原型间的关系。
2.JS高级部分,之前看的是ali的Bosn的JavaScript深入浅出
如有不适内容,欢迎指正。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。