练习中使用的浏览器为IE10,如果各位朋友有不同意见或者本文有什么错误地方,望指正

  ECMASCript有两种开发模式:函数式(面向过程)和面向对象。面向对象有一个很明显的标志,那就是类,我们可以通过类来创建很多具有相同的属性和方法的对象。但是ECMAScript中没有类的概念,它和其他很多的面向对象的高级语言中的面向对象不一样。

1、创建对象方式一    

  通过以前的var obj=new Object()方式来创建一个对象,是可以的,但是如果我们想创建两个或者多个相同属性或者方法对象的时候,势必会造成很多的代码,故这种方式不可取

  这种方式创建对象的时候,添加属性的时候必须要通过  对象名.属性名  的方式来增加属性,添加方法也是同样的,不过方法体可以声明为一个匿名方法,然后赋值给一个属性,方法中可以用this来代替对象obj,因为this代表的是当前的作用域所属的对象,也就是前面new出来的Obejct()

 //    传统的声明对象的方法,声明了两个长得差不多的对象,box,box2
var box=new Object(); //创建一个对象
box.user='abc'; //给对象添加属性
box.age=22;
box.run=function(){ //给对象添加方法,
return this.user+" "+this.age+" "+"运行中。。。";//this表示当前作用域下的对象
} // this 表示 new Object()实例化出来的那个对象
// this 要放在一个作用域下面,比如上面的box.run(){},这个是box对象作用域下的方法,方可用this,来表示box本身 alert(box.user); //abc
alert(box.run()); //abc 22 运行中。。。
alert(box instanceof Object); //true var box2=new Object(); //创建第二个对象
box2.user='jack'; //添加属性
box2.age='33';
box2.run=function(){ //添加方法
return this.user+" "+this.age+" "+"运行中。。。";//this表示当前作用域下的对象,即box2
} alert(box2.user); //jack
alert(box2.run()); //jack 33 运行中。。。
alert(box2 instanceof Object); //true

2、工厂模式创建对象

为解决上面问题而出现了工厂模式,这种方法就是为了解决实例化对象的时候产生大量的重复的代码的问题,创建方式如下:

 // 模试
function createObject(user,age){
var obj=new Object(); //创建一个新的对象,每调用一次就创建一次
obj.user=user; //给每个创建属性
obj.age=age;
obj.run=function(){ //this 就是指的当前创建的这个对象,obj
return this.user+" " +this.age+" "+"运行中...";
}
return obj; //需要返回这个对象,返回的是对象的引用
} //由模式创建变量 少了很多代码
var box1=createObject('abc',22); //创建对象box1
var box2=createObject('jack',33); //创建对象box2 alert(box1.run()); //abc 22 运行中... 运行对象box1的run方法
alert(box2.run()); //jack 33 运行中... 运行对象box2的run方法

  

  上面写了一个工厂模式,并且创建了一个对象,以后就可以调用这个对象的方法和属性了,但是这种方法还有一个问题就是,当有多个工厂模式,多个不同的类型的对象的时候,是无法判断具体是那个类型的实例对象

 // 模式2    内容中和模式1有一点小区别
function createObject2(user,age){
var obj=new Object();
obj.user=user;
obj.age=age+'a';
obj.run=function(){
return this.user+" " +this.age+" "+"运行中...";
}
return obj;
}
//由工程模式2创建的对象,
var box3=createObject2('tom',44); //用模式2创建对象box3
alert(box3.run()); //tom 44a 运行中... 运行对象box3的run方法 //判断三个变量结果都是object类型 但无法判断是那个工厂模式创建的
alert(box1 instanceof Object); //true
alert(box2 instanceof Object); //true
alert(box3 instanceof Object); //true    //不管怎样,他们都是Object类型,就无法区分,谁到底是谁的对象了

  如果用同一个模式创建了两个对象的话,即使赋初值是一样的,但是他们并不相等,因为他们是引用类型的,而且里面的方法也是引用类型的

    

    alert(box1.run);//均返回的是上面创建的时候=后面的内容
alert(box2.run); alert(box1==box2); //false 比较的是他们的引用,说明这是两个对象

3、构造函数初始化

  ECMAScript 中可以通过构造函数(构造方法)的方式来创建对象,类似于Object对象,创建方式如下:

 //定义了一个构造函数一
