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>
View Code

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);
View Code

 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);
View Code

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);
View Code

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));
View Code

 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);
View Code

 

posted @ 2016-09-26 14:12  gyz418  阅读(237)  评论(0)    收藏  举报