JavaScript常见的创建对象的几种方式
1、通过Object构造函数或对象字面量创建单个对象
这些方式有明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码。为了解决这个问题,出现了工厂模式。
2、工厂模式
考虑在ES中无法创建类(ES6前),开发人员发明了一种函数,用函数来封装以特定接口创建对象的细节。(实现起来是在一个函数内创建好对象,然后把对象返回)。

function createPerson(name,age,job){
var o=new Object();
o.name=name;
o.age=age;
o.job=job;
o.sayName=function(){
alert(this.name);
};
return 0;
} var person1=createPerson("Nicholas",29,"Software Engineer");
var person2=createPerson("Greg",27,"Doctor");

函数createPerson()能够根据接受的参数来构建一个包含所有必要信息的Person对象。工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题,即怎么知道一个对象的类型。随着JS发展,又一个模式出现了。
3、构造函数模式
像Object和Array这样的原生构造函数,在运行时会自动出现在执行环境。此外,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。

function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
alert(this.name);
};
} var person1=new Person(...);
var person2=new Person(...);

与工厂模式相比,具有以下特点:
- 没有显式创建对象;
- 直接将属性和方法赋给了this对象;
- 没有return语句;
- 要创建新实例,必须使用new操作符;(否则属性和方法将会被添加到window对象)
- 可以使用instanceof操作符检测对象类型
构造函数的问题:
构造函数内部的方法会被重复创建,不同实例内的同名函数是不相等的。可通过将方法移到构造函数外部解决这一问题,但面临新问题:封装性不好。
这些问题可通过原型模式解决。
4、原型模式
我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。(prototype就是通过调用构造函数而创建的那个对象实例的原型对象)。
使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。换句话说,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。

function Person(){
} Person.prototype.name="Nicholas";
Person.prototype.age=29;
Person.prototype.job="...";
Person.prototype.sayName=function(){
...
}; var person1=new Person();
person1.sayName();//"Nicholas"

更常见的做法是用一个包含所有属性和方法的对象字面量来重写整个原型对象,并重设constructor属性。

function Person(){
} Person.prototype={
name:"...",
age:29,
job:"...",
sayName:function(){
...
}
}; Object.defineProperty(Person.prototype,"constructor",{
enumerable:false,
value:Person,
});

原型对象的问题:
- 他省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值,虽然这会在一定程度带来一定的不便,但不是最大的问题,最大的问题是由其共享的本性所决定的。
- 对于包含基本值的属性可以通过在实例上添加一个同名属性隐藏原型中的属性。然后,对于包含引用数据类型的值来说,会导致问题。
这些问题导致很少单独使用原型模式。
5、组合使用构造函数模式和原型模式
这是创建自定义类型的最常见的方式。
构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。所以每个实例都会有自己的一份实例属性的副本,但同时共享着对方法的引用,最大限度的节省了内存。同时支持向构造函数传递参数。

function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends=["S","C"];
} Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name);
}
}; var person1=new Person(...);

6、动态原型模式

function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job; if(typeof this.sayName!="function"){
Person.prototype.sayName=function(){
alert(this.name);
};
}
}

