zoukankan      html  css  js  c++  java
  • 面向对象 [记录]

    面向对象 VS 面向过程
      
      过程:流程式写法 - 到哪步该干啥
      对象:所有程序执行都是从对象出发

      [] {} null
    var a = new Image() | object()
      对象拥有属性和方法

      啥时候用|好处:(功能|方法)
        01 所有功能都从对象出发以达到一个对象实现某种功能的效果
          (比如JQ都是从对象出发 JS,JQ互不污染)
        02 面向对象可支持扩展(继承)
     
    var a = new object();
    a.name='XXX';
    a.show = function(){};
    
    function peo(){return obj;}
    peo('xxx')  -->  里面this指window(peo内部)
    new peo('xxx')  -->  
        在函数执行前+new
            01 在函数内部自然会产生一个对象并this指向这个对象
            02 函数默认返回产生的对象
    
    this指向
         function a(){alert(this);}
         var k = a();  -->  window  -->  k = undefined
         var k = new a();  -->  obj  -->  k = obj (默认返回)
            // new a() 代码相当于
             // var obj = {};
             // alert(this);
             // return obj;
             // 相当于多了2条 不用写 默认return
         构造函数
             function peo(k){
                 this.name = k;
                 this.fn = function(){};
             }
    工厂模式
        (构造函数就是工厂模式 | 工厂=加工东西) = 简化后的构造函数 (默认要有原料 默认要出工厂)
        原料(var obj=new object())  -->  加工(obj.name='xxx')  -->  出厂(return obj)
    通常构造函数第一个字母大写
        Peo{a=10;}
        obj1.fn == obj2.fn   -->  false    -->   对象所属对象都不一样
            老李家的狗和老王家的狗不一样,obj1和obj2是不同的
        对象的赋值和引用
            obj1.a == obj2.a   -->  true !!!!!
    
        比较的时候 对象和函数作比较时 不仅仅要内容一样还要存储位置|地址都要一样
        数字,字符串,bool比较 只要内容一样 就好了
    
        new一个对象就要开辟空间去存储
    原型
        prototype 不用让一样的东西总是去开辟空间存储
        只有构造函数有原型(一个函数是不是构造函数是看如何调用的 用new去调用的就是)
    
        Peo.prototype.fn = function(){}  公有写原型中
            此时 obj1.fn == obj2.fn    -->  true !!!!! (公有)
        私有属性写构造函数里,公共属性写prototype里面,原型的方法里面的this指向的是你执行的时候的对象
            谁去执行this就指向谁(obj1执行就指向obj1,obj2执行就指向obj2)
    
        原型好处:节约内存空间
    
        但 this.name 不共享
            function Peo(name){this.name = name;}  <-- 私有
            Peo.prototype.fn = function(){}  <-- 公有
    方法链
        $('#box').css({}).click().animation()     -->   这个就是
        function Peo(name,age){
            this.name = name;
            this.age = age;
        }
        Peo.prototype.fn1 = function(){!!!重点 return this;}
        Peo.prototype.fn2 = function(){!!!重点 return this;}
        p1 = new Peo('xxx',22);
        p1.fn1().fn2();   需要p1.fn1()是一个对象 那么fn1和fn2里面 return this
    包装对象
        对于非对象的数据类型是由包装对象产生的
        是对象的:
            数组 var arr = new Array();
                 var arr = [1,2,3,4];
            arr.push   <--  push 在构造函数原型中(prototype中)
            那么 Array.prototype.push = function(){} 那么push就被重构了,没了
        写类似push的方法
            function(){
                var argu = arguments;
                for (var i = 0; i < argu.length; i++) {
                    this[this.length]=argu[i];
                }
            }
    
        非对象:
            字符串 对象才能.点 | 对象才能.方法
            var str = 'qwer'
            str.charAt(2);  str拥有string函数--包装对象
            string.prototype.charAt = function(){}
            Array 和 String 差别:
                string只有.点方法才出来 之后消失
    
            +自定义属性 str.number = 10;
                alert(str.number)   -->   undefined
                解释:因为它不是个对象
                    去原型prototype找,因为他不是个对象,
                    那么去原型找就会产生一个对象(产生一个叫包装对象的东西),number=10,
                    和string相关联去访问 string.prototype后对象销毁
                每次产生新的包装对象
                str.number --> 产生对象 number=10  -指向-> string.prototype --> 对象死亡
                    number 不是string的  |  执行完包装对象立马死亡
                alert(str.number)
                    str.number --> 产生对象(包装对象)  --> string.prototype
                这里两个包装对象不相等
                给非对象.点number(不存在)
                     --> 就会产生一个包装对象来执行.点操作
                     --> 操作完之后对象立马死亡
                     --> alert又会产生一个包装对象
                     --> 此时你给上一个包装对象赋值,这个对象拿不到赋值,2个对象不一样
                         上一个对象死亡,用完一次死一次,临时的
    原型链 _proto_
        对象和他的构造函数的关系
        构造函数a(它是有原型链的a.prototype) -->  创建出对象objA对象
            说的是 a.prototype 和 objA 之间的关系
        function A(n){this.n=5;}
        A.prototype.n=10;  (!!! A.prototype 是个对象 )
        此时 alert(a1.n)   =  5
        按原型链去找 
         --> 自己有n属性吗?有 有了之后就不会再去找
         --> 没有则就去构造函数找
         --> A.prototype 是个对象 对象有构造函数(假设B) -- 构造函数有原型
    
         [A]构造函数 ---创建出(new)---> objA
          | [A]有原型
         [A.prototype] *** 和objA有关系 ***
                       | [A.prototype]是个对象能.点
                      | 是对象就有构造函数 假设B
                    [B]
                     | 
                    [B.prototype]  *** 和 A.prototype有关系 ***
                     | 
                    [...]
                     | 
                    [object] 一直到祖宗 到根
                     | 
                    [object.prototype]
    
        往下找 一直找到obj都没有则 undefined
    
        如:object.prototype.number = 10;
            objA  --> A.prototype --> B.prototype --> ...  --> object.prototype
    原型链默认属性
        对象原型里面本来就有默认的属性和方法
        hasOwnProperty是不是对象自己的属性 返回bool
            在原型里的则false
            在A(){里面} 它自己本身(即私有的)
            如:arr   push:false | length: true
        constructor 属性:值是构造函数
            当一个new一个对象的时候,原型默认带有
        instanceof 判断构造函数是否一样
    
        function A(){}
        方法一:(正确)
        A.prototype.n = 10;
        A.prototype.fn = function(){}
        方法二:
        A.prototype = {
            n: 10,
            fn = function(){}
        }
        1和2一样的 但是2这么写把原型默认属性覆盖了
        new OA 
            OA.hasOwnProperty 是不是对象私有属性
            OA.constructor 相当于 A.prototype.constructor = A 弹出它的原型
            instanceof 判断对象1的构造函数是不是构造函数1
                对象 instanceof 对象
                OA instanceof A
    继承
        儿子继承父亲,用父亲的方法和属性 儿子的改变不会影响父亲
        call继承私有属性
        function Peo(n){this.n=n;}
        Peo.prototype.fn1 = function(){alert(this.n);}
        function PeoAge(n,a){this.a=a;} 通过继承创建一个子类
    
        现在不知道peo里面所有属性 但是我要继承
        function PeoAge(n,a){
            Peo.call(this,n);(继承|改变了this的指向)
            或者把Peo执行一遍 Peo.call(n)
            一执行PeoAge就执行了
            this.a=a;}
        Peo(a1,a2,a3) 拓展成 PeoChild(a1,a2,a3,b1) 多了个b1 
             --> 则把Peo执行一遍 改变了this的指向
             --> 抛开一切执行 Peo() this指向window 没有new 自己去找行为window
             --> this指向改为自己的this 那么Peo.call(this) 
                  那么Peo里的this指向此时call里面的this
                  此时的this为op(创建出来的对象)
    
                  var op = new PeoChild(a1,a2,a3,b1) op因为返回的就是this
                  Peo.call(this,+参数(a1,a2,a3))
                            this,a1,a2,a3
    
                  或 var op = new PeoChild([a1,a2,a3],b1)  [这里是父亲要的参数]
                  Peo.call 改为 Peo.apply(this,arr);
    
                  call参数要一个个摆着
                  apply 参数只要一个数组(放数组里)
    
    
        要把父亲的原型也继承下来
        那么 PeoChild.prototype = Peo.prototype [X] 错误!!!
            = 为引用  引用关系
            儿子的改变不影响父亲 此时 PeoChild.prototype.fn2 = ... 就会影响父亲原型
            两边都是对象 = 的时候就是引用 一旦引用 子新增父也会跟着改
        那么直接= 为引用 选择不直接=
    
            第一种Clone:
                构建个新的对象 把一个对象完全克隆
                PeoChild.prototype = new clone(Peo.prototype)
            第二种继承:
                PeoChild.prototype(对象) = Peo.prototype(原型)
                对象本身的属性改变能否改变或影响其构造函数原型属性的改变  ----  不会!!!
                var a = new Peo()  a.x=5;
                a.fn 也能读取原型属性
                那么 
                 --> 中间介质 function Fn(){}
                 --> Fn.prototype = Peo.prototype
                 --> PeoChild.prototype = new Fn();
                 --> 自身无找原型 var obj = new PeoChild();
                 --> obj.showName();
                 --> showName:PeoChild无 找原型 PeoChild.prototype(他是Fn) 无 把Fn它是 Peo.prototype
    
    
    
        Clone:
            对象克隆
            var a={aa:10,bb:20,cc:30}
            现在要b拥有a所有属性 但b改变不影响a
            var b=clone(a)
            function clone(obj){
                代码可以改成new clone
                前后去掉即可 + 改this     
                var newObj=new object()/={};
                for (var k in obj) {
                    newObj[k]=obj[k]; 这句全是引用,赋值
                }
                return newObj;
            }
            此时 bb.dd=50 alert(a.dd) ----- undefined 不影响了
            那么此时a里面有个 qqq:{a:'a',b:'b'} 对象
            .clone之后 b.qqq.c='c'   alert(a.qqq.c)  会弹出c!!!!
            clone里面循环一旦读到qqq是一个对象
            那么右边是对象了 又变成引用了 不是赋值
            要保证 = 是赋值 不管多少层下去
            那么只要是个对象就要进行克隆
            function clone(obj){    
                for (var k in obj) {
                    this[k]=obj[k];     obj[k]!!!要进行递归  遇到对象就要进行克隆
                }
                for改为
                for (var k in obj) {
                    if(typeof obj[k] == 'object'){
                        this[k]=clone(obj[k]);
                    }
                    this[k]=obj[k];
                }
            }
    
        递归:
            4!=4*3*2*1
            拆分为 4!=4*3!  3!=3*2! 2!=2*1! ... 递   ----  归:到某一点归
            x==1 的时候直接返回1
            function f(x){
                if(x==1){return 1;}
                return x*f(x-1);
            }
        Clone fn:
            function clone(obj){    
                for (var k in obj) {
                    this[k]=(typeof obj[k] == 'object')?new clone(obj[k]):obj[k];
                }
            }
  • 相关阅读:
    2019年Web前端开发职业技能等级考试试题~高级理论考试真题(二)
    2019年Web前端开发职业技能等级考试试题~高级理论考试真题(一)
    2019年Web前端开发职业技能等级考试试题~中级理论考试真题(四)
    2019年Web前端开发职业技能等级考试试题~中级理论考试真题(三)
    2019年Web前端开发职业技能等级考试试题~中级理论考试真题(二)
    2019年Web前端开发职业技能等级考试试题~中级理论考试真题(一)
    2019年Web前端开发职业技能等级考试试题~初级理论考试真题(四)
    2019年Web前端开发职业技能等级考试试题~初级理论考试真题(三)
    如何避免FOUC,是如何产生的
    input type='file'文件上传自定义样式
  • 原文地址:https://www.cnblogs.com/caiCheryl/p/9204116.html
Copyright © 2011-2022 走看看