美文网首页
原型链模式-拓展

原型链模式-拓展

作者: 阿九是只大胖喵 | 来源:发表于2017-03-02 21:39 被阅读0次

    批量设置原型上的原型和方法
    方法一

        var pro = Fn.prototype; // 把原来原型指向的地址赋值给pro,现在他们操作的是同一个内存地址
        pro.getX = function () {
            console.log(this.x);
        }
        pro.getY = function () {
    
        }
        var f1 = new Fn();
    

    方法二
    重构原型对象的方式 -> 自己新开辟一个堆内存,存储公有属性和方法,把浏览器原来给Fn.prototype开辟的那个替换掉。

        function Fn() {
            this.x = 100;
        }
        Fn.prototype = {
            // 手动增加constructor指向:
            constructor: Fn,
            a: function () {
    
            },
            b: function () {
    
            },
            c: function () {
    
            }
        }
        var f = new Fn();
        f.a();
        f.b();
        f.c();
    
    1. 只有浏览器天生给Fn.prototype开辟的堆内存里面才有constructor,而我们自己开辟的这个堆内存没有这个属性, 这样constructor指向就不再是Fn而是Object了
        console.log(f.constructor); // -> 没做任何处理前,Object
        // 为了和原来的保持一致,需要手动的增加constructor指向
    
    1. 用这种方式给内置类增加公有的属性
      例如:给内置类Array增加一个数组去重的方法
        Array.prototype.unique = function () {
    
        }
        Array.prototype = {
            constructor: Array,
            unqiue: function () {
                // 这种方式不行
            }
        }
        console.dir(Array.prototype);
    

    这种方式会把之前存在于原型上的属性和方法替换掉,所以用这种方式修改内置类的话,浏览器是会将其屏蔽的。
    但是我们可以一个个的修改内置类的方法,通过下述方式在数组的原型上增加方法,如果方法名和原来内置的重复了,会把内置的方法修改了。 -> 我们以后再内置类的原型上增加方法,命名都需要加特殊的前缀。

        Array.prototype.sort = function () {
            console.log(this); // this -> ary 当前要操作的数组
        }
        var ary = [1, 2, 3, 3, 1, 3, 4, 12];
        ary.sort();
    

    在原型模式中,this常用的有两种情况:
    在类中,this.xxx = xxx;this -> 当前类的实例。
    某一个方法中的this -> 看执行的时候 "." 前面是谁,this就是谁。

    1. 需要先确定this的指向(即this是谁)。
    2. 把this替换成对应的代码。
    3. 按照原型链查找的机制,一步步的查找结果。
        function Fn() {
            this.x = 100;
            this.y = 200;
            this.getY = function () {
                console.log(this.y);
            }
        }
        Fn.prototype = {
            constructor: Fn,
            y: 300,
            getX: function () {
                console.log(this.x);
            },
            getY: function () {
                console.log(this.y);
            }
        };
        var f = new Fn();
        f.getX(); // -> console.log(f.x) -> 100
        f.__proto__.getX(); // -> this 是f.__protoo_ -> console.log(f.__proto__.x) -> undefined
        Fn.prototype.getX(); // -> this 是Fn.prototype -> Fn.prototype.x -> undefined
    
        f.getY(); // -> f.y -> 200
        f.__proto__.getY(); // -> this是f.__proto__ -> f.__proto__.y -> 300
    

    在内置类的原型上拓展一个方法,用于数组去重

        Array.prototype.myUnique = function () {
            // this -> ary
            var obj = {};
            for (var i = 0; i < this.length; i++) {
                var cur = this[i];
                if (obj[cur] === cur) {
                    this[i] = this[this.length - 1];
                    this.length--;
                    i--;
                    continue;
                }
                obj[cur] = cur;
            }
            obj = null;
            return this; // 目的是为了实现链式写法
        }
    

    链式写法:执行完数组的一个方法,可以紧接着执行下一个方法。
    原理:
    ary为什么可以使用sort方法? -> 因为sort是Array.prototype上的公有的方法,而数组是ary是Array的一个实例,所以ary可以使用sort方法 -> 只有数组才能使用Array原型上定义的属性和方法。
    sort执行完成的返回值是一个排序后的"数组",所以可以继续执行reverse()。
    reverse执行完成的返回值也是一个"数组",所以可以继续执行pop()。
    pop()执行完成的返回值是被删除的最后一个元素,不是一个数组了,所以在执行数组相关操作会报错。

        ary.sort(function (a, b) {
            return a - b;
        }).reverse().pop();
        ary.myUnique(); // this -> ary
        Array.prototype.myUnique(); // this -> Array.prototype
        console.log(ary);
    

    相关文章

      网友评论

          本文标题:原型链模式-拓展

          本文链接:https://www.haomeiwen.com/subject/zcwkgttx.html