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中的面相对象的更多相关文章

  1. JS中的event 对象详解

    JS中的event 对象详解   JS的event对象 Event属性和方法:1. type:事件的类型,如onlick中的click:2. srcElement/target:事件源,就是发生事件的 ...

  2. js中两个对象的比较

    代码取自于underscore.js 1.8.3的isEqual函数. 做了一些小小的修改,主要是Function的比较修改. 自己也加了一些代码解读. <!DOCTYPE html> & ...

  3. MVC中处理Json和JS中处理Json对象

    MVC中处理Json和JS中处理Json对象 ASP.NET MVC 很好的封装了Json,本文介绍MVC中处理Json和JS中处理Json对象,并提供详细的示例代码供参考. MVC中已经很好的封装了 ...

  4. js中的json对象详细介绍

    JSON一种简单的数据格式,比xml更轻巧,在JavaScript中处理JSON数据不需要任何特殊的API或工具包,下面为大家详细介绍下js中的json对象, 1.JSON(JavaScript Ob ...

  5. JavaScript -- 时光流逝(五):js中的 Date 对象的方法

    JavaScript -- 知识点回顾篇(五):js中的 Date 对象的方法 Date 对象: 用于处理日期和时间. 1. Date对象的方法 <script type="text/ ...

  6. JavaScript -- 时光流逝(四):js中的 Math 对象的属性和方法

    JavaScript -- 知识点回顾篇(四):js中的 Math 对象的属性和方法 1. Math 对象的属性 (1) E :返回算术常量 e,即自然对数的底数(约等于2.718). (2) LN2 ...

  7. JavaScript -- 时光流逝(三):js中的 String 对象的方法

    JavaScript -- 知识点回顾篇(三):js中的 String 对象的方法 (1) anchor(): 创建 HTML 锚. <script type="text/javasc ...

  8. js中 给json对象添加属性和json数组添加元素

    js中 给json对象添加新的属性 比如现在有一个json对象为jsonObj,需要给这个对象添加新的属性newParam,同时给newParam赋值为pre.做法如下: var obj={ &quo ...

  9. js中关于Blob对象的介绍与使用

    js中关于Blob对象的介绍与使用   blob对象介绍 一个 Blob对象表示一个不可变的, 原始数据的类似文件对象.Blob表示的数据不一定是一个JavaScript原生格式 blob对象本质上是 ...

随机推荐

  1. odoo domain详解

    参考的以下文档: luohuayong:Odoo domain写法及运用 baimo:odoo domain表达式 1.domain 表达式规则 最简单的格式:[('字段名','操作符',值)] 例: ...

  2. 腾讯云:iptables基础

    iptables 基础 iptables 基本命令 任务时间:5min ~ 10min iptables 可以简单理解为 Linux 系统内核级防火墙 netfilter 的用户态客户端. Linux ...

  3. BNUOJ 33895 D-City

    D-City Time Limit: 1000ms Memory Limit: 65535KB This problem will be judged on HDU. Original ID: 449 ...

  4. 54. spring boot日志升级篇—logback【从零开始学Spring Boot】

    在<44. Spring Boot日志记录SLF4J>章节中有关相关的介绍,这里我们在深入的了解下logback框架. 为什么要使用logback ? --在开发中不建议使用System. ...

  5. (12)GrabCut前景提取

    import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('opencv-python-foregr ...

  6. PatentTips – Shader Interfaces

    BACKGROUND Today's graphic processing units (GPUs) host all of the computations necessary to generat ...

  7. 武大OJ 613. Count in Sama’s triangle

    Description Today, the math teacher taught Alice Hui Yang’s triangle. However, the teacher came up w ...

  8. 1. FrogRiverOne 一苇渡江 Find the earliest time when a frog can jump to the other side of a river.

    package com.code; public class Test04_3 { public static int solution(int X, int[] A) { int size = A. ...

  9. gem5: 使用ruby memory system中的mesh结构 出现AssertionError错误

    问题:在使用ruby memory system中的mesh结构測试时,出现例如以下错误: Traceback (most recent call last): File "<stri ...

  10. Android:Unable to resolve target ‘android-8’问题解决

    在学习过程中,下载别人写过的代码,导入到eclipse,报错: Unable to resolve target 'android-8' 问题是项目版本号问题. 解决方法例如以下: 右击项目:Prop ...