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) 如果是搜索方法就报错

 

posted @ 2019-07-17 10:52  Adom_ye  阅读(204)  评论(0编辑  收藏  举报