function Box(user,age){
this.user=user; //用构造函数创建的时候,后台会自动的创建一个对象,this就指向了这个对象
this.age=age; //由于是后台自动的创建,故不需要显示的new一个对象,而且用this代替对象名
this.run=function(){
return this.user+" "+this.age+" "+'运行中...';
} //构造函数创建的时候,是不需要显示返回的,后台会自动的返回他引用
} //用构造函数创建对象
var box1 = new Box('abc',22); //用构造函数创建对象,需要通过方式:new 构造函数名(参数表)
var box2 = new Box('jack',33); //运行两个对象的方法
alert(box1.run()); // abc 22 运行中...
alert(window.box1.run()); // abc 22 运行中...
alert(box2.run()); // jack 33 运行中...

  从上面可以看出,其实和C#等高级语言中的类差不多,构造函数中写同样的类容,外面创建变量的时候通过 new 构造函数名(参数)【高级语言中构造函数和类同名】。

  在用构造函数创建对象的时候,每当我们用new关键字来创建一个对象的时候,执行过程如下

    1)、当使用了构造函数,并且 new 构造函数() 的时候,后台就执行了new Object() 语句;

    2)、将构造函数的作用域给了新的对象,(就是new Object() 出来的对象),而函数中的this就代表了刚刚创建出来的这个对象;

    3)、执行构造函数中的代码;后台返回这个新对象的引用,后台直接返回

  和工厂模式相比不同:

    1)、我们省略了var obj=new Object(); 这一显示的实例化一个对象;

    2)、在添加属性和方法的时候用直接赋值给了this对象,即this来代替了工厂模式中的对象名;

    3)、没有了return语句,即不需要我们手动的将创建的这个对象进行返回,系统会自动的返回这个对象的引用

  使用构造函数的时候遵循的一些规范

    1)、构造函数也是函数,但是构造函数名最好是大写开头(有助于和普通函数进行区别);

    2)、使用构造函数创建对象的时候,必须通过 new 构造函数名(参数值) 来创建对象

  用构造函数创建的对象解决了工厂模式中遗留的问题,就是已经能够判断变量是由那个类型[构造函数]实例化而来的,因为用instanceof来判读对象的时候,可以将构造函数名Box当做类型来处理,故能够判断出实例对象是由那个构造函数类型实例化而来

 //构造函数二
function Box2(user,age){
this.user=user;
this.age=age;
this.run=function(){
return this.user+","+this.age+",运行中..."
}
}   var box3 = new Box2('tom',44); //判断对象的类型 可以知道是通过什么构造函数来创建的对象,变量时那个对象的引用
alert(box1 instanceof Object); //true
alert(box1 instanceof Box); //true 知道是用构造函数1来创建的对象
alert(box2 instanceof Object); //true
alert(box2 instanceof Box); //true
alert(box3 instanceof Object); //true
alert(box3 instanceof Box2); //true 知道是用构造函数2来创建的对象,box3是Box2对象的引用

  关于构造函数中的this:在全局中this代表的是window对象,在构造函数体内,this代表的就是当前构造函数声明的对象

  构造函数和普通函数的唯一区别就在于他们的调用方式不同,只不过构造函数也是函数,必须使用 new 运算符来调用才能够创建一个对象,否则就是普通的函数

  构造函数里面的方法返回的也是引用,当我们创建两个对象,传递相同的参数的时候,两个对象是不相等的,同时box1.run==box2.run [run是构造函数中定义的一个方法]的返回结果也是false,即方法是引用,具有唯一性的。既然是引用在创建方法的时候是可以用Functon类型来创建,即:this.run=new Function("return ...");这种方法来创建,但是这是没有必要的

 //下面两个执行的结果是一样的
alert(box1.run); //返回的是整个函数体 包括关键字 function
alert(box2.run); //返回的是整个函数体 包括关键字 function alert(box1.run==box2.run); //false 它们的返回值一样,但是不相等 因为他们比较的是引用 //既然构造函数中的方法是引用,也就是说可以写成this.run= new Function("this.user+this.age+'运行中...'");的形式,但是这样没有多少意义

  通过构造函数外面绑定同一个函数的方法来保证引用地址的一致性,因为这个方法是在外面创建的,只是创建了一次,即构造函数中使用 this.run=run; 后面这run是在全局中定义的一个方法。这样使用了全局的函数 run()来解决了保证引用地址一致的问题,但这种方式又带来了一个新的问题,全局中的 this 在对象调用的时候是 Box 本身,而当作普通函数调用的时候,this 又代表 window。故完全没有必要这样,而且不利于代码的封装

 //构造函数二
function Box2(user,age){
this.user=user;
this.age=age;
this.run=run;
} function run(){
return this.user+" "+this.age+" " +'运行中...';
} var box=new Box2('abc',22);
alert(box.run()); // abc 22 运行中...

  冒充调用:可以再外面定义一个Object类型,或者其他类型的变量,然后通过冒充调用来获取构造函数中声明的属性和方法,即通过prototype属性中的call和apply方法;

     var o=new Object();
