我们创建每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象。使用原型的好处是可以让所有对象共享它所包含的属性和方法。

function Person(){

}
Person.prototype.name = "huyuping";
Person.prototype.age = 29;
Person.prototype.job = "d";
Person.prototype.sayName = function() {
console.log(this.name);
}
var person1 = new Person();
person1.sayName();//huyuping var person2 = new Person();
person2.sayName();//huyuping
console.log(person1.name == person2.name);//true

使用原型对象时,因为对象的属性和方法时所有实例所共享的,所以person1和person2访问的都是同一组对象和同一个sayName函数。说到这里,你可能对原型的概念还有些模糊,下面我们用与i写图来形象的理解一下原型对象。

理解原型对象

无论什么时候,创建一个新函数就会自动为该函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有原性对象都会自动获得一个constructor(构造函数)属性,这跟属性包含了一个指向prototype属性所在函数的指针。通过它,我们可以给原型对象添加更多的方法。



需要注意的是,虽然这两个实例都不包含属性和方法,但我们却可以调用p.sayName().这是通过查找对象属性的过程来实现的。

虽然在所有实现中都无法访问到[[Prototype]],但通过isPrototypeOf()方法来确定对象之间是否存在这种关系。从本质上讲,如果[[Prototype]]指向调用isPrototypeOf()方法的对象(Person.prototype),那么之歌方法就会返回true,如图所示:

Person.prototype.isPrototypeOf(person1)//ture
Person.prototype.isPrototypeOf(person2)//ture

这里,我们使用的是原型对象的方法,ES中还有一个Object.getPrototypeOf(),在所有支持的实现中,这个方法返回[[Pertotype]]的值。

Object.getPrototypeOf(person1)== Person.prototype();//true
Object.getPrototypeOf(person1).name//huyuping

使用Object.getPrototypeOf()可以方便取得一个对象的原型,而这在利用原型实现继承的情况下是非常重要的。

可以直接通过创建的实例更改属性

function Person(){

}
Person.prototype.name = "huyuping";
Person.prototype.age = 29;
Person.prototype.job = "d";
Person.prototype.sayName = function() {
console.log(this.name);
}
var person1 = new Person();
person1.name = “hhh”;
person1.sayName();//hhh来自实例 var person2 = new Person();
person2.sayName();//huyuping//来自原型

当代码读取某个对象的属性时3,会先在实例中搜索这个属性,实例中找不到才到原型中去找。

可以用delete删除在实例中定义的属性

function Person(){

}
Person.prototype.name = "huyuping";
Person.prototype.age = 29;
Person.prototype.job = "d";
Person.prototype.sayName = function() {
console.log(this.name);
}
var person1 = new Person();
person1.name = “hhh”;
person1.sayName();//hhh来自实例
delete person1.name
person1.sayName();//huyuping//来自原型 var person2 = new Person();
person2.sayName();//huyuping//来自原型

使用hasOwnProperty()方法可以检测一个属性时存在于实例还是存在于原型。之歌方法时从Object继承而来的,只在给定属性存在于对象实例中时,才会返回true.

function Person(){

}
Person.prototype.name = "huyuping";
Person.prototype.age = 29;
Person.prototype.job = "d";
Person.prototype.sayName = function() {
console.log(this.name);
}
var person1 = new Person();
var person2 = new Person();
console.log(person1.hasOwnProperty("name"));//false
person1.name = "hhh";
console.log(person1.hasOwnProperty("name"));//true

