创建一个对象,先来看一段代码:

// 例如创建一个 Person 的构造函数, 让人有名字, 可以说话
function Person ( name ) {
this.name = name;
// 可以说话, 需要有一个方法
this.sayHello = function () {
console.log( '你好, 我是 ' + this.name );
};
}
var p1 = new Person( '小明' );
var p2 = new Person( '大伟' );
console.log( p1.sayHello == p2.sayHello ); // false

  说明p1的sayHello()方法 和 p2的sayHello()方法 不相同。也就间接的说明每次创建一个实例化对象的时候都会在内存中重新开辟一个存储空间进行创建,一旦频繁创建实例化的对象时,会造成内存资源的浪费 。

 解决方法
          将公共的方法提取出来进行函数封装 (缺点: 代码比较乱、命名冲突几率大)
          将所有方法都绑定到对象的属性上(虽然 提高了代码可读性、也减少了命名冲突,貌似还是可以进行优化)
          JS 原生就支持解决方法:
             每个函数都有一个 prototype(原型)属性,将共享的方法绑定到 .prototype 原型上 即可
// 例如创建一个 Person 的构造函数, 让人有名字, 可以说话
function Person ( name ) {
this.name = name;
// 可以说话, 需要有一个方法
this.prototype.sayHello = function () {
console.log( '你好, 我是 ' + this.name );
};
}
var p1 = new Person( '小明' );
var p2 = new Person( '大伟' );
console.log( p1.sayHello == p2.sayHello ); // true   说明p1与p2访问的是同一组属性,同一个sayHello()方法。间接的说明用原型绑定公共的方法(共用一个存储空间)



原型的使用   
constructor(构造器):每个构造函数被创建出来都有一个prototype(原型)属性,每个原型属性都有个constructor属性,该属性默认指向 原构造函数。
  // 首先需要构造函数, 原则就是将独有的方法放在 对象中
function Person ( name, age, gender ) {
this.name = name;
this.age = age;
this.gender = gender;
}
 
将共享的方法放到默认的 .prototype 原型中,而独有的数据与行为放到对象中
 
    // 将共享的方法提取出来
Person.prototype.sayHello = function () {
console.log( '你好, 我是 ' + this.name );
};
Person.prototype.eat = function () {
console.log( this.name + '在吃饭' );
}; Person.prototype.run = function () {
console.log( this.name + '在跑步. 已经跑了 ' + this.age + ' 年' );
}; // 直接给原型对象添加成员
var p1 = new Person( 'lilei', 19, '男' );
var p2 = new Person( 'hanmeimei', 18, '女' );
  给原型 .prototype属性 重新赋值 ,将原来默认的 .prototype 覆盖掉  
// 让 Person.prototype 指向另一个对象. 直接赋值
Person.prototype = { constructor: Person, //constructor 默认指向 Object ,将其改为指向 原构造函数 sayHello: function () {
console.log( '第二种做法: 你好, 我是 ' + this.name );
}, eat: function () {
console.log( '第二种做法: ' + this.name + ' 在吃饭' );
}, run: function () {
console.log( '第二种做法: ' + this.name + ' 在跑步. 已经跑了 ' + this.age + ' 年' );
}
}; var p1 = new Person( 'lilei', 19, '男' );
var p2 = new Person( 'hanmeimei', 18, '女' );
 
  如果访问的对象的某个方法时,实例化的对象上没有该方法,就会到该对象的原型 . prototype 上去找
 
   下面是一个简单的 原型结构 分析图:

          

          构造函数   ----------  使用 prototype 属性   -----  访问原型
          实例对象   ----------  使用 __proto__属性   -----  访问原型   
          针对构造函数而言,原型就是 构造函数的 prototype 属性 ---  原型属性
          针对实例对象而言,原型就是 实例对象的 __ptoto__属性 ---  原型对象 
 
  注:以上是个人对原型的理解及总结,如有笔误的地方还请大家多指教!

