多态
var goolgMap = {
show: function () {
console.log('显示谷歌地图');
}
}
var sosoMap = {
show: function () {
console.log('显示搜搜地图')
}
}
var baidu = {
show: function () {
console.log('显示百度地图');
}
}
function renderMap(map) {
if (map.show instanceof Function) {
map.show();
}
}
renderMap(sosoMap);
renderMap(goolgMap);
renderMap(baidu);
在这个例子中,我们假设每个地图 API 提供展示地图的方法名都是 show,在实际开发中也许不会如此顺利,这时候可以借助适配器模式来解决问题。 (适配器模式) 做什么(公共的部分进行封装) 谁去做(不同的部分封装为不同的类)
实现了私有属性和公共方法
//这里是一个闭包
var myObj = (function () {
var name = 'sven'; //这里形成了一个私有的属性
return {
getName: function () { //这里是一个公共的方法
console.log(name);
}
}
})();
console.log(myObj.getName()); //输出了name
console.log(myObj.name); //输出的undefined;
//原型模式
var Plane = function () {
this.blood = 100;
this.attacklevel = 1;
this.defenselevel = 1;
}
var plane = new Plane;
plane.blood = 500;
plane.attacklevel = 100;
plane.defenselevel = 200;
var clonePlane = Object.create(plane);
console.log(clonePlane); //使用克隆的原型模式 克隆是创建对象的手段
事实上,JavaScript 中的根对象是 Object.prototype 对象。Object.prototype 对象是一个空的对象。我们在 JavaScript 遇到的每个对象,实际上都是从 Object.prototype 对象克隆而来的, Object.prototype 对象就是它们的原型。比如下面的 obj1 对象和 obj2 对象
var obj1 = new Object();
var obj2 = {};
console.log(Object.getPrototypeOf(obj1) === Object.prototype);
console.log(Object.getPrototypeOf(obj2) === Object.prototype);
原型链
对象->proto- ->Constructor.prototype ->Object.prototype;
每个对象都有一个隐藏属性_proto_ 某个对象的__proto__属性默认会指向它的构造器的原型对象即{Constructor}.prototype __proto__就是对象跟“对象构造器的原型”联系起来的纽带对象构造器的原型并不仅限于Object.prototype 上,而是可以动态指向其他对象
原型链继承
正是因为构造器的原型并不仅限于 Object.prototype 上,而是可以动态指向其他对象从而产生了原型链继承的方式
这样一来,当对象 a 需要借用对象 b 的能力时,可以有选择性地把对象 a 的构造器的原型指向对象 b,从而达到继承的效果。下面的代码是我们最常用的原型继承方式
var obj = { name: 'sven' };
var A = function () { };
A.prototype = obj;//A的构造器原型指向了obj对象从而达到继承的效果
var a = new A();
console.log(a.name); //输出了sven
执行上面的代码引擎做哪些事情首先,尝试遍历a对象所有属性,但没有name属性查找name属性的这个请求委托给对象a的构造器的原型,它被a._proto_记录并且指向了A.prototype,而A.prototype被设置为对象obj。在obj中找到了name属性,并且返回它的值
var A = function () { };
A.prototype = { name: 'sven' };
var B = function () { };
B.prototype = new A();
var b = new B();
console.log(b.name);
最后还要留意一点,原型链并不是无限长的。现在我们尝试访问对象 a 的 address 属性。而对象 b 和它构造器的原型上都没有 address 属性,那么这个请求会被最终传递到哪里呢?实际上,当请求达到 A.prototype,并且在 A.prototype 中也没有找到 address 属性的时候,请求会被传递给 A.prototype 的构造器原型 Object.prototype,显然 Object.prototype 中也没有address 属性,但 Object.prototype 的原型是 null,说明这时候原型链的后面已经没有别的节点了。所以该次请求就到此打住,a.address 返回 undefined。