一、序

面向对象有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。ECMA-262把对象定义为“无序属性的集合,其属性可以包含基本值、对象或者函数”。

使用Object来创建对象,如下代码所示:

        var animal = new Object();
animal.name = "小猫";
animal.color = "黑色";
animal.print = function () {
console.log(this.name + "的颜色是:" + this.color);
}

使用对象字面量来创建对象,如下代码所示:

 var animal = {
name: "小猫",
color: "黑色",
print: function () {
console.log(this.name + "的颜色是:" + this.color);
}
};

通过上面两种方式,虽然我创建了对象,但是并没用满足对象的封装特性,我并不能复用这短代码,只能粘贴复制来创建新的对象,这并不是我想要的结果,前辈们就从面向对象的设计模式

的思想中提炼出一些新的方法。我们要站在巨人的肩膀上才能看得更远。

二、工厂模式

这种模式抽象了创建具体对象的过程。ECMAScript无法创建类,所以采用函数来封装以特定接口创建对象的细节。如下面代码所示:

        ///提供构造一个动物对象方法
function createAnimal(name, color) {
var obj = new Object();
obj.name = name;
obj.color = color;
obj.print = function () {
console.log(name + "的颜色是:" + color);
}
return obj; //返回对象
}
//实例化一个对象
var animal1 = createAnimal("小猫", "黑色");
animal1.print();

这种模式,虽然做到了代码可以复用的效果,但是却没有解决对象识别的问题,如果我们能够像申明Object,Array这样的原生构造函数就好了,所以就有了构造函数的衍生;

三、构造函数

熟悉C#、Java等语言的朋友,就知道一般来说我们都有无参构造函数、有参构造函数。像Array,就属于一种无参构造函数。先来看下面一段代码

        function Animal(name, color) {
this.name = name;
this.color = color;
this.print = function () {
console.log(this.name + "的颜色是:" + this.color);
}
} var animal1 = new Animal("小猫", "黑色");
animal1.print();

我们这采用了有参构造函数,和工厂模式比较起来,构造函数并没有显式的创建对象,直接将属性和方法赋给了this对象,没有return语句。通过instanceof方法我们可以得出构造函数

可以将它的实例化标识为一种特定的类型;

        console.log(animal1 instanceof Object);//true
console.log(animal1 instanceof Animal);//true

使用构造函数的主要问题,就是每个方法都要在每一个实例上重新创建一遍。ECMAScript中函数是对象,也就是说每定义一个函数,也就是实例化了一个对象,所以上面对象中print函数就实例化了2次。

这样做是没有必要的,所以我们可以通过把函数定义转移到构造函数外部来解决这个问题。

        function Animal(name, color) {
this.name = name;
this.color = color;
this.print = print
} function print() {
console.log(this.name + "的颜色是:" + this.color);
}

但是这样做新问题又来了,在全局作用域中定义的函数实际上只能被某个对象调用,这让全局作用域有点名不副实了。于是让我们这个自定义的引用类型就丝毫没有封装性可言了。接下来就有了原形模式来

解决这个问题了。

四、原型模式

我们创建每个函数都有一个prototype(原型)属性,这个属性是个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。如下面的代码所示:

        function Animal() {

        }

        Animal.prototype.name = "小猫";
Animal.prototype.color = "黑色";
Animal.prototype.print = function () {
console.log(this.name + "的颜色是:" + this.color);
} var animal = new Animal();
animal.print();

如果我们要改变这个对象中的属性的话,就直接对其属性重新赋值:

        var animal = new Animal();
animal.name = "小花猫";
animal.print();

但是一般来说,我们都喜欢在创建对象的时候就对其赋值,所以我就结合有参构造函数来重新改造下上面的代码

        function Animal(name, color) {
this.name = name;
this.color = color;
}
Animal.prototype.print = function () {
console.log(this.name + "的颜色是:" + this.color);
} var animal = new Animal("小黑猫", "黑色");
animal.print();

但是这样做,如果参数过于多就会显得很长,有时候传参的时候就会容易出错,根据我几年的C#代码经验,针对过于长的参数,我一般喜欢把参数分装成一个对象,作为参数,

如下代码所示:

        function Animal(setting) {
this.name = setting.name;
this.color = setting.color;
}
Animal.prototype.print = function () {
console.log(this.name + "的颜色是:" + this.color);
} var setting = {
name: "小猫",
color:"黑色"
}; var animal = new Animal(setting);
animal.print();

这样做封装就看起来简洁了许多,个人所爱吧。

五、结语

本来是计划早睡早起身体好的,现在又00:30了,又得晚睡早起了,今天就先温故知新到这,加油吧,老男孩!晚安!

