• 面向对象的Javascript 通过原型(Prototype)实现继承


    Prototype的使用方式


    Prototype(原型)是Javascript中实现对象继承的基础方式,使用方式为 [function].prototype = [object1]

    [function]可认为相当于type/class,这样可以使该类型的所有对象继承[object1]中所有Public的属性和方法。在这里public的意思是使用了this.xxx。

    先看以下例子

    View Code
    function Person() {
    this.fullName = "Unknown";
    this.sex = "Male";
    this.speek = function(){
    console.log(this.fullName + " is speeking");
    }
    }
    function Staff() {
    this.id = 1001;
    this.title = "Developer";
    }
    Staff.prototype = new Person();

    var s1 = new Staff();
    console.log(s1.sex); //==> Male
    s1.speek(); //==> Unknown is speeking

     * 注: console.log的结果可以在浏览器开发人员工具/Firebug中的Console(控制台)中查看

    通过指定Staff.prototype = new Person(), Staff类型的对象s1获得了Person的属性和方法。

    Prototype的原理及实现方式


    绝大多数的javascript对象都有原型对象,这些原型对象的应用形成一条“原型链”,链的尽头是Object.prototype。当调用对象的某属性或方法时,js引擎现在当前对象中查找,找不到的话就会查找其原型对象,如此上溯直到到达Object.prototype。我们所熟知的toString,valueOf等方法正是定义在Object.prototype中,因此所有js对象都通过继承获得这些方法。

    在Chrome和Firefox里,原型对象可以通过对象的属性"__proto__"访问,该属性实际上指向对应类型的”prototype”属性,即[object].__proto__ == [function].prototype。

    在未指定继承状态下,每一个对象都具有一个默认的__proto__对象,而该__proto__的上一级原型对象为Object.prototype.

    当指定Staff继承自Person之后,__proto__属性会指向personObj,原型链也会随之变化

     

    支持带参数的构造函数


    在第一点的代码例子中,考虑构造函数带参数的情况。

    View Code
    function Person(fullName, sex) {
    this.fullName = fullName || "Unknown";
    this.sex = sex || "Male";
    this.speek = function(){
    console.log(this.fullName + " is speeking");
    }
    }
    function Staff(id, title, fullName, sex) {
    this.id = id || 1001;
    this.title = title || "Developer";
    }
    Staff.prototype = new Person();
    var s1 = new Staff(99, "Manager","Eva", "Female");
    console.log(s1.fullName); //==> Unknown

     发现通过new Staff(…)无法对fullName和sex赋值,因为在指定继承关系的时候并没有把参数传进Person的构造函数中。要解决此问题需要在Staff中将参数传进Person,答案就是改变__prop__属性。

    View Code
    function Person(fullName, sex) {
    this.fullName = fullName || "Unknown";
    this.sex = sex || "Male";
    this.speek = function(){
    console.log(this.fullName + " is speeking");
    }
    }
    function Staff(id, title, fullName, sex) {
    if(this.__proto__){ //For Firefox, Chrome
              this.__proto__ = new Person(fullName, sex);
        }else{                //For IE
              Person.call(this,fullName, sex);
        }
    this.id = id || 1001;
    this.title = title || "Developer";
    }
    Staff.prototype = new Person();
    var s1 = new Staff(99, "Manager","Eva", "Female");
    console.log(s1.fullName); //==> Eva

    IE不支持__prop__属性,可以使用call/apply方法,该方法将带参数地调用Person()方法,并且将this作为Person()方法的当前对象。

    这种做法所有浏览器都支持,所以通常直接使用call/apply即可,上述例子只是为说明__proto__属性的作用。

  • 相关阅读:
    模拟器安装.apk包_夜神模拟器
    SDK安装报错_2019
    Jenkins安装插件方法
    Jenkins安装
    Python项目第三方库安装_pip freeze命令
    深入理解Java虚拟机—内存分配
    深入理解Java虚拟机—垃圾回收 下
    深入理解Java虚拟机—垃圾回收 上
    深入理解Java虚拟机—OutOfMemoryError异常
    深入理解Java虚拟机—Java内存区域
  • 原文地址:https://www.cnblogs.com/hiteddy/p/Object_Oriented_javascript_prototype_inheritance.html
Copyright © 2020-2023  润新知