hello,everybody,今天要探讨的问题是JS面向对象,其实面向对象呢呢,一般是在大型项目上会采用,不过了解它对我们理解JS语言有很大的意义。

首先什么是面向对象编程(oop),就是用对象的思想去写代码,那什么是对象呢,其实我们一直在用,像数组 Array  时间 Date 都是对象,并且这些对象是系统创建的,所以叫系统对象,而我们自己当然也可以创建对象,一般对象有两部分组成:

1 方法 (动态的,相当于对象下面的函数)比如Array 的push(),sort()方法

2  属性 (静态的,相当于对象下面的变量)Array的 length属性

OK,既然存在面向对象的编程,那么一定有它的优点,那么我们来看看它的四大特点:

抽象:抓住核心问题
封装:只能通过对象来访问方法
继承:从已有对象上继承出新的对象
多态:多对象的不同形态

这些特点呢,一开始理解是比较抽象的,只有我们在实践起来更能理解它的意义。不过我们做简单的介绍。

抽象:我们知道呢,不同的对象下面的方法是不一样的,比如数组有属于数组的方法属性,时间对象有属于它的方法属性,我们不能把时间对象的方法加给数组,把很多的方法分门别类,放到不同的对象下面,就是一种抽象,更好的管理。

封装:这个就比较好理解了,就是每个方法必须得在指定的对象下用。

继承:假如我们有两个弹窗,第二个弹窗相比第一个弹窗仅仅是多了一个功能,这个时候,就适合用继承,第二个可以继承第一个的功能,然后在这基础上再增加功能,继承提高了我们对代码的复用。

多态:也是代码复用的一种形式,用的不太多,比如有一个电脑,我们只用一个接口,然后连接不同的设备,这些设备可以实现不同的功能。听起来比较抽象,一般后端语言用的比较多。

下面我们来具体看面向对象的创建以及创建模式的演变

1 创建一个面向对象

//创建一个面向对象
var obj = new Object(); //创建一个空对象
obj.name = 'haha';
obj.showName = function(){
   alert(obj.name);

}
obj.showName();

这个栗子很简单,存在的问题是,当我们有多个面向对象的时候,重复代码过多,需要封装,所以有了下面的方法

2  工厂方式

function CreatePerson(name){
    //原料
    var obj = new Object();
    //加工
    obj.name = name;
    obj.showName = function(){
       alert(this.name);
   }
   //出厂
   return obj;
}

var p1 = CreatePerson('haha');
p1.showName();
var p2 = CreatePerson('hehe');
p2.showName();

这其实就是简单的封装函数,整个过程像工厂的流水线,所以叫工厂方式,但为了与我们的系统对象(Array等)保持一致,所以我们要进行改造,成为构造函数模式

3 构造函数模式

我们要通过这三个方面来改变:1 函数名首字母大写  2 New 关键字提取  3  this指向为新创建的对象

function CreatePerson(name){   //函数名首字母大写
     //var this=new Object(); //系统会偷偷在这里声明一个对象赋给this替咱们做,不用写
     this.name = name;      this.showName = function(){         alert(this.name);      }     //return this;//函数的默认返回值就是this即这个对象(隐式返回 不用自己再写返回值)

} 
var p1 =new CreatePerson('haha'); //当用new去调用一个函数:这个时候this指的就是创建出来的对象 而且函数的默认返回值就是this即这个对象(隐式返回 不用自己再写返回值) p1.showName();var p2 = new CreatePerson('hehe'); p2.showName();

所以最终的代码是这样的

function CreatePerson(name){
     this.name = name;
     this.showName = function(){
        alert(this.name);
     }
}
var p1 =new CreatePerson('haha');
 p1.showName();
var p2 = new CreatePerson('hehe');
 p2.showName();

但是函数构造模式也存在相应的问题:

alert(p1.showName==p2.showName);//false

测试这个代码,两个方法是不相同的,也就是说这两个对象并不是共用一个方法,每new一次,系统都会新创建一个内存,这两个对象各自有各自的地盘,但他们具有相同的功能,还不共用,肯定不是我们所希望的。所以就有了下一种方法,原型模式

