zoukankan      html  css  js  c++  java
  • [js]js中原型的继承

    js继承01

    思路:
    
    单例/工厂/构造函数--演进到原型
    搞清原型结构
    
    原型继承
        模拟系统原型继承
        实现自己的继承
        观察原型继承特点
    

    演进到原型链这一步

    
    //单例模式: 防止变量名冲突:
    // 思路: 本空间调用其他空间的方法-->本空间调用自己空间的方法
    /*var utils = {
        show: function () {
            console.log('utils.show');
        }
    };
    
    var search = {
            show2: function () {
                console.log('search.show2');
                utils.show();
            },
            show3:function () {
                this.show2();
            }
        };
    
    search.show2();
    // search.show2
    // utils.show*/
    
    //工厂模式: 节约了代码
    /*function people(name, age) {
        obj = {};
        obj.name = name;
        obj.age = age;
        obj.show = function () {
            console.log(this.name, this.age);
        };
        return obj;
    }
    
    p1 = people("maotai",22);
    p1.show();*/
    
    //构造函数: 类属性和方法每个实例会有一份
    /*
    function people(name,age) {
        this.name = name;
        this.age = age;
        this.show = function () {
            console.log(this.name,this.age);
        }
    }
    p1 = new people('maotai',22);
    p1.show(); //maotai 22
    
    p2 = new people('maomao',19);
    p2.show(); //maomao 19
    console.log(p1.show == p2.show); //false
    */
    
    
    //原型模式: 实现方法共享
    思路: 共有部分放到原型上(方法), 私有部分放到自己空间(属性)
    /*
    function people(name, age) {
        this.name = name;
        this.age = age;
    }
    
    people.prototype.show = function () {
        console.log(this.name, this.age);
    }
    p1 = new people('maotai', 22);
    p1.show(); //maotai 22
    
    p2 = new people('maomao', 19);
    p2.show(); //maomao 19
    console.log(p1.show == p2.show); //true <----------------比上一种优化点
    */
    

    原型及圆形继承

    - 知识前提
        类属于function类型, 天生有prototype属性,指向一个对象(constructor[类本身]+__prototype)
        实例属于object类型, 天生有__proto__属性,指向所属类的prototype
        
        function A() {
            this.name = 'maotai'          //name属于类A的私有属性
        }
        A.prototype.show = function () {  //方法为了实例间公用,都放在prototype上.
            console.log(this);
        };
    
    
    - 原型继承: 将B的prototype指向new A.
    
    - 模拟系统原型继承
        function myObject() {
    
        };
    
        function myEventTarget() {
    
        };
    
        myEventTarget.prototype = new myObject;
        myEventTarget.prototype.addListener = function () {
    
        };
    
        function myNode() {
    
        }
    
        myNode.prototype = new myEventTarget;
        myNode.prototype.createElement = function () {
    
        };
    
        var n = new myNode;
        console.dir(n);
    
    1,原型链继承特点
        1,将B将A的私有属性继承了, 当作了B的共有属性
        2,原型继承是索引的执行, 并非属性的添加. 和父子之间基因继承不一样, 病不是把A类的属性和方法克隆一份给B,而是让B和A之间增加原型链的链接.
    
    - 实现自己的原型继承: 下面有内存图
    
        function A() {
            this.name = 'maotai'
        }
    
        function B() {
            this.name = 'maomao'
        }
    
        B.prototype = new A;
    
        var n = new B;
        console.dir(n);
    

    构造函数中的细节知识点

    - 构造函数中的细节知识点
    
    js中的函数3种角色:
        类
        普通函数
        对象
        
    思路: 原型类和实例化写法 -- 类中this的2种情况
    
        function Fn() {
            this.name = 'maomao';
            this.getName = function () {
                console.log(this.name);
                console.log(this);
            }
        }
    
        var f = new Fn;
        f.getName();//方法中this是f
        var ss = f.getName;
        ss();       //方法中this是window
        
    1.如果无参,Fn()省掉(),写成 Fn
    2.this当前类的实例
    
    
    - 思路: 搞函数局部变量和类属性区别(各自独立,没啥关系).
    function fn = (){num=10;this.x = 100;}
    f1 = new fn();
    f1.num //undefined
    
    
    函数执行3步骤(开辟私有作用域):
    1, 形参赋值
    2, 预解释
    3, 代码从上到下执行
    
    - 类中自定义返回值,将类默认返回覆盖了.
    
        function Fn() {
            this.name = 'maomao';
            this.getName = function () {
                console.log(this.name);
                console.log(this);
                return {'name':'ssssssss'}
            }
        }
    
        var f = new Fn; //f变为{'name':'ssssssss'}
        
    
    //检测数据类型
    思路: 实例属于类 -- 检测是否为f1的属性 -- 检测是否为f1的私有属性 -- 检测是否为f1的共有属性
    
    
    
    typeof                  //缺点: 只能检测到object类
    arr instanceof Array    //优点: 检测某个实例是否属于类,可以检测是object的arr?number
    
    'name' in f1   //name是f1的一个属性
    f1.hasOwnProperty('name') // 检测私有属性
    
    
        function Fn() {
            this.name = 'maotai';
        };
        Fn.prototype.age = 22;
        Fn.prototype.getName = function () {
            console.log(this.name);
        }
        var f1 = new Fn;
        //f1是Fn的实例
        console.log(f1 instanceof Fn); //true
        //f1有属性age
        console.log('age' in f1);      //true
    
        //f1有私有属性name
        console.log(f1.hasOwnProperty('name'));//true
    
        //自己实现: f1的共有属性
        function hasPubProperty(obj,att) {
            return (att in obj) && !obj.hasOwnProperty(att);
        };
        console.log(hasPubProperty(f1, 'age')); //true
    
    - 构造函数中的细节知识点
    
    js中的函数3种角色:
        类
        普通函数
        对象
        
    思路: 原型类和实例化写法 -- 类中this的2种情况
    
        function Fn() {
            this.name = 'maomao';
            this.getName = function () {
                console.log(this.name);
                console.log(this);
            }
        }
    
        var f = new Fn;
        f.getName();//方法中this是f
        var ss = f.getName;
        ss();       //方法中this是window
        
    1.如果无参,Fn()省掉(),写成 Fn
    2.this当前类的实例
    
    
    - 思路: 搞函数局部变量和类属性区别(各自独立,没啥关系).
    function fn = (){num=10;this.x = 100;}
    f1 = new fn();
    f1.num //undefined
    
    
    函数执行3步骤(开辟私有作用域):
    1, 形参赋值
    2, 预解释
    3, 代码从上到下执行
    
    - 类中自定义返回值,将类默认返回覆盖了.
    
        function Fn() {
            this.name = 'maomao';
            this.getName = function () {
                console.log(this.name);
                console.log(this);
                return {'name':'ssssssss'}
            }
        }
    
        var f = new Fn; //f变为{'name':'ssssssss'}
        
    
    //检测数据类型
    思路: 实例属于类 -- 检测是否为f1的属性 -- 检测是否为f1的私有属性 -- 检测是否为f1的共有属性
    
    
    
    typeof                  //缺点: 只能检测到object类
    arr instanceof Array    //优点: 检测某个实例是否属于类,可以检测是object的arr?number
    
    'name' in f1   //name是f1的一个属性
    f1.hasOwnProperty('name') // 检测私有属性
    
    
        function Fn() {
            this.name = 'maotai';
        };
        Fn.prototype.age = 22;
        Fn.prototype.getName = function () {
            console.log(this.name);
        }
        var f1 = new Fn;
        //f1是Fn的实例
        console.log(f1 instanceof Fn); //true
        //f1有属性age
        console.log('age' in f1);      //true
    
        //f1有私有属性name
        console.log(f1.hasOwnProperty('name'));//true
    
        //自己实现: f1的共有属性
        function hasPubProperty(obj,att) {
            return (att in obj) && !obj.hasOwnProperty(att);
        };
        console.log(hasPubProperty(f1, 'age')); //true
    
    原型扩展
        1.重新赋值,导致constructor指向object,需要恢复
        2.确定this是谁的顺序
        
        function Fn() {
            this.x = 100;
            this.y = 200;
            this.getX = function(){
                console.log(this.x);
            }
        };
    
        Fn.prototype = {
            constructor: Fn,
            y: 300,
            getX: function () {
                console.log(this.x);
            },
            getY: function () {
                console.log(this.y);
            }
        };
    
        var f = new Fn;
        f.getX(); //100  1,this是f, 2.f.x 在私有里有,所以100
        f.__proto__.getX(); //300  1.this是f.__proto__, console.log(f.__proto__),忽略私有,直接去原型上找, 无, 去object找,无,undefined
    
        Fn.prototype.getX(); //undefined
    
        f.getY(); //200
        f.__proto__.getY();// 300
        // 1.先确定this是谁
        // 2.把this替换为对应的代码
        // 3.按照原型链查找顺序
    

    这里为何纠结this?  可以引出数组的链式写法.
    
    
        //执行原型上方法的3种方式
        Array.prototype.myUnique=function () {
            
        }
        Array.prototype.myUnique();
        var arr = [];
        arr.myUnique();
        arr.__proto__.myUnique();
    
        var ary = [12, 23, 34, 12, 23, 34, 12, 23, 34, 12, 23, 34, 12, 23, 34];//->Array ->Object
    
        //->内置方法的链式写法:执行完成上一个方法,返回的结果依然是当前类的实例,这样就可以继续执行下一个方法了
        //    ary.sort(function (a, b) {
        //        return a - b;
        //    }).reverse().pop().push(100);
        //    console.log(ary);
    
    
        //->给方法起名字的时候加一个自己的前缀myXxx,防止把内置的方法覆盖掉
        Array.prototype.myDistinct = function myDistinct() {
            //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.myDistinct().push(100);
        console.log(ary);
    
    

    函数的3种角色

    继承和核心:
    所有类都是函数数据类型的一个实例

        //1、函数在整个JS中是最特殊的也是最重要的也是最难的
        //->在JS中我们的函数有三种角色:
    
        //普通的函数(优先级最高的角色):因为它可以执行形成私有的作用域->形参赋值(arguments)->预解释->代码执行(return)->作用域的销毁或者不销毁... fn instanceof Function ->true
    
        //类:new执行,创建出自己的实例,有自己的原型,函数体中的this.xxx=xxx中的this是当前类的实例...
    
        //普通的对象:和var obj;中的obj一样,就是个对象名,有自己的属性... fn instanceof Object ->true
    
        //->函数的三种角色让其具有了多面性,但是每一种角色和其他的角色都是互不影响的
    
        //2、Function函数类
        //->每一个函数数据类型都是Function这个类的一个实例
    

    json数据绑定 浏览器回流,重绘


  • 相关阅读:
    go-go协程
    linux-pclint代码检测
    linux-32位-交叉编译openssl
    go-json类
    mysql-定时任务
    go-IO操作
    go-异常处理-error-panic-recover
    go-defer语句
    go-select
    go-指针
  • 原文地址:https://www.cnblogs.com/iiiiiher/p/8982760.html
Copyright © 2011-2022 走看看