1、构造函数模式

构造函数用来创建特定的类型的对象。如下所示:

function Person(name,age,job){
  this.name=name;
  this.job=job;
  this.age=age;
  this.sayName=function(){
    alert(this.name);
  };
}
var person1=new Person('nick',20,'student');
var person2=new Person('nick',20,'student');
alert(person1.sayName==person2.sayName);//false

构造函数特点:不需要显示地创建对象,直接将属性和方法赋给this对象;

创建构造构造函数的实例,需要用new操作符,new操作符会创建一个新对象,而后将构造函数的作用域指向新的对象。

构造函数的缺点:上面的例子中,构造函数内的sayName()方法,也可以写为 this.sayName()=new Function("alert(this.name)") 可以看出来,每次创建一个Person的实例都会创建一个新的sayName实例,不同的实例,有不同的作用域链和标识符解析,因此不同实例上的同名函数不相等!

对于这个缺点,我们可以考虑一下:既然在函数内创建的新的sayName实例有不同的作用域链,假设我们将sanName函数定义转义到构造函数外部,那么sayName函数就处于一个全局环境中了!

function Person(name,age,job){
...
}
function sayName(){
alert(this.name);
}
var person2=new Person1('alex',20,'student');
var person3=new Person1('alexx',20,'student');
alert(person2.sayName==person3.sayName);//true 两个都是引用同一个全局作用域中定义的函数

2、原型模式

  JS高级程序设计的P147对于原型属性的解释是这样的:每个函数都有一个prototype原型属性,它是一个指针,指向一个对象,这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。怎么理解这句话呢,其实就是我可以创建2个实例person,这两个对象实例继承了构造函数的属性,其中包括prototype,因此它们也就具有了prototype中的所有实例共享的属性和方法了!

  如下,原型模式中,直接把属性方法写到prototype中

function Person(){
}
Person.prototype.name='nick';
Person.prototype.age=20;
Person.prototype.sayName=function(){
alert(this.name);
};
var person1=new Person();
var person2=new Person();
person2.name="jack";
alert(person1.name);//nick 继承Person的原型属性,先读取person1实例中的属性,没找到name属性再搜索原型对象中的属性
alert(person2.name);//jack 在实例中添加一个属性,将同名的原型属性屏蔽了
alert(person1.hasOwnproperty('name));//true person1实例有name属性
alert(person2.hasOwnproperty('name));//true person2实例没有name属性,它的name属性存在于所继承的Person原型属性中

  (1)通过hasOwnProperty()方法可以检测一个属性是存在实例还是原型中。

  (2)通过in操作符,只要实例或者原型有所查找属性就返回true;

alert("name" in person2);//true name在person的原型中

原型模式的缺陷:

编写原型对象,可以使用对象字面量,但是会导致Person.constructor属性不再指向Person,即

alert(person constructor==Person);//false 

这方面在JS高级程序设计P154中有详细讲到。

还有一个缺陷:前面说到,原型属性是被实例共享的,对于包含基本值的属性来说,如果在某个实例中把某个原型属性修改了就会反映在其他实例中。

function Person(){
}
//用对象字母两来重写整个原型对象更简便
Person.prototype={
name:'NICK',
age:20,
job:'student',
friend:['aa','bb'];
sayName:function(){
alert(this.name);
}
}
var person1=new Person();
var person2=new Person();
person1.friend.push('cc');
alert(person2.friend);//['aa','bb','cc'];在person1中修改的内容反映在person2中

组合使用构造函数模式和原型模式

这种方式的好处在于:构造函数可以保持实例属性的独立,原型模式可以定义共享的属性的方法;

 function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friend=['aa','bb'];
} Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name);
}
}
var person1=new Person('nick',20,'student');
var person2=new Person('jerry',10,'student'); person1.friend.push('cc'); alert(person1.name);
alert(person1.friend);
alert(person2.name);
alert(person2.friend);//aa bb 往person1的friend添加cc,不会影响到person2因为friend不是原型属性

理解了原型模式,对于后面原型链的认识理解很重要,比如原型链的问题,原型链是通过

function SuperType(){
this.color=['aa','bb'];
}
function Subtype(){}
Subtype.prototype=new SuperType();//继承supertype Subtype.prototype成为SuperType的一个实例,因此Subtype建立的实例,都会拥有SubType的原型属性,这个原型属性是共享的! var instance1=new Subtype();
var instance2=new Subtype();
instance1.color.push('cc');
alert(instance2.color);//['aa','bb','cc'];

这个缺点同样可以使用构造函数来解决。找时间再写JS面向对象(2)——原型链

