• JavaScript之prototype对象


    简述prototype:

    在js中,每个构造函数都有一个原型属性prototype,因为这个属性的值通常是一个对象,又叫原型对象!你不需要显式的去定义原型对象,因为每个构造函数都会一个原型属性,通常在这个原型对象中,会包含一个constructor属性指向该原型对象的构造函数:

    function a() {
        alert('hello');
    }
    
    var b = new a();
    console.log(b.constructor);//返回函数a的字面量function a() {alert('hello')} ;

    以上代码中你会发现,首先你并没有定义函数a的prototype,以及constructor;但是在使用的时候构造函数a的实例对象b的constructor属性却正确的指向构造函数a;

    我们都知道js是一种基于原型继承的语言,这里说的原型指的就是对象的原型属性!从这就能看出来,在js中,原型是用来实现继承的!那么为什么可以通过对象的原型就能实现继承了?这是因为在js中,所有使用同一个构造函数生成的实例对象,都共享该构造函数的原型对象,例如:

    //定义构造函数
    function user(name, age) {
        this.name = name;
        this.age = age;
    }
    
    //定义构造函数user的原型方法
    user.prototype.getName = function() {
        alert(this.name);
    }
    user.prototype.getAge = function() {
        alert(this.age);
    }
    
    //生成实例
    var userA = new user('a', '22');
    var userB = new user('b', '30');
    userA.getName();//a
    userA.getAge();//22
    userB.getName();//b
    userB.getAge();//30

    由以上代码可以看出,在构造函数中我们并没有定义获取名称和获取年龄的方法getName以及getAge;它们是在原型对象中定义的;但是我们在底下代码中的user构造函数的两个实例对象userA和userB却都可以使用构造函数的原型对象中的方法!这就是上面说的:所有使用同一个构造函数生成的实例对象,都共享该构造函数的原型对象!

    prototype中的constructor属性:

    上面简单的介绍了一下prototype中的constructor属性,该属性是原型对象中自带的属性,并且它始终是指向该原型的构造函数的!

    //定义构造函数
    function user(name, age) {
        this.name = name;
        this.age = age;
    }
    
    //定义构造函数user的原型方法
    user.prototype.getName = function() {
        alert(this.name);
    }
    user.prototype.getAge = function() {
        alert(this.age);
    }
    
    //生成实例
    var userA = new user('a', '22');
    var userB = new user('b', '30');
    console.log(userA.constructor === userB.constructor)//true;

    当然,我们也可以动态的设置constructor属性的值:

    user.prototype.constructor = user;

    只是在我们没有重新定义覆盖prototype对象的时候,并不需要这样显示的去让constructor属性指向构造函数!

    覆盖prototype对象:

    上面我们简单介绍了prototype对象,并且也给出来一些简单使用的例子,在上面的例子中,我们都是往构造函数的prototype对象上添加方法或属性的,有一个方法我们就要添加一次,这样显的不够优雅,那么有没有一种写法是可以一次定义这些方法的了?答案当然是肯定的,这就是我们下面要讲的覆盖prototype对象,我们先来看看怎么做,下面我们重写上面的例子:

    //定义构造函数
    function user(name, age) {
        this.name = name;
        this.age = age;
    }
    //定义构造函数user的原型方法
    user.prototype = {
        constructor : user,
        getName : function() {
            alert(this.name);
        },
        getAge : function() {
            alert(this.age);
        }
    }

    大家可以复制上面的代码,看看效果是不是跟之前的效果一样!相信大家看了代码之后应该也都明白了,既然prototype是一个对象,那么我们当然能重新定义一个对象去覆盖它了,但是这里值得注意的是,在原型对象中,默认是包含constructor属性指向构造函数的,在我们自己定义对象覆盖prototype对象时,要显式的定义constructor属性指向构造函数,否则,这个prototype对象的constructor属性就会是undefined!

    结:

    说到这里,关于prototype对象的一些知识以及基本用法,已经跟大家交代清楚了,因为js是基于原型继承的,所以了解prototype对象的相关对象,对于js面向对象编程是至关重要的!关于prototype的部分我们就先讲到这里,等以后有时间,我们在接着讲原型链,面向对象以及js中的继承等知识!

    感谢大家的阅读,本文由平凡公子原创发布,转载请注明出处,谢谢!

  • 相关阅读:
    AX 2012 Form and Parts
    AX 2012 SSRS print setting-报表打印输出设置
    AX 2012 关于parts 添加
    AX Dynamic 2012 tabletype:TempDB使用
    AX Dynamic 2012 SSRS 按行数分页
    AX Dynamic 2012 SSRS autorepot中取当前公司名、打印时间、打印页码
    AX Dynamics 去中文字符长度:中文字符当2个字符处理
    AX dynamics 2012 ssrs 开发报错:Native compiler return value: ‘[BC30179]
    在Ubuntu 下编译c语言
    在ubuntu加载flash的方法
  • 原文地址:https://www.cnblogs.com/xjser/p/4962889.html
Copyright © 2020-2023  润新知