zoukankan      html  css  js  c++  java
  • 认识javascript中的原型和原型链

    原型和原型链是javascript中非常重要的概念,下面让我们来认识一下这两个熟悉的陌生人。

    原型

    概念:无论何时,只要创建一个函数,就会按照规则为这个函数创建一个prototype属性,prototype属性指向的对象也就是原型对象。每次调用这个函数创建一个新实例,这个实例内部指针([[prototype]])就会被赋值为这个函数的原型对象,由于javascript脚本中没有设置可以访问[[prototype]]特性的标准模式,所以Firefox,Safari和Choreme会在每个对象上暴露一个__proto__属性,通过这个属性就可以访问到对象的原型。

    作用:通过对象的原型,我们可以获取到这个对象有哪些属性,并在实例化对象时,直接拥有这些属性。

    下面,我们同样通过例子来理解原型的概念。

    
    
    function Person() { //构造函数
    }

    Person.prototype.name = "张三";
    Person.prototype.age = "18";
    Person.prototype.sex = "man";

    const person = new Person(); //实例1

    person.name = '李四'

    const person2 = new Person(); //实例2

    console.log(person.__proto__ === Person.prototype) //true
    console.log(person.__proto__ === person2.__proto__ ) //true

    例子中,我们定义了构造函数Person,并给Person的原型对象上设置了三个属性。同时也通过Person函数构建了两个实例person和person2。

    例子的输出结果都是true,所以我们可以看出,实例化的对象的__proto__属性是指向构造函数的prototype属性,所以这person.__proto__ 和 Person.prototype是全等的。

    同时为了方便理解这个例子,我们可以画一个图来理解prototype和__proto__之间的关系。

    绘画能力有限,不过应该还是能够看懂。通过这个图我们能清晰的看到,不管是构造函数的prototype属性还是实例的__proto__属性都是指向构造函数的原型对象。

    现在我们了解了原型,那原型的作用是什么,这种规则有什么用,现在我们也来探索一下。

    通过上面的例子,我们可以看到,实例对象person和person2都具有Person原型对象的属性。学习过面向对象思想的同学应该了解了,通过原型,我们可以将javascript 当做面向对象的语言使用,通过提炼公共属性与方法,实现代码优化。

    同样,我们也通过一个例子来看看面向对象编程的优点。

    function Person() { //构造函数
    }
    
    Person.prototype.name = "张三";
    Person.prototype.age = "18";
    Person.prototype.sex = "man";
    /* 原型方式 */
    const person = new Person(); //实例1
    const person2 = new Person(); //实例2
    
    /* 原始方式 */
    let person3 = {
        name: '王五',
        age: 18,
        sex: 'man'
    };
    
    let person4 = {
        name: '周六',
        age: 18,
        sex: 'man'
    }

    相信例子中两种创建对象方式的优劣都是显而易见的。接下来我们了解下原型链。

    原型链

    了解原型之后,原型链的理解相信就是水到渠成的了。

    概念:每一个构造函数都有一个原型对象,该原型对象有个属性回指向构造函数,通过该构造函数实例化的对象也有一个指针指向原型。如果当这个原型是另一个构造函数的实例时,这个原型的__proto__属性将指向另一个函数的原型对象。这样实例和原型之间就构造了一条原型链。

    作用:实现继承。

    同样我们也来一个例子。

    function a() {
    }
    
    a.prototype.a = 'a';
    
    function b() {
    }
    
    b.prototype.__proto__ = a.prototype;
    b.prototype.b = 'b';
    
    function c() {
    }
    c.prototype.__proto__ = b.prototype;
    c.prototype.c = 'c';
    
    let obj = new c();
    console.log({a: obj.a, b: obj.b, c: obj.c})

    例子中,我们声明了三个函数,并分别给三个函数的原型上添加了三个不同的属性。我们通过将c函数的原型对象的原型设置成b函数的原型对象(让c函数的原型对象是b函数的实例),实现了c继承b的效果,同时将b函数的原型对象的原型设置成a的原型对象(让b函数的原型对象是a函数的实例),实现了b继承a。通过串联c,b,a的原型,形成了一条原型链。

    所以,上面这段程序最后的输出值是{a: "a", b: "b", c: "c"},因为实例obj通过原型链拿到了a,b,c三个属性。

    同样我们用一张图描述下上面三个函数的关系。

     虽然图画的不怎么好,不过能看懂就行。相信通过这张图,你应该知道为什么叫原型链了吧。

    总结:原型和原型链主要用于面向对象编程,实现类的封装与继承,是我们开发中不可获取的一部分。对他的使用要不断深研、探索。

    浅陋见识,不足之处,请大神指正。

  • 相关阅读:
    获取数字的位数
    使用json把php数据传给js处理
    Java实现带括号优先级的计算器
    Java使用正则表达式解析LRC歌词文件
    Android开发环境搭建:离线安装ADT插件和安装SDK
    【转】C语言快速幂取模算法小结
    【转】Java高手真经全套书籍分享
    10.19stark组件开发(三)
    10.18正式开发stark组件*(三)
    10.17正式开发stark项目(二)
  • 原文地址:https://www.cnblogs.com/heshuaiblog/p/13987095.html
Copyright © 2011-2022 走看看