这里只有sayName()不存在的情况下,才会将它添加到原型中,这段代码只会在初次调用构造函数时才执行。这里对原型所做的修改,能够立刻在所有实例中得到反映。
7、Object.create()
ES5定义了一个名为Object.create()的方法,它创建一个新对象,其中第一个参数是这个对象的原型,第二个参数对对象的属性进行进一步描述。
8、另有寄生构造函数模式和稳妥构造函数模式
JavaScript常见的创建对象的几种方式的更多相关文章
- JavaScript高级特性-创建对象的九种方式
1. 对象字面量 通过这种方式创建对象极为简单,将属性名用引号括起来,再将属性名和属性值之间以冒号分隔,各属性名值对之后用逗号隔开,最后一个属性不用逗号隔开,所有的属性名值对用大括号括起来,像这样: ...
- js-JavaScript常见的创建对象的几种方式
1.通过Object构造函数或对象字面量创建单个对象 这些方式有明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码.为了解决这个问题,出现了工厂模式. 2.工厂模式 考虑在ES中无法创建类( ...
- JavaScript 创建对象的七种方式
转自:xxxgitone.github.io/2017/06/10/JavaScript创建对象的七种方式/ JavaScript创建对象的方式有很多,通过Object构造函数或对象字面量的方式也可以 ...
- JavaScript创建对象的几种 方式
//JavaScript创建对象的七种方式 //https://xxxgitone.github.io/2017/06/10/JavaScript%E5%88%9B%E5%BB%BA%E5%AF%B9 ...
- JavaScript中创建对象的三种方式!
JavaScript中创建对象的三种方式! 第一种 利用对象字面量! // 创建对象的三种方式! // 1 对象字面量. var obj = { // 对象的属性和方法! name: 'lvhang' ...
- Java中创建对象的几种方式
Java中创建对象的五种方式: 作为java开发者,我们每天创建很多对象,但是我们通常使用依赖注入的方式管理系统,比如:Spring去创建对象,然而这里有很多创建对象的方法:使用New关键字.使用Cl ...
- OOP 创建对象的7种方式
JavaScript OOP 创建对象的7种方式 我写JS代码,可以说一直都是面向过程的写法,除了一些用来封装数据的对象或者jQuery插件,可以说对原生对象了解的是少之又少.所以我拿着<J ...
- Java创建对象的几种方式
解析:Java创建对象的几种方式(重要):(1) 用new语句创建对象,这是最常见的创建对象的方法.(2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Co ...
- &和&&的共同点和区别、Java字符含义和Java创建对象的几种方式
一.&和&&的共同点和区别 1.&和&&的联系(共同点): &和&&都可以用作逻辑与运算符,但是要看使用时的具体条件来决定. 操 ...
随机推荐
- 23 模块 os sys pickle json
一. os模块 主要是针对操作系统的 用于文件操作 二. sys 模块 模块的查找路径 sys.path 三 pickle 模块 1. pickle.dumps(对象) 序列化 ...
- python从文本中提取某酒店机顶盒号和智能卡号
1.某项目中经常遇到需要关闭一些机顶盒消费权限.但是给过来的不是纯字符串,需要自己提取. 有400多个机顶盒和智能卡.nodepad++的列块模式也可以提取,但是还是稍微麻烦,因为列不对等 先复制到文 ...
- ML(附录3)——过拟合与欠拟合
过拟合与欠拟合 我们希望机器学习得到好的模型,该模型能够从训练样本中找到一个能够适应潜在样本的普遍规律.然而,如果机器学习学的“太好”了,以至把样本的自身特点当作潜在样本的一般特性,这就使得模型的泛化 ...
- [转]JDK动态代理
代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间 ...
- C#:匿名类型
匿名类型和var关键字是Visual C# 3.0提供的一个新特性,var是隐式类型而并不是类型javascript中的var. var user = new { Id = 1, Name = &qu ...
- 集群RedHat6.5+JDK1.8+Hadoop2.7.3+Spark2.1.1+zookeeper3.4.6+kafka2.11+flume1.6环境搭建步骤
1.RHEL 6.5系统安装配置图解教程(rhel-server-6.5) 2.在Linux下安装JDK图文解析 3.RedHat6.5上安装Hadoop集群 4.RedHat6.5安装Spark集群 ...
- Java从命令行接受多个数字并求和
一,设计思路 1,定义一个int型变量作为数字之和 2,运用for循环将字符转换成int型加到和中 3,输出和的值 二,程序流程图 三,源程序代码 //信1605-3 程浩public class J ...
- C#编程的最佳工具
C#是企业中广泛使用的编程语言,特别是那些依赖微软的程序语言.如果您使用C#构建应用程序,则最有可能使用Visual Studio,并且已经寻找了一些扩展来对您的开发进行管理.但是,这个工具列表可能会 ...
- Ubuntu 安装以及web服务器配置
1.安装实在没必要说,连系统都装不了,干脆下岗算了 2.Apache2 安装 //安装 sudo apt-get install apache2 Apache安装完成后,默认的网站根目录是" ...
- 【转】C# XML序列化去掉XML默认的命名空间及声明头
http://blog.csdn.net/aoshilang2249/article/details/44860155 重点: XmlSerializerNamespaces namespaces = ...