第一次写自己学习的一些总结呢,最近在在JS高级程序设计,感觉看了对JS的理解提升很大!加油!

 

JS面向对象(1)——构造函数模式和原型模式的更多相关文章

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

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

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

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

  3. JavaScript之面向对象学习六原型模式创建对象的问题,组合使用构造函数模式和原型模式创建对象

    一.仔细分析前面的原型模式创建对象的方法,发现原型模式创建对象,也存在一些问题,如下: 1.它省略了为构造函数传递初始化参数这个环节,结果所有实例在默认的情况下都将取得相同的属性值,这还不是最大的问题 ...

  4. javascript 面向对象编程(工厂模式、构造函数模式、原型模式)

      javascript 面向对象编程(工厂模式.构造函数模式.原型模式) CreateTime--2018年3月29日17:09:38 Author:Marydon 一.工厂模式 /** * 工厂模 ...

  5. 【js基础】创建对象的几种常见模式(工厂模式,构造函数模式,原型模式,构造原型组合模式)

    一.工厂模式 缺点:没有解决对象识别的问题 优点:解决了创建多个相似对象的问题 function createPerson(name,age,job){ var o = new Object(); o ...

  6. JS中使用组合构造函数模式和原型模式

    创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式.构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性. 结果,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的 ...

  7. javacript 组合使用构造函数模式和原型模式

    构造函数模式创建对象 基本方法 function Person(name,age){ this.name=name; this.age=age; this.sayName=function(){ al ...

  8. js面向对象(构造函数与继承)

    深入解读JavaScript面向对象编程实践 Mar 9, 2016 面向对象编程是用抽象方式创建基于现实世界模型的一种编程模式,主要包括模块化.多态.和封装几种技术. 对JavaScript而言,其 ...

  9. 初涉JavaScript模式 (7) : 原型模式 【三】

    组合使用构造函数模式和原型模式 上篇,我们提到了原型模式的缺点,就是每个实例不能拥有自己的属性,因为纯原型模式所有的属性都是公开给每个实例的,故我们可以组合使用构造函数模式和原型模式.构造函数用来定义 ...

随机推荐

  1. js 中this到底指向哪里?

    其实js的this指向很简单.我们记住下面3种情况. this 指向的是浏览器中的window.代码如下: function fn(){ this.name='yangkun'; this.age=2 ...

  2. encodeURI和encodeURIComponent的区别?

    encodeURI方法不会对下列字符编码 ASCII字母.数字.~!@#$&*()=:/,;?+' encodeURIComponent方法不会对下列字符编码 ASCII字母.数字.~!*() ...

  3. 数据结构实验病毒感染检测问题(C++)

    医学研究者最近发现了某些新病毒,通过对这些病毒的分析,得知他们的DNA序列都是环状的.现在研究者已收集了大量的病毒DNA和人的DNA数据,想快速检测出这些人是否感染了相应的病毒.为了方便研究,研究者将 ...

  4. [luogu4162 SCOI2009] 最长距离(最短路)

    传送门 Solution 题目是最长路,其实是最短路ヽ(ー_ー)ノ 把进入障碍点的边设为1,其他为0.枚举每个点为起点找距离<=T的点,更新答案 Code //By Menteur_Hxy #i ...

  5. Codeforces 899C - Dividing the numbers

    传送门:http://codeforces.com/contest/899/problem/C 本题是一个数学问题——集合划分. 将集合{1,2,...,n}划分成两个集合,使得两个集合的元素之和的绝 ...

  6. JUnit单元测试实践:测试工具类和方法(EmptyUtils)

    以前的时候(读大学时),我认为写单元测试太费事了.现在,我改变看法了. 工作中,为了提高Web开发的质量和效率,近期又为了保证自己的工具类等一系列可复用组件的质量,我煞费苦心地开始认真学习和撰写单元测 ...

  7. 【codeforces 798C】Mike and gcd problem

    [题目链接]:http://codeforces.com/contest/798/problem/C [题意] 给你n个数字; 要求你进行若干次操作; 每次操作对第i和第i+1个位置的数字进行; 将 ...

  8. 心急的C小加 贪心算法

    心急的C小加 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 C小加有一些木棒,它们的长度和质量都已经知道,需要一个机器处理这些木棒,机器开启的时候需要耗费一个单位的 ...

  9. SUSAN算子

  10. 王立平--Http中Get() 与 Post()的差别?

    Http协议是基于TCP协议的,而TCP协议是一种有连接.可靠的传输协议.假设丢失的话,会重传.所以这种话,就 不会有数据的丢失了. 而Http协议有三种方法.Get,Post,Head方法.可是用的 ...