`
Supanccy2013
  • 浏览: 223650 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

js面向对象2--js中工厂模式的演化(重要,详细)

阅读更多
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<script type="text/javascript">
    /*
          总括:
    javascript创建对象的模式演化:1,函数创建----》2,构造函数创建
    -----》3.原型创建
    */
    
    //第一种模式:函数创建模式
    //因为js无法创建类,开发人员刚开始发明了一种函数,用函数来封装以特定接口创建
    //对象的细节,如:
    function createPerson(name,age,job)
    {
    	var o = new Object();
    	o.name = name;
    	o.age = age;
    	o.job = age;
    	o.sayName = function sayName(){
    		alert(this.name);
    	};
    	return o;
    }
    
    function onloadFunction()
    {
    	var person1 = createPerson("陈超阳","27","java Soft Enginner")
    	var person2 = createPerson("heshengnan","23","java Soft Enginner")
    	console.log(person1);
    	console.log(person2);
    	console.log(person1.constructor); //打印出Object
    	console.log(person2.constructor); //打印出Object
    }
    
    /*
	    函数工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题
	    (即怎样知道一个对象的类型)
	    Person1,person2的构造函数都是Object,因此无法辨别对象的类型
	    随着JavaScript的发展,出现了一种新的工程模式--构造函数模式
    */
    
    
    //第二种模式:构造函数模式
    /*
	    注意:
	    1,该种模式没有显示创建对象也就是没有用new Object();
	    2,直接将属性和方法赋值给this对象。
	    3,没有return语句
	    4.函数名字的首字母是大写的(以便区分构造函数和一般函数的区别)
	    5,要创建Person的新实例必须使用new关键字
	    */
	    /*
	       使用new 构造函数创建对象的步骤:
	       1,js引擎会自动创建一个对象。
	       2,将构造函数的作用域赋给新对象(因此this就指向了新对象)
	       3,执行构造函数里面的代码(为这个新对象添加属性方法);
	       4,返回新对象
	    */
    
    function Person(name,age,job)
    {
    	this.name = name;
    	this.age = name;
    	this.job = job;
    	this.sayName = function(){
    		alert(this.name);
    	}
    }
    
    function onloadFunction2()
    {
    	var person3 = new Person("陈超阳","27","java Soft Enginner");
    	var person4 = new Person("heshengnan","23","java Soft Enginner")
    	console.log(person3.constructor); //打印出Person(name, age, job)
    	console.log(person4.constructor); //打印出Person(name, age, job)
    	
    	//构造函数设计之初是用来标示对象类型的,但是提到检测对象类型,还是用instanceof操作符
    	//要更可靠一些,我们在这个例子中创建的所有对象既是Object的实例,同时也是Person的实例
    	//这一点可以用instanceof操作符可以得到验证
    	console.log(person3 instanceof Object);  //true;
    	console.log(person3 instanceof Person);  //true;
    	console.log(person4 instanceof Object);  //true;
    	console.log(person4 instanceof Person);  //true;
    }
    //注意以这种方法创建的构造函数是定义在global对象(在浏览器中是window中的)
    
    /*
          构造函数的缺点:
          构造函数虽然好用,但并非没有缺点。使用构造函数的主要问题,就是每个方法都要在每个实例上重新创建一边
          。在上面的例子中。person1和person2都有一个名字叫做sayName()的方法,但这两个sayName()
          方法不是同一个function实例。不要忘记了——EcmaScript中的对象,因此每定义一个函数也就实例化了
          一个对象。从逻辑上讲,此时的构造函数也可以如下面定义:
    */
    function Person(name,age,job){
    	this.name = name;
    	this.age = age;
    	this.job = job;
    	this.sayName = new Function(){alert(this.name)};
    }
    /*
          从这个角度来看构造函数,更容易明白每个Person实例都包含一个不同的function实例(以显示name属性)
          的本质。说明白些,以这种方式创建函数,会导致不同的作用域链和标示符解析,但创建function新实例的
          机制仍然相同。因此,不用实例上的同名函数是不相同的,一下代码可以证明这一点:
          console.log(person.sayName == person2.sayName);
          然而,创建两个完成同样任务的function实例的确没有必要,况且有this对象在,根本不用在执行代码前就
          把函数绑定到特定对象上面,大可像下面这样,通过把函数定义在构造函数外来解决这个问题:
          function Person (name,age,job)
          {
        	  this.name = name;
        	  this.age = age;
        	  this.job = job;
        	  this.sayName = sayName;
          }
          function syaName()
          {
        	  alert(this.name);
          }
          在这个例子中,我们把sayName()函数的定义转移到了构造函数的外部。而在构造函数内部,我们
          将sayname属性值设置成等于全局函数sayName()。这样一来,由于sayName包含的是一个指向
          函数的指针,因此person1和person2对象就共享了在全局作用域中定义的同一个sayName函数
          这样做确实解决了两个函数做同一件事情的问题,可是新问题又来了:在全局作用域中定义的函数
          实际上只能被某个对象调用,这让全局函数有点名不副实,而更让人无法接受的是,如果对象需要定义
          很多函数,那么就需要定义很多个全局函数,于是我们这个自定义的引用类型就没有封装而言了,好在
          这些问题可以使用原型模式解决。
    */
    
    
    /*
          第三:原型模型
          我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个
          对象的用途是包含可以由特定类型的所有实例共享的属性和方法。如果按照字面意思来理解,那么
          prototype就是通过调用构造函数而创建的那个对象实例的原型对象。使用原型对象的好处是
          可以让所有对象共享它所包含的属性和方法,换句话说,不必在构造函数中定义对象实例的信息,而是
          可以将这些信息直接添加到这些对象上,如下面的这些例子:
    */
    function Person(){}
    Person.prototype.name = "chenchaoyang";
    Person.prototype.age = "454";
    Person.prototype.job = "soft enginner";
    Person.prototype.sayName = function(){alert(this.name)};
    
    var person1 = new Person(){};
    person1.sayName();
    
    var person2 = new Person(){};
    person2.sayName();
    
    console.log(person1.sayName = person2.sayName); //true
    
    /*
        在此,我们将sayname()方法和所有属性直接添加到了Person的prototype属性中,构造函数
        变成了空函数,即使如此,也仍然可以通过调用构造函数来创建对象,而且对象还会具有相同的属性
        和方法,但与构造函数模式不同的是:新对象的浙西二属性和方法是所实例共享的,换句话说,person1
        和person2访问的都是同一组属性和同一个sayName函数,要理解原型模式的工作原理,必须先理解
        EcmScript中原型对象的性质。
        
        理解原型对象:
        无论什么时候,只要创建了一个函数,就会根据一组特定的规则为这个函数创建一个prototype属性,
        这个属性指向函数的原型对象。 在默认情况下,所有原型对象都会自动获得一个constrcutor构造函数
        ,这个属性包含一个纸箱prototype属性所在函数的指针。就拿全面的例子来说,Person.prototype
        .construtctor指向Person,而通过这个函数,我们可以继续为原型对象添加其他属性和方法。
    */
    
    /*
             重要:访问一个对象 的属性的过程是这样的:
             首先检查这个对象是否含有自身的属性(不是这个对象含有的prototype对象的属性),如果有就直接
             访问。  如果没有就去这个对象的prototype对象中检查是否含有这个属性。
             也就是  首先访问自己是否含有这个属性,  然后再检查这个对象的prototype中是否含有这个属性。
             例如一下例子:
    */
    function Person(){}
    Person.prototype.name = "chenchaoyang";
    Person.prototype.age = 27;
    Person.prototype.job = "softWare enginner";
    Person.prototype.syaName = function(){
    	console.log(this.name);
    }
    var person1 = new Person();
    var person2 = new Person();
    person1.name = "heshegnnan";
    
    console.log(person1.name);  //"heshegnnan"来自实例
    console.log(person2.name);  //"chenchaoyang"来自原型对象
    
    /*
         总结:当为对象添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性,换句话说,添加这个属性
         只会阻止我们访问原型中的那个属性,但不会修改那个属性。及时这个属性设置为null,也只会在实例中
         设置这个属性,而不会恢复指向原型的链接。不过,使用delete操作符则可以完全删除实例属性,从而
         让我们能够重新访问原型中的属性:例如:
         function Person(){};
         Person.prototype.name = "chenchaoyang";
         Person.prototype.age = 12;
         Person.prototype.job = "softWare enginner";
         Person.prototype.sayName = function sayName(){
        	 alert(thos.name);
         }
         
         var person1 = new Person();
         var person2 = new Person();
         
         person1.name = "Greg";
         alert(person1.name);  //Greg  来自实例
         alert(person2.name);  //chenchoyang  来自原型对象
         
         delete person1.name;
         alert(person1.name);  //chenchaoyang  来自原型对象
         
         
             使用hanOwnProperty()方法可以检测一个属性是否存在于实例中,还是存在于原型中。
             这个方法(不要忘了它是从Object继承来的)只在属性存在于对象实例中时,才会返回
             true,来看看一下的例子:
         function Person(){}
         Person.prototype.name = "chenchaoyang";
         Person.prototype.age = 22;
         Person.prototype.job = "software enginner";
         Person.sayName = function sayName(){
        	 alert(this.name);
        	 
         var person1 = new Person();
         person1.hasOwnProperty("name"); //false
         
         person1.name = "heshegnnan";
         person1.hasOwnProperty("name"); //true
         
         使用hasOwnProperty方法,什么时候访问的实例属性,什么时候访问的是原型属性就一清二楚了。
         }
    */

</script>
</head>
<body onload="onloadFunction();onloadFunction2();">
</body>
</html>
分享到:
评论
1 楼 Cobain_LI 2016-11-14  
有个小失误,144和147行多了两个花括号

相关推荐

    javascript面向对象编程.pdf

    总而言之,学习现代JavaScript面向对象编程,有助于开发者在认识这门语言演化的基础上,运用面向对象的设计和编程模式来构建更加健壮和可维护的JavaScript应用程序。同时,测试和调试是保证代码质量不可或缺的环节,...

    javascript面向对象编程PDF

    原型是JavaScript面向对象编程的一个核心概念,每个对象都有一个原型对象,通过它可以继承其他对象的属性和方法。 程序示例分析: 在文档提供的代码示例中,Lecture类和Schedule类展示了如何在JavaScript中实现面向...

    javascript面向对象编程

    通过这种方式,JavaScript面向对象编程不仅包括了代码的实际编写,还包括了测试和调试的环节,确保代码的质量和可维护性。学习和掌握面向对象编程的方法是学习JavaScript的重要一环,对于任何想要深入学习并掌握...

    javascript面向对象编程pdf

    总结来说,JavaScript面向对象编程涵盖了从基本原理到实现细节的多个方面,包括但不限于对象、构造函数、原型链、继承以及封装等。本书系统地介绍了这些知识点,并通过实例演示了如何在现代JavaScript中实现OOP,...

    由图灵机到面向对象程序编程----程序的语义表达探讨

    2. **面向对象编程**:随着计算机科学的发展,面向对象编程(OOP)成为了主流,如C++的出现。OOP强调数据和操作数据的方法封装在一起,形成对象,通过类和继承构建复杂的系统。这种方式增强了程序的抽象性和模块化,...

    jsjava

    1. 类和对象支持:模仿Java的面向对象编程模式,允许开发者创建类和实例,进行封装和继承。 2. 类型检查:尽管JavaScript是动态类型的,但JsJava可能提供了一种方式来强制类型检查,增加代码的稳定性和可预测性。 ...

    悟透JavaScript.chm

    为了适应面向对象编程的潮流,JavaScript语言也在向完全面向对象的方向发展,新的JavaScript标准已经从语义上扩展了许多面向对象的新元素。与此相反的是,许多静态的对象语言也在向JavaScript的那种简洁而幽雅的方向...

    全栈工程师修炼指南 下载

    15-重剑无锋,大巧不工: JavaScript面向对象.mp3 16-百花齐放,百家争鸣:前端MVC框架.mp3 17-不一样的体验:交互设计和页面布局.mp3 18-千言万语不及一幅画:谈谈数据可视化.mp3 19-打开潘多拉盒子: JavaScri

    JavaScript权威指南_第6版

    在更高级的应用中,JavaScript还支持面向对象编程(OOP)的概念,允许开发者利用类和继承来组织和复用代码。随着ECMAScript标准的发展,JavaScript也在不断演化,引入了诸如箭头函数、模块、异步编程(Promise、...

    项目示例源码解析与展示

    例如,Java中的面向对象特性,包括类、接口、继承、多态等;Python的动态类型和简洁语法;C++的模板和指针操作;JavaScript的异步编程模型等。 其次,代码组织结构也是解析源码的重要部分。一个项目通常包含多个...

    game-of-life-js:约翰·康威(John Conway)的《人生游戏》JavaScript实现

    总的来说,通过JavaScript实现《人生游戏》,不仅可以学习到基本的编程概念和技巧,如数组操作、条件判断、循环和函数,还能了解到更高级的主题,如面向对象编程和事件驱动编程。这样的项目不仅有趣,而且有助于提升...

    gol.js:javascript中简单(未完成)的生活游戏

    同时,这也是一个练习面向对象编程和算法的好例子,因为生命游戏的规则可以通过封装在类或函数中来实现。尽管该项目可能未完成,但它为那些想要探索JavaScript和康威生命游戏的互动性提供了一个宝贵的起点。

    COINDEX-源码.rar

    COINDEX的源码中可能会应用到各种设计模式,如工厂模式、单例模式、观察者模式等,这些模式在软件工程中有着广泛应用,有助于提高代码的可读性和可维护性。 6. **算法与数据结构** "索引"一词暗示COINDEX可能涉及...

    pwxe-源码.rar

    3. **编程范式**:源代码可能展示了面向对象、函数式、过程式或面向切面等不同的编程范式,通过类、函数、模块等来组织代码。 4. **设计模式**:开发者可能运用了常见的设计模式,如工厂模式、单例模式、装饰器模式...

    javapms-1.2-beta.zip

    Java PMS的实现离不开Java的基础知识,包括面向对象编程、异常处理、集合框架、多线程等。源码中,你可以看到类的设计、继承、封装、多态的体现,同时会涉及到线程同步、并发控制等进阶概念。这对于理解和运用Java...

    Java项目实战-物流信息网的设计与实现(附源码,部署说明).zip

    1. **Java编程语言**:作为项目的基石,Java以其平台无关性、面向对象的特性以及丰富的库支持,为物流信息系统的开发提供了稳定且高效的编程环境。项目中的源码充分体现了Java的这些优势。 2. **MVC设计模式**:...

Global site tag (gtag.js) - Google Analytics