JS --- 原型模式的更多相关文章

  1. Js原型模式

    function Person(){ } Person.prototype.name = "xd"; Person.prototype.age = 26; Person.proto ...

  2. js原型模式和继承

    function SuperType() { this.property = true; //原型属性 } //基类方法 SuperType.prototype.getSuperValue = fun ...

  3. JS中prototype属性-JS原型模式

    /* *对象方法 *类方法 * 原型方法 */ function People(name) { this.name = name; this.say = function () { //对象方法 al ...

  4. JS 原型模式创建对象

    例子: class Test { constructor(val) { this.val = val } walk() { console.log(this) console.log('walk') ...

  5. js设计模式:工厂模式、构造函数模式、原型模式、混合模式

    一.js面向对象程序 var o1 = new Object();     o1.name = "宾宾";     o1.sex = "男";     o1.a ...

  6. 面向对象JS基础讲解,工厂模式、构造函数模式、原型模式、混合模式、动态原型模式

    什么是面向对象?面向对象是一种思想!(废话). 面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下 ...

  7. 关于js的对象创建方法(简单工厂模式,构造函数模式,原型模式,混合模式,动态模式)

    // 1.工厂方式创建对象:面向对象中的封装函数(内置对象) 简单来说就是封装后的代码,简单的工厂模式是很好理解的,关于它的作用,就是利用面向对象的方法,把一些对象封装,使一些占用空间多的,重复的代码 ...

  8. JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)

    什么是面向对象?面向对象是一种思想. 面向对象可以把程序中的关键模块都视为对象, 而模块拥有属性及方法. 这样如果我们把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.   工厂 ...

  9. JS面向对象(1)——构造函数模式和原型模式

    1.构造函数模式 构造函数用来创建特定的类型的对象.如下所示: function Person(name,age,job){ this.name=name; this.job=job; this.ag ...

随机推荐

  1. MVVM与Backbone demo

    MVVM https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel

  2. C# async and await

    C# 5.0中引入了async 和 await.这两个关键字可以让你更方便的写出异步代码. 看个例子: public class MyClass { public MyClass() { Displa ...

  3. git tag — 标签相关操作

    标签可以针对某一时间点的版本做标记,常用于版本发布. 列出标签 $ Git tag # 在控制台打印出当前仓库的所有标签$ git tag -l 'v0.1.*' # 搜索符合模式的标签 打标签 gi ...

  4. DNS CNAME的一些细节

    1, 概述 DNS中的CNAME可以减轻运维压力,使得已有的DNS配置具有一定的灵活性和可扩展性.本文对CNAME中的一些细节做阐述, 使DNS服务器的运维人员和开发人员能合理地使用CNAME. 2, ...

  5. mysql时间属性之时间戳和datetime之间的转换

    一.datetime转换为时间戳     方案一:强制转换字段类型 use`nec`; ; ) NOT NULL COMMENT '注册时间' , ) NULL DEFAULT NULL COMMEN ...

  6. Java被忽略的基本知识(四)

    Java IO(不是一般的重要) 54.IO中的流:字节流(InputStream.OutputStream).字符流(Reader.Writer).转换流(InputStreamReader.Out ...

  7. centOs安装jdk1.7

    1,下载jdk-7u75-linux-x64.tar.gz,地址http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloa ...

  8. [整理]Centos6.5 + hadoop2.6.4环境搭建

    搭建Hadoop集群环境(3台机器) 1 准备环境 1.1 安装系统,并配置网络使3台机器互联互通,且SSH可直连(无需密码.保存私钥) 1.1.1 安装系统 安装Centos 6.5系统 安装过程略 ...

  9. Subversion Edge

    http://www.collab.net/downloads/subversion#tab-1

  10. dev GridView常用属性,事件

    一.属性 1.GridControl属性 //允许拖拽行 gridControl1.AllowDrop = true; 2.GridView属性 //不可编辑 gridView1.OptionsBeh ...