• web 原型链与对象


    原型链类

    1、创建对象有几种方法

     2、原型、构造函数、实例、原型链的概念

    3、instanceof的原理

    4、new运算符

    创建对象有几种方法

    字面量的方法   构造函数的方法  Object.create的方法

    原型、构造函数、实例、原型链的概念

    构造函数:只有是new后面的函数,它就不是一个普通的函数,它就是一个构造函数,任何一个函数只要被new使用了,都可以是构造函数

     函数都有一个prototype属性,在声明一个函数的时候,js就会自动给一个prototype属性,prototype指的是原型对象,原型对象的constructor是声明的那个函数

     原型链是通过什么往上查找呢?通过__proto__

    任何一个实例化的对象,通过原型链找到它上面的原型对象,这个原型对象上面的方法和属性是它的实例对象所共用的。这就是原型链的基本原理

    M = function (name) {
    this.name = name
    this.say = function () {
    console.log('say hi')
    }
    }
    M.prototype.say = function () {
    console.log('say hi')
    }
    var o1 = new M('o1')
    上述代码中,在构造函数中写的方法,和在原型对象上写的方法的区别:
    构造函数中写的方法在每次实例化对象的时候都会被执行一次,会比较占内存,而在原型对象上面写的方法,是可以让实例对象通过原型链进行继承的

     只有实例才有__proto__属性,但是会发现上述的M也有__proto__属性,这是因为函数其实它也是一个对象,发现M.__proto ==function.prototype,就是说M的构造函数是function

     instanceof的原理

    instanceof 判断实例是否是某个构造函数的实例

    比如:o1.instanceof == M // true

      o1.instanceof == Object //true

    只要是在o1的原型链上的构造函数,o1都可以instanceof

    比如 A继承了B,B继承了C,那么A的实例a1 a1.instanceof === B | A | C都是返回true

    那么如果知道a1是通过谁来进行实例化的呢?这得用constructor

    a1.__proto__.contractor === A // true

    a1.__proto__.contractor === B // false

    new 运算符

    面向对象类

      类与实例

        类的声明

        生成实例

      类与继承

        如何实现继承

        继承的几种方式

    类与实例

    /**
    * 类的声明
    */
    var Animal = function () {
    this.name = 'Animal';
    };

    /**
    * es6中class的声明
    */
    class Animal2 {
    constructor () {
    this.name = 'Animal2';
    }
    }

    /**
    * 实例化
    */
    console.log(new Animal(), new Animal2());

    类与继承

    /**
    * 借助构造函数实现继承

    这种方法只能部分继承,继承不了原型对象上的方法和属性

    call:将父级函数运行的this指向子类函数
    */
    function Parent1 () {
    this.name = 'parent1';
    }
    Parent1.prototype.say = function () {

    };
    function Child1 () {
    Parent1.call(this);
    this.type = 'child1';
    }
    console.log(new Child1(), new Child1().say());

    /**
    * 借助原型链实现继承

    这种方法的缺点:如果其中一个实例改变了原型对象上的一个方法,则其他的实例的方法都会被改变,因为所有实例都是继承了一个原型链上的方法
    */
    function Parent2 () {
    this.name = 'parent2';
    this.play = [1, 2, 3];
    }
    function Child2 () {
    this.type = 'child2';
    }
    Child2.prototype = new Parent2();

    var s1 = new Child2();
    var s2 = new Child2();
    console.log(s1.play, s2.play);
    s1.play.push(4);

    /**
    * 组合方式

    这种方式的缺点就是:父级的构造函数执行了两次,

    如果把play写到prototype中,实例中的一个对象改变此方法,则另外的对象的此方法也跟着改变
    */
    function Parent3 () {
    this.name = 'parent3';
    this.play = [1, 2, 3];
    }
    function Child3 () {
    Parent3.call(this);
    this.type = 'child3';
    }
    Child3.prototype = new Parent3(); // 构造函数执行了一次
    var s3 = new Child3();// 构造函数又执行了一次
    var s4 = new Child3();
    s3.play.push(4);
    console.log(s3.play, s4.play);

    /**
    * 组合继承的优化1

    Child4.prototype = Parent4.prototype;此步把child4的原型对象和parent4的原型对象是指向了同一个,当new chlid4()的时候,无法区分这个实例的构造函数是chlid4还是parent4
    * @type {String}
    */
    function Parent4 () {
    this.name = 'parent4';
    this.play = [1, 2, 3];
    }
    function Child4 () {
    Parent4.call(this);
    this.type = 'child4';
    }
    Child4.prototype = Parent4.prototype;
    var s5 = new Child4();
    var s6 = new Child4();
    console.log(s5, s6);

    console.log(s5 instanceof Child4, s5 instanceof Parent4);
    console.log(s5.constructor);

    /**
    * 组合继承的优化2

    Object.create(Parent5.prototype) 首先创造一个空的对象,这个对象的原型对象继承了parent5.prototype的原型对象,这就能区分了child5的构造函数了

    Object.create(参数)这个方法创建的对象的原型对象就是它的参数
    */
    function Parent5 () {
    this.name = 'parent5';
    this.play = [1, 2, 3];
    }
    function Child5 () {
    Parent5.call(this);
    this.type = 'child5';
    }
    Child5.prototype = Object.create(Parent5.prototype);

    Child5.prototype.constractor = Child5

  • 相关阅读:
    scanf的参数类型自动转换
    Gedit中文乱码
    在VirtualBox的Ubuntu虚拟机中与母体Windows共享文件夹
    Win7安vc2008编译报LINK : fatal error LNK1000: Internal error during IncrBuildImage
    贝叶斯后验概率小记
    美国计算机专业最好的前20名学校
    Linux磁盘空间不够怎么办?
    Debian6.0装机过程
    把用户加到sudoers组中的方法
    vi命令手册
  • 原文地址:https://www.cnblogs.com/liangshuang/p/8493284.html
Copyright © 2020-2023  润新知