趣谈js中的原型(prototype)

来源:互联网 发布:log4j数据存进mongodb 编辑:程序博客网 时间:2024/05/02 04:25

学习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();//我是高中生






 



0 0
原创粉丝点击