4 原型模式

我们创建的每个函数都有原型(prototype),从字面意思看,就是指最原始的,原型是加在构造函数下面的,这个时候,通过这个构造函数创建出来的对象,都能共享这个原型下的方法和属性。

看个栗子(原型+构造)

function CreatePerson(name){
    this.name = name;
}
CreatePerson.prototype.showName = function(){
    alert(this.name);
}
var p1 =new CreatePerson('haha');
p1.showName();
var p2 = new CreatePerson('hehe');
p2.showName();

alert(p1.showName==p2.showName);//true

通过最后一句的测试为true,可以看到在构造函数的原型下面加的方法showName()方法是所有通过这个构造函数创建出来的对象所共享的,也就是说他们共用一个内存,更进一步的说它们存在引用关系,也就是说你更改了p1的showName也会影响p2的showName。

所以我们在构造对象的时候,一般是原型模式和构造模式组合使用,变化的用构造模式 不变的公用的用原型模式,就像上面的这个栗子,属性用的构造函数,因为一般不同对象属性都不同,方法用原型模式。

(补充):

原型和普通函数的区别(相当于style和class的区别)
  1 原型优先级低

function Thing(){}
var p =new Thing();
Thing.prototype.num= 1;
p.num = 2;
alert(p); //2 会优先在自己下面找,再去原型里面找
2 原型重用性高

3 原型所有东西共享一份

在这里我要介绍一个重要的属性就是constructor

1  它指的是对象的构造函数

2  每个自定义的构造函数都有的属性,当你写完一个构造函数的时候,系统程序会自动在函数的原型下添加对应的构造函数,比如有个自定义构造函数Aaa,系统会自动帮你添加这句话:

Aaa.prototype.construnctor = Aaa;(每个函数都有 都是自动生成的)

所以每个构造函数出生后,原型下面都有这样一个属性了。可以测试一下

 function Aaa(){}
 var a1 = new Aaa();
 a1.constructor  //Aaa函数

3 所以既然是原型下面的,证明构造函数也是可以被修改的。

 function Aaa(){}
 Aaa.prototype.construnctor=10;//添加
 var a1 = new Aaa();
 a1.constructor  //10

不过要避免修改这个属性。

4 不过有一种情况,我们需要修改,为了创建对象的代码更方便,你一定见过这样的代码,采用Json的方式在原型下加方法,也就是字面量法:

function Aaa(){}
Aaa.prototype = {
    num1:function(){alert(10);},
    num2:function(){alert(20);}
 } 
//这种方式相当于重新赋值了Aaa的原型 ,所以也覆盖掉了系统默认添加的这个:Aaa.prototype.construnctor = Aaa; 
var a1 = new Aaa();

a1.constructor //object

这个时候弹出的构造函数竟然变成了object,这是为什么呢,首先我们要知道object是所有对象的最初始的大boss,所有的对象都属于object,其次上面有讲过,每个最开始的构造函数的原型下面都有这样一句话,Aaa.prototype.construnctor = Aaa;这个例子的赋值方式,已经不是在原型上增加方法了,它属于一种赋值的方式,所以就把原来的构造函数给覆盖了,因此我们在写的时候需要修正一下原型的指向。

function Aaa(){}
Aaa.prototype = {
     constructor:Aaa,
     num1:function(){alert(10);},
     num2:function(){alert(20);}
}
var a1 = new Aaa(); a1.constructor // Aaa

关于JS面向对象之构造对象就先说到这里,其实还有别的不常用的模式,后续会继续补充,如果疏漏,欢迎补充,我是沐晴,不见不散

