JS中的面相对象
1.使用Object或对象字面量创建对象
JS中最基本创建对象的方式:
var student = new Object();
student.name = "easy";
student.age = "20";
这样,一个student对象就创建完毕,拥有2个属性name以及age,分别赋值为"easy"和20。
如果你嫌这种方法有一种封装性不良的感觉。来一个对象字面量方式创建对象。
var sutdent = {
name : "easy",
age : 20
};
这样看起来似乎就完美了。但是马上我们就会发现一个十分尖锐的问题:当我们要创建同类的student1,student2,…,studentn时,我们不得不将以上的代码重复n次....
var sutdent1 = {
name : "easy1",
age : 20
};
var sutdent2 = {
name : "easy2",
age : 20
};
...
var sutdentn = {
name : "easyn",
age : 20
};
有个提问?能不能像工厂车间那样,有一个车床就不断生产出对象呢?我们看”工厂模式”。
2.工厂模式创建对象
JS中没有类的概念,那么我们不妨就使用一种函数将以上对象创建过程封装起来以便于重复调用,同时可以给出特定接口来初始化对象
function createStudent(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
return obj;
}
var student1 = createStudent("easy1", 20);
var student2 = createStudent("easy2", 20);
...
var studentn = createStudent("easyn", 20);
这样一来我们就可以通过createStudent函数源源不断地”生产”对象了。看起来已经高枕无忧了,但贪婪的人类总有不满足于现状的天性:我们不仅希望”产品”的生产可以像工厂车间一般源源不断,我们还想知道生产的产品究竟是哪一种类型的。
比如说,我们同时又定义了”生产”水果对象的createFruit()函数:
function createFruit(name, color) {
var obj = new Object();
obj.name = name;
obj.color = color;
return obj;
}
var v1 = createStudent("easy1", 20);
var v2 = createFruit("apple", "green");
对于以上代码创建的对象v1、v2,我们用instanceof操作符去检测,他们统统都是Object类型。我们的当然不满足于此,我们希望v1是Student类型的,而v2是Fruit类型的。为了实现这个目标,我们可以用自定义构造函数的方法来创建对象
3.构造函数模式创建对象
在上面创建Object这样的原生对象的时候,我们就使用过其构造函数:
var obj = new Object();
在创建原生数组Array类型对象时也使用过其构造函数:
var arr = new Array(10); //构造一个初始长度为10的数组对象
在进行自定义构造函数创建对象之前,我们首先了解一下构造函数和普通函数有什么区别。
1、实际上并不存在创建构造函数的特殊语法,其与普通函数唯一的区别在于调用方法。对于任意函数,使用new操作符调用,那么它就是构造函数;不使用new操作符调用,那么它就是普通函数。
2、按照惯例,我们约定构造函数名以大写字母开头,普通函数以小写字母开头,这样有利于显性区分二者。例如上面的new Array(),new Object()。
3、使用new操作符调用构造函数时,会经历(1)创建一个新对象;(2)将构造函数作用域赋给新对象(使this指向该新对象);(3)执行构造函数代码;(4)返回新对象;4个阶段。
ok,了解了构造函数和普通函数的区别之后,我们使用构造函数将工厂模式的函数重写,并添加一个方法属性:
function Student(name, age) {
this.name = name;
this.age = age;
this.alertName = function(){
alert(this.name)
};
}
function Fruit(name, color) {
this.name = name;
this.color = color;
this.alertName = function(){
alert(this.name)
};
}
这样我们再分别创建Student和Fruit的对象:
var v1 = new Student("easy", 20);
var v2 = new Fruit("apple", "green");
这时我们再来用instanceof操作符来检测以上对象类型就可以区分出Student以及Fruit了:
alert(v1 instanceof Student); //true
alert(v2 instanceof Student); //false
alert(v1 instanceof Fruit); //false
alert(v2 instanceof Fruit); //true alert(v1 instanceof Object); //true 任何对象均继承自Object
alert(v2 instanceof Object); //true 任何对象均继承自Object
这样我们就解决了工厂模式无法区分对象类型的尴尬。那么使用构造方法来创建对象是否已经完美了呢?使用构造器函数通常在js中我们来创建对象。
我们会发现Student和Fruit对象中共有同样的方法,当我们进行调用的时候这无疑是内存的消耗。
我们完全可以在执行该函数的时候再这样做,办法是将对象方法移到构造函数外部:
function Student(name, age) {
this.name = name;
this.age = age;
this.alertName = alertName;
}
function alertName() {
alert(this.name);
}
var stu1 = new Student("easy1", 20);
var stu2 = new Student("easy2", 20);
在调用stu1.alertName()时,this对象才被绑定到stu1上。
我们通过将alertName()函数定义为全局函数,这样对象中的alertName属性则被设置为指向该全局函数的指针。由此stu1和stu2共享了该全局函数,解决了内存浪费的问题
但是,通过全局函数的方式解决对象内部共享的问题,终究不像一个好的解决方法。如果这样定义的全局函数多了,我们想要将自定义对象封装的初衷便几乎无法实现了。更好的方案是通过原型对象模式来解决。
4.原型的模式创建对象
原型链甚至原型继承,是整个JS中最难的一部分也是最不好理解的一部分,在这里由于我们课程定位的原因,如果对js有兴趣的同学,可以去查阅一下相关JS原型的一些知识点。更加有助于你以后前端JS的面试。
function Student() {
this.name = 'easy';
this.age = 20;
}
Student.prototype.alertName = function(){
alert(this.name);
};
var stu1 = new Student();
var stu2 = new Student();
stu1.alertName(); //easy
stu2.alertName(); //easy
alert(stu1.alertName == stu2.alertName); //true 二者共享同一函数
JS中的面相对象的更多相关文章
- JS中的event 对象详解
JS中的event 对象详解 JS的event对象 Event属性和方法:1. type:事件的类型,如onlick中的click:2. srcElement/target:事件源,就是发生事件的 ...
- js中两个对象的比较
代码取自于underscore.js 1.8.3的isEqual函数. 做了一些小小的修改,主要是Function的比较修改. 自己也加了一些代码解读. <!DOCTYPE html> & ...
- MVC中处理Json和JS中处理Json对象
MVC中处理Json和JS中处理Json对象 ASP.NET MVC 很好的封装了Json,本文介绍MVC中处理Json和JS中处理Json对象,并提供详细的示例代码供参考. MVC中已经很好的封装了 ...
- js中的json对象详细介绍
JSON一种简单的数据格式,比xml更轻巧,在JavaScript中处理JSON数据不需要任何特殊的API或工具包,下面为大家详细介绍下js中的json对象, 1.JSON(JavaScript Ob ...
- JavaScript -- 时光流逝(五):js中的 Date 对象的方法
JavaScript -- 知识点回顾篇(五):js中的 Date 对象的方法 Date 对象: 用于处理日期和时间. 1. Date对象的方法 <script type="text/ ...
- JavaScript -- 时光流逝(四):js中的 Math 对象的属性和方法
JavaScript -- 知识点回顾篇(四):js中的 Math 对象的属性和方法 1. Math 对象的属性 (1) E :返回算术常量 e,即自然对数的底数(约等于2.718). (2) LN2 ...
- JavaScript -- 时光流逝(三):js中的 String 对象的方法
JavaScript -- 知识点回顾篇(三):js中的 String 对象的方法 (1) anchor(): 创建 HTML 锚. <script type="text/javasc ...
- js中 给json对象添加属性和json数组添加元素
js中 给json对象添加新的属性 比如现在有一个json对象为jsonObj,需要给这个对象添加新的属性newParam,同时给newParam赋值为pre.做法如下: var obj={ &quo ...
- js中关于Blob对象的介绍与使用
js中关于Blob对象的介绍与使用 blob对象介绍 一个 Blob对象表示一个不可变的, 原始数据的类似文件对象.Blob表示的数据不一定是一个JavaScript原生格式 blob对象本质上是 ...
随机推荐
- springcloud(十四):搭建Zuul微服务网关
springcloud(十四):搭建Zuul微服务网关 1. 2. 3. 4.
- 【网络流24题】最长k可重区间集问题(费用流)
[网络流24题]最长k可重区间集问题 [问题分析] 最大权不相交路径问题,可以用最大费用最大流解决. [建模方法] 方法1 按左端点排序所有区间,把每个区间拆分看做两个顶点<i.a>< ...
- HDU RSA 扩展欧几里得
Problem Description RSA is one of the most powerful methods to encrypt data. The RSA algorithm is de ...
- Spring实现封装自定义注解@Trimmed清除字符串前后的空格
在Spring中实现字符串清除的方法有很多,原生方法String自带trim()方法,或者使用StringUtils提供的trim...方法. 通常可以将上面的方式封装成自定义注解的形式去实现来节省更 ...
- ScrollView双击图片定点放大
直接先说原理吧--原理:利用了scrollview的回调函数(如下)以及scrollview自己内部的一些缩放规则(其实我也还没弄清楚具体scrollview干了什么事),只是知道了它可以怎么做-_- ...
- Intellij IDEA安装插件
从Eclipse到Intellij IDEA换过来,还是没有适应,并且电脑异常的卡顿,4核4G内存的机器表示伤不起.Intellij IDEA还有待我进行调教. 今天说明一下怎样安装插件.以keyPr ...
- Raphael.js image 在ie8以下的兼容性问题
Raphael.js 在ie7,ie8浏览器内绘制图形採用的vml,在绘制image的时候会解析成 <?xml:namespace prefix = "rvml" ns = ...
- C 语言宏快速入门
//####### 参照C语言的预处理命令简介 ######## #define 定义一个预处理宏 #undef 取消宏的定义 #include 包含文件命令 #include_next 与#incl ...
- Cisco VPP(1) 简单介绍
一.简单介绍 VPP全称Vector Packet Processing.是Cisco2002年开发的商用代码. 2016年2月11号,Linux基金会创建FD.io项目.Cisco将VPP代码的开源 ...
- 每日一支TED——弗兰斯·兰庭:为动物发声的摄影作品——2015年6月3日
今天是听TED的第11天,从今天開始简单写一下听TED的感受! 刚把得! 弗兰斯·兰庭从一个部落得到一个思想说:全部的动物都是一样的.虽然他们的外形不一样.可是内在确实一样的,他们在外面伪装,可是他们 ...