重新认识JavaScript里的创建对象(一)的更多相关文章

  1. JavaScript里的创建对象(一)

    一.序 面向对象有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.ECMA-262把对象定义为“无序属性的集合,其属性可以包含基本值.对象或者函数”. 使用Obje ...

  2. 重新认识JavaScript里的创建对象

    一.序 面向对象有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.ECMA-262把对象定义为“无序属性的集合,其属性可以包含基本值.对象或者函数”. 使用Obje ...

  3. javascript里for循环的一些事情

    今天在给一个学妹调她的代码BUG时,她的问题就是在一个for循环里不清楚流程的具体流向,所以导致了页面怎么调都是有问题,嗯确实你如果不清楚语句流向很轻易就会出问题,所以说for循环不会用或者说用的不恰 ...

  4. Javascript里,想把一个整数转换成字符串,字符串长度为2

    Javascript里,想把一个整数转换成字符串,字符串长度为2.  想把一个整数转换成字符串,字符串长度为2,怎么弄?比如 1 => "01"11 => " ...

  5. JavaScript里的依赖注入

    JavaScript里的依赖注入 我喜欢引用这句话,“程序是对复杂性的管理”.计算机世界是一个巨大的抽象建筑群.我们简单的包装一些东西然后发布新工具,周而复始.现在思考下,你所使用的语言包括的一些内建 ...

  6. 如何才能通俗易懂的解释javascript里面的"闭包"?

    看了知乎上的话题 如何才能通俗易懂的解释javascript里面的‘闭包’?,受到一些启发,因此结合实例将回答中几个精要的答案做一个简单的分析以便加深理解. 1. "闭包就是跨作用域访问变量 ...

  7. javascript里的循环语句

    前序:我一直对于for跟for..in存在一种误解,我觉得for都能把事情都做了,为啥还要for...in...这玩意了,有啥用,所以今天就说说JavaScript里的循环语句. 循环 要计算1+2+ ...

  8. Safari 里的javascript 里不能用submit作为函数名

    Safari 里的javascript 里不能用submit作为函数名, 这样写的时候,怎么也运行不了JeasyUI的onSubmit的function, 改个名就可以了.而在chrome下面就没问题 ...

  9. JavaScript 里,$ 代表什么?/JQuery是什么语言?/html中用link标签引入css时的中 rel="stylesheet"属性?/EL表达式是什么?

    JavaScript 里,$ 代表什么? 比如说我写一个mouseover事件: $(document).ready(function(){ $("p").mouseover(fu ...

随机推荐

  1. 解决项目中找不到Maven Dependencies

    项目中找不到Maven Dependencies 正常的Maven项目应该是这样的 自己的项目中却没有Maven Dependencies,自己百度了, 发现解决不了,最后发现在.classpath和 ...

  2. Linux tomcat设置ip地址直接访问,tomcat设置ip地址直接访问,tomcat绑定ip地址

    Linux tomcat设置ip地址直接访问,tomcat设置ip地址直接访问,tomcat绑定ip地址 >>>>>>>>>>>> ...

  3. C#语言基础——语句

    1·语句是指程序命令,都是按照顺序执行的.语句在程序中的执行顺序称为"控制流"或"执行流".根据程序对运行时所收到的输入的响应,在程序每次执行时控制流可能有所不 ...

  4. 多线程爬坑之路--并发,并行,synchonrized同步的用法

    一.多线程的并发与并行: 并发:多个线程同时都处在运行中的状态.线程之间相互干扰,存在竞争,(CPU,缓冲区),每个线程轮流使用CPU,当一个线程占有CPU时,其他线程处于挂起状态,各线程断续推进. ...

  5. 学习HTML5一周的收获1

    HTML5的基本结构 学习了title标签(显示网站名称),link标签(链接文件,可做网页美化) 快捷键:Ctrl+/ 注释 学习[meta标签] 1.charset属性:单独使用,设置文档字符集编 ...

  6. CCF2014093字符串匹配(C语言版)

    问题描述 给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行.你的程序还需支持大小写敏感选项:当选项打开时,表示同一个字母的大写和小写看作不同的字符:当选项关闭时,表示同一个字母的大写和小写 ...

  7. Java Stream API进阶篇

    本文github地址 上一节介绍了部分Stream常见接口方法,理解起来并不困难,但Stream的用法不止于此,本节我们将仍然以Stream为例,介绍流的规约操作. 规约操作(reduction op ...

  8. http的几种请求的方式(Get、Post、Put、Head、Delete、Options、Trace和Connect)

    http的这几种请求方式各有各的特点,适用于各自的环境.下面我就说说这些方式的各自特点: 1.Get:它的原理就是通过发送一个请求来取得服务器上的某一资源.获取到的资源是通过一组HTTP头和呈现数据来 ...

  9. Winform自定义控件在界面上拖动、滚动鼠标。。会闪烁的解决方法

    环境说明:   项目中有一个基类窗体BaseForm,有一个自定义控件TextBoxBase,两个控件都做了一些独特常规的封装和重写,在TextBoxBase中有一点重绘的下划线,发现在窗体运行之后, ...

  10. JavaScript 再认识(一):Function调用模式对this的影响

    近来,学习了一下<JavaScript精粹>,读到了函数这章,理清了JavaScript中this在不同调用模式下的指向. 1.Function调用模式:Function是JavaScri ...