浅谈JS面向对象之创建对象的更多相关文章

  1. 浅谈JS面向对象

    浅谈JS面向对象 一 .什么是面向过程 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了.注重代码的过程部分. 二.什么是面向对象 最先出现在管理学 ...

  2. 浅谈JS之AJAX

    0x00:什么是Ajax? Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HT ...

  3. 浅谈JS继承

    今天呢,我们来谈谈继承,它也是JS语言中的一大重点,一般什么时候我们会用继承呢,比如有两个拖拽的面板,两个功能基本一致,只是第二个面板多了一些不同的东西,这个时候,我们就会希望,要是第二个直接能继承第 ...

  4. 浅谈JS中的闭包

    浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...

  5. 浅谈 js 正则字面量 与 new RegExp 执行效率

    原文:浅谈 js 正则字面量 与 new RegExp 执行效率 前几天谈了正则匹配 js 字符串的问题:<js 正则学习小记之匹配字符串> 和 <js 正则学习小记之匹配字符串优化 ...

  6. 浅谈 js 字符串之神奇的转义

    原文:浅谈 js 字符串之神奇的转义 字符串在js里是非常常用的,但是你真的了解它么?翻阅<MDN String>就可以了解它的常见用法了,开门见山的就让你了解了字符串是怎么回事. 'st ...

  7. 浅谈 js 正则之 test 方法

    原文:浅谈 js 正则之 test 方法 其实我很少用这个,所以之前一直没注意这个问题,自从落叶那厮写了个变态的测试我才去看了下这东西.先来看个东西吧. var re = /\d/; console. ...

  8. 浅谈 js 数字格式类型

    原文:浅谈 js 数字格式类型 很多人也许只知道 ,123.456,0xff 之类的数字格式.其实 js 格式还有很多数字格式类型,比如 1., .1 这样的,也有 .1e2 这样的. 可能有人说这是 ...

  9. 浅谈 js 语句块与标签

    原文:浅谈 js 语句块与标签 语句块是什么?其实就是用 {} 包裹的一些js代码而已,当然语句块不能独立作用域.可以详细参见这里<MDN block> 也许很多人第一印象 {} 不是对象 ...

随机推荐

  1. Spring-framework下载

    下载版本,修改版本号就行. http://repo.springsource.org/libs-release-local/org/springframework/spring/4.3.2.RELEA ...

  2. MyEclipse中SVN的常见的使用方法

    本次主要内容: 一 .导入项目 (Checkout).从svn资源库检出 二 .更新 (Update) 三.锁(对要修改的文件加锁,防止文件冲突) 四.提交(项目修改后的提交) 五.解锁 六.查看历史 ...

  3. centos7 + php7 lamp全套最新版本配置,还有mongodb和redis

    我是个懒人,能yum就yum啦 所有软件的版本一直会升级,注意自己当时的版本是不是已经更新了. 首先装centos7 如果你忘了设置swap分区,下面的文章可以教你怎么补一个上去: http://ww ...

  4. 常用awk命令(转)

    awk 用法:awk ' pattern {action} ' 变量名 含义 ARGC 命令行变元个数 ARGV 命令行变元数组 FILENAME 当前输入文件名 FNR 当前文件中的记录号 FS 输 ...

  5. libc.so.6被删后导致系统无法使用的原因及解决方法

    记一次升级glibc库发生的错误 今天给glibc库升级,发生了一件让我吓出一声汗的事情,我把动态库中的libc.so.6给删了,瞬间所有的非系统命令都无法使用,使用就报错 当时就吓尿了,生产环境被我 ...

  6. 一个fork的面试题

    前两天有人问了个关于Unix的fork()系统调用的面试题,这个题正好是我大约十年前找工作时某公司问我的一个题,我觉得比较有趣,写篇文章与大家分享一下.这个题是这样的: 题目:请问下面的程序一共输出多 ...

  7. Linux Bash shell one practice : array if else

    shell practice 1 1.require A B C D 1 2 3 4 5 6 7 8 3 5 8 0 1 2 4 3 after handling: T A B C D A 1 2 3 ...

  8. selenium处理div生成弹框

    目前遇到的弹框有两种,一种是alert,一种是div,如果遇到div模拟的弹框,在用alert就不行了. 1. public static Alert getAlert(WebDriver dr) { ...

  9. 【温故而知新-Javascript】图片效果(图像震动效果、闪烁效果、自动切换图像)

    1.当鼠标指针经过图像时图像震动效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...

  10. 2014 UESTC 暑前集训队内赛(2) 部分解题报告

    B.Cuckoo for Hashing 模拟题. 代码: #include <iostream> #include <cstdio> #include <cstring ...