面向对象02-原型对象与实例

原型对象

01 原型对象概念

  • 在构造函数创建出来的时候,系统会默认帮构造函数创建一个关联的新对象,就是原型对象,其默认为一个空对象
  • 构造函数找到原型对象:prototype
  • 原型对象找到构造函数:constructor

注意:原型对象本身也是一个对象,这个对象是Object类型,有一个属性constructor

02 原型对象的作用

  • 构造函数的原型对象的属性与方法可以被构造函数创建的对象共享

03 如何访问原型对象

  • 构造函数.prototype
  • 对象.__ proto__(注意:正常开发中不要使用这个属性,因为ECMA标准中并没有这个属性,是浏览器开发商提供的方便调试,直到E6纳入了标准中)
  • Object.getPrototypeOf(对象)

04 如何使用原型对象

  • 利用对象的动态特性

    实例成员:实例对象的属性与方法
    
    原型成员:原型对象上的属性与方法
    

代码示例

    function Person(name,age) {
        this.name = name;
        this.age = age;
    }

    Person.prototype.showName = function () {
        console.log(this.name);
    }
    Person.prototype.showAge = function () {
        console.log(this.age);
    };
    Person.prototype.des = "描述信息";

    var p1 = new Person("张三",20);
    console.log(p1);
    console.log(Person.prototype);

    //删除原型对象上面的属性
    //delete Person.prototype.des;   //删除成功
    console.log(p1.des);

    //删除对象中不存在的属性,返回true
    console.log(delete p1.des);   //不能使用这种方式直接删除原型对象上面的属性
    console.log(p1.des);
  • 字面量的方式直接替换

代码示例1

   function Person(name,age) {
        this.name = name;
        this.age = age;
    }

    Person.prototype = {
        showName:function () {
            console.log(this.name);
        },
        showAge:function () {
            console.log(this.age);
        },
        des:"描述信息",
        friends:["乌拉乌拉","哗啦哗啦","滴答滴答"]
    }

    var p1 = new Person("张三",20);
    var p2 = new Person("张四",20);
    p1.showName();
    p2.showName();

    //原型成员会被所有的对象(构造函数)共享
    p1.des = "测试";        //该行代码添加属性在p1上面,并不会改变原型属性
    console.log(p2.des);         //描述信息
    console.log(p1);
    console.log(p2);

    p1.friends.push("巴拉巴拉");
    console.log(p1);
    console.log(p2);  //会受到影响

    //使用对象.这种方式来设置属性的时候,
    // 如果这个属性是值类型那么表示添加一个实例属性des,不会修改原型属性
    // 如果这个属性是引用类型,那么可以修改到原型属性

    Person.prototype.des = "0000";
    console.log(p1.des);  //测试
    console.log(p2.des);  //0000

注意:使用字面量方式替换原来的原型对象,需要手动添加构造器属性,因为字面量创建的对象本身没有构造器属性,那么会去他的原型对象上找,而通过字面量创建的对象是由Object创建的,其原型对象的构造器属性为object,所以在没有添加构造器属性之前,Person.prototype.constructor = Object

代码示例2

    function Person(name,age) {
        this.name = name;
        this.age = age;
    }

//    var o = {};
//    var o = new Object();

    //字面量创建的对象是Object创建的
    //该对象的构造函数是 Object
    //该对象的构造函数也有自己的原型对象 Object.prototype
    //该对象的构造函数也有自己的原型对象,内部有构造器属性 Object.prototype.constructor =》Object,所以需要手动添加一个构造器属性
    //对象本身并没有构造器属性,在访问该属性的时候访问的是其原型对象上面的属性
    Person.prototype = {
        constructor:Person,
        showName:function () {
            console.log(this.name);
        },
        showAge:function () {
            console.log(this.age);
        }
    };
    var p1 = new Person("张三",20);

    console.log(Person.prototype.constructor == Person); //Person
    console.log(p1);

代码示例

    function Dog() {
    }
    //构造函数 Dog
    //构造函数的原型对象  Dog.prototype
    //原型对象找到构造函数 Dog.prototype.constructor ==>Dog

    Dog.prototype.name = "默认的名称";
//    Dog.prototype = {
//        name:"默认的名称"
//    };
    console.log(Dog.prototype);

    var dog1 = new Dog();
    var dog2 = new Dog();
    console.log(dog1.name);
    console.log(dog2.name);
    console.log(dog1.\_\_ proto\_\_== Dog.prototype);  //true
    console.log(Object.getPrototypeOf(dog2) == Dog.prototype);  //true

05 构造函数,原型对象与对象的关系


06 原型对象解决函数共享问题

建议:属性写在构造函数上,方法写在原型对象上

注意:对象访问属性与方法时,会先在自己身上查找,没有再去原型对象上查找。

代码示例

    function Person(name) {
        this.name = name;
    }

    //设置构造函数的原型对象
    Person.prototype.showName = function () {
        console.log(this.name);
    }

    var p1 = new Person("张三");
    var p2 = new Person("张三丰");
    p1.showName(); //张三
    p2.showName(); //张三丰
    console.log(p1.showName == p2.showName); //true

    //注意:下面的代码在p1上面添加了一个showName方法并没有修改原型对象。
    p1.showName = function () {
        console.log("测试");
    };
    p1.showName(); //测试
    p2.showName(); //张三丰

07 原型对象位置设置问题

注意:在设置(替换)原型对象前后创建的对象指向的原型对象不是同一个

代码示例

    //01 提供构造函数
    function Person(name,age) {
        this.name = name;
        this.age = age;
    }

    //03 创建实例对象
    var p1 = new Person("张三",20);

    //02 设置原型对象
    Person.prototype = {
        constructor:Person,
        showName:function () {
            console.log(this.name);
        }
    }


    var p2 = new Person("李四",20);
    p2.showName();  //李四
    p1.showName();  //报错,因为p1是在替换原型对象之前创建的,其原型对象只有一个constructor属性,没有showName方法,所以报错。

08 hasOwnProperty方法

hasOwnProperty:判断某个对象是否拥有指定的实例属性(不包括原型成员)

in关键字 :检查对象是否拥有指定的成员(实例成员与原型成员)

代码示例

    function Person(name) {
        this.name = name;
    }

    Person.prototype.hi = "hi";
    Person.prototype.show = function () {

    };
    var p1 = new Person();

    //语法 对象.hasOwnProperty("属性")
    console.log(p1.hasOwnProperty("name")); //true
    console.log(p1.hasOwnProperty("age"));  //false
    console.log(p1.hasOwnProperty("hi"));   //false

    //语法 “属性” in 对象
    console.log("name" in p1);           //true
    console.log("age" in p1);            //false
    console.log("hi" in p1);              //true
    console.log("show" in p1);           //true

09 isPrototypeOf方法

isPrototypeOf:判断某个对象是否是另一个对象的原型对象

代码示例

    function Person(name) {
        this.name = name;
    }

    var obj = {};
    var o = {
        hi:"hi"
    }
    Person.prototype = o;

    var p1 = new Person("李四");
    
    //Object.prototype Object构造函数的原型对象
    console.log(o.isPrototypeOf(p1));  //true 判断o是否是p1的原型对象
    console.log(Object.prototype.isPrototypeOf(p1));  //true

实例化与实例

实例化:构造函数创建对象的过程

实例(对象):构造函数创建出来的对象是该构造函数的一个实例对象;在说实例的时候需要指明构造函数。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容