趣谈js中的原型(prototype)

学习js一段时间了,下面就按照一下我自己的理解来讲述一下js的原型(prototype)

首先,先介绍一下声明一个对象的常用的两种方法:

1.使用关键字class(es6)支持(考虑浏览器兼容性的问题,目前暂不推荐,也不是本文的讨论重点)

2.使用function来声明类:

        function Student (name,age,grade)
        {
                //public属性
                this.name=name;
                this.age=age;
                this.grade=grade;

//public方法
                this.course=function()
                {
                        console.log("学生课程");
                };
        }

var student = new Student ('','','');

这样便声明好了一个Student 的类,并定义了一个student 的对象


关于原型的语法约定:

1.只有函数才有prototype,并且任何函数的prototype都会自动生成一个constructorfunction,指向本身

(正因为此,才能通过var student = new Student ('','',''); 来定义一个对象);

2.任何定义好的对象都有一个_proto_属性来指向函数的function的prototype(他们都是指向同一个对象,js中的引用类型):

student .__proto__===Student.prototype (true)

__proto__的所用属性方法(除了constructor),student 对象都可以使用,也正因为js给所有对象(包括函数)都以__proto__属性,从而使得js实现了继承的特点


牢记以上两点,基本上就已经了解了js的对象继承特性


下面一个我们经常用到的例子来在理解一下原型:

贴了一段js关于Array indexof的源码:

if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(searchElement, fromIndex) {

    var k;

    // 1. Let O be the result of calling ToObject passing
    //    the this value as the argument.
    if (this == null) {
      throw new TypeError('"this" is null or not defined');
    }

    var O = Object(this);

    // 2. Let lenValue be the result of calling the Get
    //    internal method of O with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = O.length >>> 0;

    // 4. If len is 0, return -1.
    if (len === 0) {
      return -1;
    }

    // 5. If argument fromIndex was passed let n be
    //    ToInteger(fromIndex); else let n be 0.
    var n = +fromIndex || 0;

    if (Math.abs(n) === Infinity) {
      n = 0;
    }

    // 6. If n >= len, return -1.
    if (n >= len) {
      return -1;
    }

    // 7. If n >= 0, then Let k be n.
    // 8. Else, n<0, Let k be len - abs(n).
    //    If k is less than 0, then let k be 0.
    k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

    // 9. Repeat, while k < len
    while (k < len) {
      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the
      //    HasProperty internal method of O with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      //    i.  Let elementK be the result of calling the Get
      //        internal method of O with the argument ToString(k).
      //   ii.  Let same be the result of applying the
      //        Strict Equality Comparison Algorithm to
      //        searchElement and elementK.
      //  iii.  If same is true, return k.
      if (k in O && O[k] === searchElement) {
        return k;
      }
      k++;
    }
    return -1;
  };
}


var array = ["hello","world","csdn"]


1.定义array变量为["hello","world","csdn"],这边其实是通过 new Array()进行实例化;

因此array.__proto__ = Array.prototype

2. Array.prototype.Indexof = function(){}  (由于js是弱类型的动态语言,所以这句代码的意思是指给Array.prototype.的对象添加一个方法Indexof 

3.array会拥有__proto__ 的所有方法,所以array既然也就拥有了indexof方法(js中除了Undefined,Null,Boolean,Number和String五类基本类型是值类型,其余都是引用类型


实例:在讨论一下如何实现js类的继承

functionStudent()
                {
                        this.studentValue="我是学生";
                }
                Student.prototype.getStudentValue=function()
                {
                        //console.log(this.studentValue);
                        console.log("我是学生,直接调用");
                };

functionHighSchoolStudent()
                {
                        this.highSchoolStudentValue="我是高中生";
                }

// HighSchoolStudent.prototype=newStudent();
                //HighSchoolStudent.prototype=Object.create(Student.prototype);
                //HighSchoolStudent.prototype=createobject(Student.prototype);
                //HighSchoolStudent.prototype.constructor=HighSchoolStudent;

inherits(HighSchoolStudent,Student);

HighSchoolStudent.prototype.getHighSchoolStudentValue=function()
                {
                        console.log(this.highSchoolStudentValue);
                };

functioninherits(Child,Parent)
                {
                        functionF(){}         //相当于temp变量                      
                        F.prototype=Parent.prototype;
                        Child.prototype=new F ();
                        Child.prototype.constructor=Child;

                }

functioncreateobject(proto)
                {
                        functionF(){}
                        F.prototype=proto;
                        returnnewF();
                }

调用结果:

                varhightSchoolStudent=newHighSchoolStudent();
                console.log(hightSchoolStudent.studentValue);//undefined
                hightSchoolStudent.getStudentValue();//我是学生,直接调用
                console.log(hightSchoolStudent.highSchoolStudentValue);//我是高中生
                hightSchoolStudent.getHighSchoolStudentValue();//我是高中生






 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值