- 多态
- 封装
- 原型模式
- 基于原型模式的继承javascript对象
1.多态
多态的实际含义是:同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。换句话说,给不同的对象发哦少年宫同一个消息的时候,这些对象会根据这个消息分别给出不同的反馈。 多态最根本的作用就是吧通过过程化的条件分子语句转换为对象的多态性,从而消除这些条件分支语句。
var googleMap = { show:function(){ console.log("开始渲染Google地图"); } }; var baiduMap={ show :function () { console.log('开始渲染百度地图'); } }; //如果要添加一个搜搜地图 var sosoMap={ show:function(){ console.log('开始渲染搜搜地图'); } } var renderMap = function(map){ if(map.show instanceof Function){ map.show(); } } renderMap(googleMap); renderMap(sosoMap);
2.封装
封装的目的是将信息隐藏,封装应该被视为“任何形式的封装”,也就是说,封装不仅仅是隐藏数据,还包括隐藏实现细节,设计细节以及隐藏对象类型等。
var myObject = (function(){ var _name = 'SarmTom'; //私有成员变量 return { //公开public方法 getName:function(){ return _name; } }; })
我们创建的每一个函数都有一个prototype(原型)属性
,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。如果按照字面意思来理解,那么prototype就是通过调用构造函数而创建的原型对象
。使用原型对象的好处是可以让所有对象实例共享它包含的属性和方法。换句话说,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中
。
function Person(){}; Person.prototype.name = 'SmarTom'; Person.prototype.age = 29; Person.prototype.job = "Soft Engineer"; Person.prototype.syaName=function(){ console.log(this.name); } var a = new Person(); a.syaName();
使用克隆原型的模式
var Plane = function(){ this.blood = 100; this.attackLevel = 1; this.defenseLevel = 1; } var plan = new Plan(); plan.blood = 500; plane.attackLevel = 10; plane.defenseLevel = 7; var clonePlan = Object.create(plane); console.log(clonePlan); //输出:Object{blood:500,atackLevel:10,defenseLevel:7} //在不支持Object.create方法的浏览器中,则可以使用一下代码 /* Object.create = Object.create || function(object){ var F = function(){}; F.prototype = obj; return new F(); } */
3.JavaScript中的原型继承
- 所有的数据都是对象。
- 要得到一个对象,不是通过实例化,而是找到一个对象原型并克隆它。
- 对象会记住它的原型。
- 如果对象无法响应某个请求,它会把这个请求委托给自己的原型。
1.所有数据都是对象
JavaScript除了undefined之外,一切都是对象,为了 实现
这个目标,number,boolean,string,这几种基本类型数据
也可以通过“包装类”的方式编程对象类型的数据处理。
事实上,javascript中的跟对象Object.prototype对象。Object.prototype对象是一个空的对象。
我们再JavaScript中遇到的每一个对象,实际上都是从Object.prototype对象克隆出来的,
Object.prototype对象就是它们的原型。比如
var obj1 = new Object(); var obj2 = {};
2.要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并克隆它。
function Person(name){ this.name = name; } Person.prototype.getName = function(){ return this.name; } var a = new Person('SmarTom'); console.log(a.name); //SmarTom console.log(a.getName()); //SmarTom console.log(Object.getPrototypeOf(a)==Person.prototype); //true
在JavaScript中没有类的概念,在这里Person并不是类,而是函数构造器,JavaScript函数既可以作为普通函数被调用,也可以作为构造器被调用。
当使用new运算符来调用函数时,此时的函数就是一个构造器。
用new运算符来创建对象的过程,实际上也只是先克隆Object.prototype对象,在进行一些其它操作的过程。
3.对象会记住它的原型
JavaScript给对象提供了一个名为__proto__的隐藏属性,某个属性的__proto__属性会指向它的构造器的原型对象,即{Constuctor}.prototype。
var a = new Object(); console.log(a.__proto__ ===Object.prototype); //结果为true
4.如果对象无法响应某个请求,它会把这个请求委托给它的构造器的原型
var obj = {name:'SmarTom'}; var A = function(){}; A.prototype = obj; var a = new A(); console.log(a.name);
我们来看这段代码解释器做了哪些事情:
- 首先,尝试遍历执行a中的所有属性,但没有找到name这个属性
- 查找name属性的这个请求被委托给对象a的构造器的原型,它被a.__proto__记录着并且指向A.prototype,而A.prototype被设置成为对象Obj;
- 在对象obj中查找到了name属性,并返回它的值。
var A = function(){}; A.prototype = {name:"SmarTom"}; var B = function(){}; B.prototype = new A(); var b = new B(); console.log(b.name); //输出SmarTom
在看这段代码执行的时候,引擎做了那些事情
- 首先,尝试遍历b中的属性,但没有找到name这个属性。
- 查找name属性的请求被委托给对象B的构造器的原型,它被b.__proto__记录着并且指向B.prototype,而B。prototype被设置为一个通过new A()创建的对象。
- 在该对象中依然没有找到name属性,于是请求被继续委托给这个对象构造器的原型A.prototype。
- 在A.prototype中找到了name属性,并返回它。
最后还要留意一点,原型链并不是无限长的。现在我们尝试访问对象a的address属性。对象b和它的构造器原型上没有address属性,那么这个请求最终会被返回为undefined。