javascript设计模式与开发实践
1. js面向对象6种形式(详情)

<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <script> // 1. 基于object的对象 var person=new Object(); person.name='my name'; person.getName= function () { return this.name+' is aa'; } console.log("person.getName: "+person.getName()); //2.对象字面量方式 var person2={ name:'person2', getName: function () { return this.name+' is bb'; } } console.log("person2.getName: "+person2.getName()); //3.工厂模式 function createPerson3(name,age){ var o=new Object(); o.name=name; o.age=age; o.getName=function(){ return this.name+' is cc'; } return o;//使用return返回生成的对象实例 } var person3=createPerson3('person3',12); console.log("person3.getName: "+person3.getName()); // 4.构造函数模式 function Person4(name,age){ this.name=name; this.age=age; this.getName= function () { return this.name+" is dd"; } } var person4=new Person4('person4',22); console.log("person4.getName: "+person4.getName()); //5 原型模式 function Person5(){ } Person5.prototype.name='person5'; Person5.prototype.age=22; Person5.prototype.getName= function () { return this.name+" is ee"; } var person5=new Person5(); console.log("person5.getName(): "+person5.getName()); // 6 组合构造函数及原型模式 function Person6(name,age){ this.name=name; this.age=age; } Person6.prototype={ construct:Person6,//原型字面量方式会将对象的constructor变为Object,此外强制指回Person getName: function () { return this.name+" is ff"; } } var person6=new Person6('person6',22); console.log("person6.getName(): "+person6.getName()); </script> </body> </html>
2.静态类型语言:编译时便已确定变量的类型 如 java: int a = 1;
动态类型语言:待变量被赋予某个值之后,才会具有某种类型 如 javascript : var a=1;
javascript面向接口编程: 一个对象如果有lenght属性,也可以依照下标来存取属性,那这个对象就可以被当作数组来使用。【鸭子类型】
3.多态
多态:给不同的对象发送同一消息,这些对象会根据这个消息分别给出不同的反馈。【主人向家禽发出“叫”的命令,鸡会“咯咯咯“,鸭会”嘎嘎嘎“】
把不变的部分隔离出来,把可变的部分封装起来

// 多态 把相同的隔离出来,动物都会叫, // 把不同的封装起来,不同动物不同叫声。 var makeSound= function (animal) { animal.sound(); } var duck= function () {} duck.prototype.sound= function () { console.log("嘎嘎嘎: "); } var chicken= function () { } chicken.prototype.sound=function(){ console.log("咯呼呼: "); } makeSound(new duck()); // ? 为什么要用new ? makeSound(new chicken()); var dog= function () { } dog.prototype.sound= function () { console.log("旺旺旺: "); } makeSound(new dog()); console.log("typeof dog: "+typeof dog); // 这个简单点! var cat={ sound: function () { console.log("喵喵喵"); } } makeSound(cat); //=================== 多态简单版 google============== var googleMap={ show: function () { console.log("google : " ); } } var baiduMap={ show: function () { console.log("baidu;"); } } var renderMap= function (type) { type.show(); } renderMap(googleMap); renderMap(baiduMap);
4.js模拟封装 public private 、 object.create()

//js模拟封装 非必须 private public ES6 有更好的方式 var my=(function () { var __name='aaa'; // private return { getName: function () { return __name; // public } } })(); console.log("my.getName(): "+my.getName()); console.log("my.__name: "+my.__name); // 直接警告出错了。。 // javascript 要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并克隆它 Object.create() /* 兼容ie Object.create=Object.create || function (obj) { var F= function () {}; F.prototype=obj; return new F(); } */ var Plane= function () { this.blood=100; } console.log("typeof plane: "+typeof plane); var plane=new Plane(); plane.blood=110; var clonePlane=Object.create(plane); // 新飞机 console.log("clonePlane: "+clonePlane.blood); var clonePlane2=Object.create(new Plane()); //老飞机 console.log("clonePlane2: "+clonePlane2.blood);
5.构造器创建对象效率比object.create()高 原型继承

// 常用原型继承 var obj={name:'aaa'}; var A= function () {} A.prototype=obj; var a=new A(); console.log("a.name: "+a.name); // 构造器创建对象 效率比 object.create()高,但构造器底层也是object.create() // ES6有新的方式 function Person10(name){ this.name=name; } Person10.prototype.getName= function () { return this.name; } var b=new Person10('xxx'); console.log("b.name: "+b.name);
6. js闭包、单例、函数作用域

// 【函数】内变量的作用域: 没加var为全局变量,加var为局部变量 // 函数里面可以访问到函数外面的变量, 函数外面无法访问到函数里面的变量 var func= function () { var a=1; console.log("a: "+a); }; func(); // alert(a); // undefined //闭包,解决局部变量的问题,把一些不需要暴露在全局的变量封装成私有变量,防止被修改 //使用闭包封装私有变量 var user=(function () { var __name='sven', __age=22; // 约定用 __ 表示私有 return{ getUserInfo: function () { return __name + __age; } } })(); console.log("user.__name: "+user.__name); // 访问不到 console.log("user.getUserInfo(): "+user.getUserInfo()); // 可以访问 // js中的单例 var test={}; // 独一无二,可全局访问 //为了减少全局变量,可使用对象字面量的方式 var namespace1={ a:function(){alert(1);}, b:function(){alert(2);} } //怪异的写法,不懂。。。 var strategies={ "S": function (salary) { return salary*4; }, "A": function (salary) { return salary*3; }, "B": function (salary) { return salary*2; } }; var calc= function (level, salary) { return strategies[level](salary); // 真怪异 } console.log("calc: "+calc('S',20000)); console.log("calc2: "+calc('A',10000));
7.闭包

//闭包,解决局部变量的问题,把一些不需要暴露在全局的变量封装成私有变量,防止被修改 //使用闭包封装私有变量 var user=(function () { var __name='sven', __age=22; // 约定用 __ 表示私有 return{ getUserInfo: function () { return __name + __age; } } })(); console.log("user.__name: "+user.__name); // 访问不到 console.log("user.getUserInfo(): "+user.getUserInfo()); // 可以访问 console.log("typeof user: "+typeof user); /* 闭包 读取函数内部的变量,把变量的值始终保持在内存中*/ function f1(){ var n=999; function f2(){ console.log(n); } return f2; } var res=f1(); res(); //网上经典闭包 //f1(); //闭包2 function f11(){ var test=111; tmp_test= function () { return test; } } function f2(){ console.log("测试一: "+tmp_test()); var test1=tmp_test(); console.log("测试二: "+test1); } f11(); f2(); //闭包作用1: 使用闭包代替全局变量 // 全局变量 stu1 var stu1='aa'; function st1(){ console.log("stu11: "+stu1); } st1(); console.log("stu1: "+stu1); //使用闭包 ,这种简单。。。。。。。 (function () { var stu2='bb'; function st2(){ console.log("stu2: "+stu2); } function a(){ console.log("闭包stu2: "+stu2); } st2(); a(); })(); console.log("undefined stu2: "+stu2);