js 深入理解原型模式的更多相关文章

  1. JS 设计模式一 -- 原型模式

    原型模式 概念: 原型模式 是指原型实例指向创建对象的种类,并通过拷贝这些原型创建新的对象,是一种用来创建对象的模式,也就是创建一个对象作为另一个对象的prototype属性. 实现原型模式: 方法一 ...

  2. JS创建对象之原型模式

    一.原型对象 只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象:在默认情况下,所有原型对象都会 自动获得一个constructor(构造函 ...

  3. 理解javascript中的原型模式

    一.为什么要用原型模式. 早期采用工厂模式或构造函数模式的缺点:  1.工厂模式:函数creatPerson根据接受的参数来构建一个包含所有必要信息的person对象,这个函数可以被无数次的调用,工厂 ...

  4. 理解js的prototype原型对象

    我们创建的每一个函数都有一个prototype(原型)属性.这个属性是一个指针,指向一个对象,而这个对象的用途是包括能够由特定类型的全部实例共享的属性和方法.假设依照字面意思来理解,那么prototy ...

  5. iOS设计模式之原型模式

    原型模式 基本理解 原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节 ...

  6. Android设计模式系列--原型模式

    CV一族,应该很容易理解原型模式的原理,复制,粘贴完后看具体情况是否修改,其实这就是原型模式.从java的角度看,一般使用原型模式有个明显的特点,就是实现cloneable的clone()方法.原型模 ...

  7. 原型模式--java代码实现

    原型模式 原型模式,属于对象创建型模式中的一种.通过复制原型对象的方法来创建一个对象实例,且该对象与原对象有相同的数据结构和值.类似我们在备份数据库信息的时候,将数据库中表的结构和数据的一同备份,生成 ...

  8. 2.6 《硬啃设计模式》第8章 复制不是很难 - 原型模式(Prototype Pattern)

    案例: 某即时战略游戏,你训练出来各种很强的战士. 为了增加游戏的可玩性,增加了一种复制魔法.实施该魔法,可以复制任意的战士. 你会怎样考虑这个设计? 在继续阅读之前,请先认真思考并写出你的设计,这样 ...

  9. 设计模式(C#)——04原型模式

    推荐阅读:  我的CSDN  我的博客园  QQ群:704621321       在软件开发过程中,我们习惯使用new来创建对象.但是当我们创建一个实例的过程很昂贵或者很复杂,并且需要创建多个这样的 ...

随机推荐

  1. 用python爬取app照片

    首先下载一个斗鱼(不下载也可以,url都在这了对吧) 通过抓包,抓取到一个json的数据包,得到下面的地址 观察测试可知,通过修改offset值就是相当于app的翻页 访问这个url,返回得到的是一个 ...

  2. CCF-201604-3-路径解析

    问题描述 试题编号: 201604-3 试题名称: 路径解析 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 在操作系统中,数据通常以文件的形式存储在文件系统中.文件系统一般采 ...

  3. linux禁用锁定和解除解锁用户账号的方法

    Linux系统使用的是/etc/shadow保存加密了的用户密码,要禁止一个帐号的话,最快的方法就是修改存储于/etc/shadow中的密码. 一般情况下,一个有效的Linux用户在/etc/shad ...

  4. mysql left join 几个意思

    left join 用于多表  >1个表比如select a.*,b.* from ta as a left join tb as b on a.aid=b.bid咱们就以实际的代码来查看一下. ...

  5. php结合redis实现高并发下的抢购、秒杀功能 (转载)

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易想到 ...

  6. Aurora Player 开源啦~~~

    上一年做了很久的项目,是一个完整版的视频播放器,强大.美观!!! 现在转投UWP了,决定开源这个项目. 在你下载本项目之前,请仔细阅读每一行字,以免以后引起不必要的法律纠纷. 本项目最终解释权归本人所 ...

  7. Android测试:Testing Apps on Android

    原文:https://developer.android.com/training/testing/index.html 测试你的App是开发过程中的重要组成部分.通过对应用程序持续的运行测试,你可以 ...

  8. salesforce零基础学习(八十四)配置篇: 自定义你的home page layout

    当我们进入salesforce系统或者切换app后,默认第一个看到的就是home页面.home页面简单的来说可以包括左侧(narrow component)和右侧(wide component)两部分 ...

  9. 关于xshell:Connection closed by foreign host

    因为原来系统网有时掉,有时卡(同局域网别人没事),重新做了系统. 装了xmanager3,在用xshell连接linux服务器时,提示:服务器发送了一个无效的密钥,然后输出:Connection cl ...

  10. 10_Eclipse中演示Git冲突的解决

     1 在user1中的readme.txt文件里先改动,而且commitand push 选中user1,右击team->Commit-à watermark/2/text/aHR0cDov ...