Javascript漂流记(上)__继承模式、命名空间、对象枚举

一、继承模式
       1、传统形式 --> 原型链
             缺点:过多地继承了没用的属性
       2、借用构造函数
             call/apply,可借用别人的方式实现自己的功能。
             缺点:不能继承借用构造函数的原型,且每次构造函数都要多走函数,运行效率偏低

       前两种继承模式详情请参考上节--原型、原型链、call/apply
       3、共享原型
             缺点:不能随便改动自己的原型

            Father.prototype.lastName = 'James';
            function Father(){}
            function Son(){}
            function inherit(Target,Origin){
                Target.prototype = Origin.prototype;
            }
            inherit(Son,Father);
            var son = new Son();
            console.log(son.lastName);//James


       4、圣杯模式(丰满的继承)

            借用中间构造函数F,实现继承。

            function inherit(Target,Origin){
                function F(){}
                F.prototype = Origin.prototype;
                Target.prototype = new F();
                Target.prototype.constructor = Target;//找到对象的构造器
                Target.prototype.uber = Origin.prototype;//找到真正继承自哪个构造函数
            }
            Father.prototype.lastName = 'James';
            function Father(){}
            function Son(){}
            inherit(Son,Father);
            var son = new Son();
            var father = new Father();
            
            //son.__proto__ --> new F().__proto__ -->Father.prototype

             更完美的模式:参考下列代码 

            var inherit = (function(){
                var F = function(){};
                return function(Target,Origin){
                    F.prototype = Origin.prototype;
                    Target.prototype = new F();
                    Target.prototype.constructor = Target;
                    Target.prototype.uber = Origin.prototype;
                }
            }());
            Father.prototype.lastName = 'James';
            function Father(){}
            function Son(){}
            inherit(Son,Father);
            var son = new Son();
            var father = new Father();

二、命名空间:用来管理变量,防止污染全局,适用于模块化开发

       下图是一种原始的方法,只做参考。

        var org = {
            department1: {
                zhangsan: {},
                lisi: {},
                wangermazi: {}
            }
        }
        var zhangsan = org.department1.zhangsan;

        现代化解决方案:闭包,进行模块化开发

        var name = 'bcd';
        var initJack = (function(){
            var name = 'abc';
            function callName(){
                console.log(name);
            }
            return function(){
                callName();
            }
        }());

        initJack();

        方法的链式调用:

        var james = {
            basketball: function(){
                console.log('Cool~~~!');
                //return undefined;
                return this;
            },
            football: function(){
                console.log('Crazy~~~!');
                return this;
            },
            badminton: function(){
                console.log('Good~~~!');
                return this;
            }
        }
        james.basketball().football().badminton();

         访问属性的另一个方法:
         var obj = {name : 'abc'};
         obj.name  --> obj['name'],中括号里必须是字符串,直接写name就成变量了。

        var obj = {
            city1: {name: 'Beijing'},
            city2: {name: 'Shanghai'},
            city3: {name: 'Tianjin'},
            city4: {name: 'Chongqing'},
            sayCity : function(num){
                return this['city' + num];
            }
        }

三、对象的枚举enumeration:

        var obj = {
            name : 'abc',
            age : 13,
            gender : 'male',
            height : 180,
            weight : 80,
            __proto__ : {
                lastname : 'James',
                __proto__ : Object.prototype
            }
        }
        for(var prop in obj){
            if(obj.hasOwnProperty(prop)){
                console.log(prop + " " + typeof(prop));
                //console.log(obj.prop);//实质为obj['prop'],相当于访问prop属性,打印5个undefined
                console.log(obj[prop]);//枚举里面必须写方括号!!!
            }
        }

        for in循环,遍历对象(包括原型链上的属性,任何手动添加的属性,但不包括最顶端的Object.prototype的缺省属性)
        obj.hasOwnProperty(prop);(返回布尔值,判断是否真实的属于自己)
        in:'height' in obj(返回布尔值,属性必须写成字符串。in只能判断此对象能不能调用该属性,原型链上的也返回true)

        instanceof:A instanceof B:返回布尔值,看A对象的原型链上,有没有B的原型!!!如下列代码:

        function Person(){}
        var person = new Person();
        person instanceof Person-->true
        person instanceof Object-->true

        如何区分数组和对象:

        [].constructor;//Array
        var obj = {};
        obj.constructor;//Object
        [] instanceof Array;//true,只能用Array区分
        var obj = {};
        obj instanceof Array;//false
        Object.prototype.toString.call([]);//"[object Array]"
        Object.prototype.toString = function(){
            //识别this
            //返回相应的结果
        }
        var obj = {};
        obj.toString();//"[object Object]"

以上内容属二哥原创,整理自 "渡一教育Javascript课程" ,一个值得推荐的"渡一教育"。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章