Box.call(o,'maochong',55); //通过对象冒充的行试来获取这个对象的所有方法和属性
alert(o.user); //maochong
alert(o.run()); //maochong 55 运行中...

  

  这样,虽然对象o是Object类型的变量,但是由于冒充调用改变了它的作用域,它就具有构造函数Box中定义的所有的方法和属性

JS 学习笔记--12---面向对象的更多相关文章

  1. JS 学习笔记 (七) 面向对象编程OOP

    1.前言 创建对象有很多种方法,最常见的是字面量创建和new Object()创建.但是在需要创建多个相同结构的对象时,这两种方法就不太方便了. 如:创建多个学生信息的对象 let tom = { n ...

  2. JS学习笔记2_面向对象

    1.对象的定义 ECMAScript中,对象是一个无序属性集,这里的“属性”可以是基本值.对象或者函数 2.数据属性与访问器属性 数据属性即有值的属性,可以设置属性只读.不可删除.不可枚举等等 访问器 ...

  3. 《JavaScript高级程序设计》学习笔记12篇

    写在前面: 这12篇博文不是给人看的,而是用来查的,忘记了什么基础知识,点开页面Ctrl + F关键字就好了 P.S.如果在对应分类里没有找到,麻烦告诉我,以便尽快添上.当然,我也会时不时地添点遗漏的 ...

  4. Python3+Selenium3+webdriver学习笔记12(js操作应用:滚动条 日历 内嵌div)

    #!/usr/bin/env python# -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记12(js操作应用:滚动条 日历 内嵌div)'''from ...

  5. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  6. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  7. 一点感悟:《Node.js学习笔记》star数突破1000+

    写作背景 笔者前年开始撰写的<Node.js学习笔记> github star 数突破了1000,算是个里程碑吧. 从第一次提交(2016.11.03)到现在,1年半过去了.突然有些感慨, ...

  8. WebGL three.js学习笔记 6种类型的纹理介绍及应用

    WebGL three.js学习笔记 6种类型的纹理介绍及应用 本文所使用到的demo演示: 高光贴图Demo演示 反光效果Demo演示(因为是加载的模型,所以速度会慢) (一)普通纹理 计算机图形学 ...

  9. Node.js学习笔记(2):基本模块

    Node.js学习笔记(2):基本模块 模块 引入模块 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式.在No ...

  10. Vue.js学习笔记(2)vue-router

    vue中vue-router的使用:

随机推荐

  1. Win7系统下VS2008安装SP1补丁解决JQuery无智能提示的问题

    jQuery在vs2008中的智能提示 1  安装VS2008SP1补丁 要确保您的vs2008已经打了sp1补丁,在vs2008的帮助里的关于,要是安装了sp1,会出现“版本 3.5 sp1”,没安 ...

  2. js实现文字字幕滚动

    <div class="dggd_r" id="h" style="height:400px;overflow:hidden;display:i ...

  3. MHA学习笔记

    MHA是一款开源的MySQL高可用程序,为MySQL主从复制架构提供了节点故障转移功能,当 master发生故障时MHA会自动提升拥有最新数据的slave节点成为新的主节点,还提供了master节 点 ...

  4. Flex 4.0及4.6发布的网络应用在内网内会访问很慢的解决方案

    Flex 4.x 开发的程序部署在外网在能访问到www.adobe.com的时能够很快加载完成,但是部署在本地局域网,不能访问外网的服务器上,用浏览器访问应用需要加载几分钟的时间,这种等待时间客户几乎 ...

  5. 通过bind实现activity与service的交互

    先点bind按钮实现onCreate,在点击start给service传值(get方法) xml: <RelativeLayout xmlns:android="http://sche ...

  6. spark概论

    一.概述 1.轻:(1)采用语言简洁的scala编写:(2)利用了hadoop和mesos的基础设施   2.快:spark的内存计算.数据本地性和传输优化.调度优化,使其在迭代机器学习,ad-hoc ...

  7. 百度 迷你版 UMeditor富文本编辑器 使用方法

    第一步:下载编辑器 到官网下载 umeditor 最新版源码版本,下载之后打开 _examples/index.html 就可以看到演示例子.[下载页面] 第二步:部署编辑器到页面 解压下载的包,放到 ...

  8. C++文件操作(输入输出、格式控制、文件打开模式、测试流状态、二进制读写)

    1.向文件写数据 头文件#include <ofstream> ①Create an instance of ofstream(创建ofstream实例) ②Open the file w ...

  9. desin pattern

    uml tool http://cruise.site.uottawa.ca/umple/ http://www.umldesigner.org/download/ http://www.eclips ...

  10. 《大话设计模式》ruby版代码:简单工厂模式

    之前有看过<ruby设计模式>,不过渐渐的都忘记了.现在买了一个大话设计模式,看起来不是那么枯燥,顺便将代码用ruby实现了一下. # -*- encoding: utf-8 -*- #运 ...