zoukankan      html  css  js  c++  java
  • javascript基础学习六--原型与继承

    回顾:
    1、删除子元素
             //从node中删除一个div
            node.removeChild(div);
            //如果div变量不存在
            var div = document.getElementById('...');
            node.removeChild(div);
            //假设node节点中只有一个div
            node.innerHTML = '';
    2、删除属性
    var attrNode = node.getAttributeNode('属性名');
            node.removeAttributeNode(attrNode);
            //removeAttribute是什么意思呢?
            node.removeAttributeNode('属性名');
            
            //getAttributeNode
            //getAttribute
    3、获取属性值 
        var attrNode = node.getAttributeNode('属性名');
        attrNode.nodeValue;
            //简化
            node.getAttribute('属性名');

    思考:

    Json基于JavaScript语言的轻量级的数据交换格式(JavaScript Object Notiation)

    对象字面量和json对象的区别

    json对象有两种说法:一种是传统的json对象,一个是符合json协议的对象

    符合json协议的对象要求所有的属性名必须带有双引号,表示字符串

    Var o = {name : ‘jim’};

    Var o = {“name”  :  “jim”};

    1、为什么需要原型

      a) 代码验证

      b) 内存与性能的需求

    2、函数的prototype属性

      a) prototype指向一个对象

      b) 构造函数创建的对象会默认连接到该对象上

      c) 代码修改实现共享方法

    3、原型的概念

      a) 原型属性

      b) 原型对象

    __proto__

    以前要访问原型,必须使用构造函数。无法直接使用实例对象访问原型

    火狐最早引入属性__proto__表示使用实例对象引用原型,但是早期是非标准的

    通过该属性可以允许使用实例对象直接访问原型

    //function Person() {}
            //原型对象就是Person.prototype
            //那么只有使用构造函数使用才可以访问
            //var o = new Person();
            //以前不能直接使用o来访问原型对象
            //现在有了__proto__后
            //o.__proto__也可以直接访问原型对象
            //那么o.__proto__ == Person.prototype
            //标志符:名字 
            //原型对象中默认有‘constructor’,构造器构造函数

     

    继承的概念

    拿来主义:自己没有的,别人有的,拿过来自己用

    1、最简单的继承就是将别的对象的属性强加到我的身上,那么我就有这个成员了
    
    2、利用原型可以实现继承,不需要在我的身上添加任何成员,只要原型有了,我就有了
    
    3、结论:将属性,方法等成员利用混入(mix)的办法,加到构造函数的原型上,构造函数的原型就都有了

    为什么需要继承?

      方法复用(*

      方法共享

    混合式继承复杂描述(前面的知识)

    1、new DivTag()用来创建Div对象
    
    2、appendTo 加到某元素上
    
    3、扩展
    
    4、无论方法怎么写,方法是谁调用的this就是谁

    混合式继承

    //        var Person = function () {
    //        };
    //        var extend = function (o1,o2) {
    //            for (var k in o2) {
    //                o1[k] = o2 [k];
    //            }
    //        };
    //        extend( Person.prototype, {
    //            run : function () { console.log('我能跑了')},
    //            eat : function () { console.log('我能吃了')},
    //            sayHello : function () { console.log('你好')}
    //        });
    //        var p1 = new Person();
    //        var p2 = new Person();
    //        p1.run();
    //        p1.eat();
    //        p1.sayHello();
    //        
    //        p2.run();
    //        p2.eat();
    //        p2.sayHello();
            
            //改良
            var Person = function () {};
            Person.prototype.extend = function(o){
                for (var k in o) {
                    this[k] = o[k];
                }
            };
            Person.prototype.extend({
                run : function () { console.log('我能跑了')},
                eat : function () { console.log('我能吃了')},
                sayHello : function () { console.log('你好')}
            });
            var p1 = new Person();
            var p2 = new Person();
            p1.run();
            p1.eat();        
         p1.sayHello(); p2.run(); p2.eat(); p2.sayHello();

     

    面试题

    1、逻辑中断

      a) Foo = foo || bar

      b) ||逻辑或,左边如果为真,那么整个表达式的值就是左边的值

      c) ||如左边的值为假,整个表达式的值就是右边的值

      d) 如果考虑函数参数的时候,一般使用该方法来兼容处理参数

      原型存在的目的就是实现继承
    
      js是基于原型继承的面向对象语言

    使用点语法给原型添加成员与使用直接替换修改原型对象的区别:

      1、原型指向发生了变化
    
      2、构造函数做常见的对象所继承的原型不同
    
      3、新增的对象默认是没有constructor属性

    注意:在使用替换的方式修改原型的时候一般会添加constructor属性,在构造函数内部需要多次调用构造函数必须使用构造函数

    构造函数在调用的时候,根据不同的参数创建不同的对象

     

    静态成员与实例成员的概念

    也是从面向对象的编程语言中引入的

    1、静态成员表示的是静态方法和静态属性的概念,所谓静态就是构造函数提供的
    
    2、实例成员表示的是实例方法和实例属性。实例是由构造函数创建的对象
    
    3、一般工具型方法都由静态成员提供,跟实例有关由实例成员表示

     

    构造原型实例三角形

    //绘图练习
            //1
            function Person() {
                this.name = '张三';
                this.sayHello = function (){}
            }
            var p = new Person();

    //2
             function Person() {
                this.name = '张三';
            }
            Person.prototype.sayHello = function (){};
            var p = new Person();

    //3
             function Person() {
                this.name = '张三';
            }
            Person.prototype = {
              sayHello : function(){}  
            };
            var p = new Person();

     

    原型与继承小结:

    1、什么是原型?
    
    2、如何使用原型?为了继承
    
      a) 利用点添加成员(Person.prototype.成员)
    
      b) 直接替换添加成员(Person.prototype = {})
    
    3、什么是原型继承?
    
      a) 实例对象继承自原型对象
    
      b) 一般的开发方式:属性交给构造函数,方法交给原型
    
    4、如何实现?
    
      a) 混合继承方式:利用混入的方法给原型添加成员(方法和属性),那么实例就可以继承指定的方法和属性
    
      b) 直接替换原型对象
    //例如要实现一个自定义集合(数组)
            //弄一个类型Per
            function Per() {}
            //要提供数组的方法为其添加成员
            Per.prototype = [ ];
            var arr = new Per();
            arr.push( 123 );
            arr.push( 456 );
            arr.push(1,2,3,4,5,6,7);
            //由于数组的方法push是首先将元素加到数组结尾处,然后将其长度+1
            var str = arr.join( '=' );
            alert (str );
    
    
    1
    function Collection (){}
               //要提供数组的方法为其添加成员
               Collection.prototype = [];//能够防止数据污染
               // Collection.prototype = Array.prototype;
            
            var arr = new Collection();
            arr.push('a','b','c');
            //自定义的集合目的是让其像所有数组一样使用,但是同时有一些数组无法实现的方法
            //例如:sum
            Collection.prototype.sum = function(){};
            
            alert([].sum);

    2
    function Collection (){}
               //要提供数组的方法为其添加成员
               //Collection.prototype = [];//Array.prototype
                Collection.prototype = Array.prototype;//效率高
            
            var arr = new Collection();
            arr.push('a','b','c');
            //自定义的集合目的是让其像所有数组一样使用,但是同时有一些数组无法实现的方法
            //例如:sum
            Collection.prototype.sum = function(){};
            
            alert([].sum);

     

    从案例中引出的问题

    1、什么时候会得到undefined
    
    2、我们介绍的是在实例中没有就到原型中找,但是原型中没有?

    属性搜索原则

    1、原型链
    
    2、属性搜索原则
    
      a) 所谓的属性搜索原则就是对象在访问属性和方法的时候,首先在当前对象中查找
    
      b) 如果当前对象没有,那么在其原型中没有
    
      c) 原型没有就到原型的原型中找,循环往复,直到object.prototype没有就返回undefined
    
      d) 如果是搜索方法就报错
  • 相关阅读:
    BZOJ3669
    HDU3726
    BZOJ3282
    BZOJ2843
    Link/cut Tree
    Codeforces396A
    LOJ6277~6285 数列分块入门
    Codeforces446C
    Codeforces475D
    Codeforces103D
  • 原文地址:https://www.cnblogs.com/Adam-Ye/p/11198997.html
Copyright © 2011-2022 走看看