1、 使用object创建

var person = new Object();
person.name = "Tom";
person.age = "29";
person.job = "software engineer";
person.sayName = function(){
console.log(this.name);
} console.log(typeof person); // object
console.log(person instanceof Object); //true

2、 字面量对象

var person = {
name: "Tom",
age:29,
job:"software engineer",
sayName:function(){
console.log(this.name);
}
}
console.log(typeof person); // object
console.log(person instanceof Object); //true

使用字面量创建对象比使用object创建直观一些。这两种创建对象的方式都有明显的缺点:使用同一个接口创建很对对象,会产生大量的重复代码

3、 工厂模式

function createPerson(name,age,job){
var o = new Object();
o.name = name;
o.job = job;
o.age = age;
o.sayName = function(){
console.log(this.name);
}
return o;
} var p1 = createPerson("Tom",29,"software engineer");
var p2 = createPerson("Jerry",32,"doctor"); console.log(typeof p1); // object
console.log(p1 instanceof createPerson); // false

工厂模式,可以使用同一种接口创建多个对象,且很简洁。但也有一个问题:无法确定该对象实例属于哪种对象类型(instanceof 无效)。

4、构造函数模式

function Person(name,age,job){
this.name = name;
this.job = job;
this.age = age;
this.sayName = function(){
console.log(this.name);
}
} var p1 = new Person("Tom",29,"software engineer");
var p2 = new Person("Jerry",32,"doctor"); console.log(typeof p1); // object
console.log(p1 instanceof Person); // true
console.log(p1 instanceof Object); // true
console.log(p1.constructor == Person); // true p1.sayName(); //Tom //构造函数当作普通函数来使用
Person("jack",30,"driver");
window.sayName(); // jack // 在另一个对象的作用域中使用
var o = new Object();
Person.call(o,"Kristen",25,"Nurse");
o.sayName() // Kristen

Person() 函数没有显示地创建对象,直接将属性和方法赋给了this对象,没有 return 语句。

使用 new 操作符创建新的对象实例,调用构造函数实际上会经过以下步骤:创建一个新对象,将构造函数的作用域赋给新对象(this指向这个新对象),执行构造函数中的代码(为新对象添加属性),返回新对象。

构造函数也是函数,也可以正常调用。

构造函数的缺点是:每个的方法都要在每个对象实例上重新创建一遍,上面创建的p1 、p2都有一个sayName()的方法,但这两个方法不是同一个Function的实例,因为每定义一个函数就是实例化了一个对象

function Person(name,age,job){
this.name = name;
this.job = job;
this.age = age;
this.sayName = new Function("console.log(this.name);"); //逻辑上与声明函数是等价的,并且每创建一个对象就要执行一次
} var p1 = new Person("Tom",29,"software engineer");
var p2 = new Person("Jerry",32,"doctor"); console.log(p1.sayName == p2.sayName); // false

当然为了构造函数创建对象时,每个函数都是同一个Function实例,也可以使用全局函数:

function Person(name,age,job){
this.name = name;
this.job = job;
this.age = age;
this.sayName = sayName; // 使用全局函数
} function sayName(){
console.log(this.name);
} var p1 = new Person("Tom",29,"software engineer");
var p2 = new Person("Jerry",32,"doctor"); console.log(p1.sayName == p2.sayName); // true

但是这样,如果有很多函数,就要定义很多全局函数,没有封装性

5、原型模式

每个函数都有一个 prototype 属性,一个指向某个对象(原型对象)的指针,原型对象中包含着所有实例共享的属性和方法。那么就可以使用原型来新建对象

function Person(){
}
Person.prototype.name = "Tom";
Person.prototype.job = "software engineer";
Person.prototype.friends = ["Shelby","Court"];
Person.prototype.age = 29;
Person.prototype.sayName = function (){
console.log(this.name);
}; var p1 = new Person();
var p2 = new Person(); p1.friends.push("Van"); p1.sayName(); // Tom
p2.sayName(); // Tom console.log(p1.friends); // "Shelby,Court,Van"
console.log(p2.friends); // "Shelby,Court,Van"
console.log(p1.friends == p2.friends); // true
console.log(p1.sayName == p2.sayName); // true

很明显,单独使用原型新建对象时,不能传递参数,并且会因为所有对象的数据都一样而不能添加某个对象自己的特性

 6、构造函数和原型模式的组合模式

function Person(name,age,job){
this.name = name;
this.job = job;
this.age = age;
this.friends = ["Shelby","Court"];
}
Person.prototype.sayName = function (){
console.log(this.name);
}; var p1 = new Person("Tom",29,"software engineer");
var p2 = new Person("Jerry",32,"doctor"); p1.friends.push("Van"); p1.sayName(); // Tom
p2.sayName(); // Jerry console.log(p1.friends); // "Shelby,Court,Van"
console.log(p2.friends); // "Shelby,Court"
console.log(p1.friends == p2.friends); // false
console.log(p1.sayName == p2.sayName); // true

这是一种常用模式

也可以对其进行一些修改:

function Person(name,age,job){
this.name = name;
this.job = job;
this.age = age;
this.friends = ["Shelby","Court"]; if(this.sayName != "function"){
Person.prototype.sayName = function (){
console.log(this.name);
};
}
}

现在自身属性和原型的初始化,都封装在构造函数中,看起来更像面向对象。这样的写法下,不能使用对象字面量重写原型,因为对象字面重写原型不会让现有实例和新原型联系起来,与现有实例联系的还是旧原型。

js 创建对象的几种方法的更多相关文章

  1. js创建对象的三种方法:文本标识法和构造器函数法和返回对象的函数

    文本标识法和定义变量差不多,像这样 var obj = {name:'HanMM','2':'Dali'}; 函数构造器法  先创建一个对象函数 function Obj() { this.addre ...

  2. js创建对象的三种方法

    1.使用对象初始化器:{} var person = {....} 2 var person=new object() function person(参数) { this.参数=... } var ...

  3. java中需要关注的3大方面内容/Java中创建对象的几种方法:

    1)垃圾回收 2)内存管理 3)性能优化 Java中创建对象的几种方法: 1)使用new关键字,创建相应的对象 2)通过Class下面的new Instance创建相应的对象 3)使用I/O流读取相应 ...

  4. 创建对象的两种方法: new 和 面向对象(对象字面量)及对象属性访问方法

    创建对象的两种方法: new 和 面向对象(对象字面量)用 new 时:var o = new Object();o.name = "lin3615";alert(o.name); ...

  5. js去除空格12种方法

    注:本文非本人原著:原文作者: 黄卉  <js去除空格12种方法> //JS去除空格的方法目前共有12种: //实现1 String.prototype.trim = function() ...

  6. Javascript 创建对象的三种方法及比较【转载+整理】

    https://developer.mozilla.org/zh-CN/docs/JavaScript/Guide/Inheritance_and_the_prototype_chain 本文内容 引 ...

  7. 判断数组的方法/判断JS数据类型的四种方法

    参考文: 以下 3 个判断数组的方法,请分别介绍它们之间的区别和优劣Object.prototype.toString.call() . instanceof 以及 Array.isArray() h ...

  8. 判断JS数据类型的四种方法

    在 ECMAScript 规范中,共定义了 7 种数据类型,分为 基本类型 和 引用类型 两大类,如下所示: 基本类型:String.Number.Boolean.Symbol.Undefined.N ...

  9. 判断JS数据类型的几种方法

    原文转自http://www.cnblogs.com/onepixel/p/5126046.html! 说到数据类型,我们先说一下JavaScript 中常见的几种数据类型: 基本类型:string, ...

随机推荐

  1. EXCEL workbook.saveas 函数详解

    本问所有资料来自于 Excel2003 VBA帮助文件,张荣整理,适用于DELPHI,VB的高级语言操作Excel用 ExcelApplication.WorkBook.SaveAs(filename ...

  2. 关于Access导入Oracle会产生双引号的问题

    把Access2007的数据导入到oracle 10g xe中,成功了,可是在写sql语句时必须加双引号 ,如select “name” from “Product”,貌似是因为access为了防止列 ...

  3. wmware虚拟机的克隆

    VMware 支持两种类型的克隆:完整克隆 链接克隆 完整克隆是和原始虚拟机完全独立的一个拷贝,它不和原始虚拟机共享任何资源.可以脱离原始虚拟机独立使用. 链接克隆需要和原始虚拟机共享同一虚拟磁盘文件 ...

  4. JS 对象(对象遍历,拷贝)

     定义属性 直接 obj.对象 的方法 Object.defineProperty(obj, prop, descriptor) ,这种方法可以设置 或者修改对象属性的访问权限 数据描述符和存取描述符 ...

  5. MD5类(MD5Helper)

    项目中经常需要使用到MD5来进行加密 代码: namespace MyProject.Common { public class MD5Helper { /// <summary> /// ...

  6. 机器学习进阶-图像梯度运算-Sobel算子 1. cv2.Sobel(使用Sobel算子进行计算) 2. cv2.convertScalerAbs(将像素点进行绝对值的计算)

    1.cv2.Sobel(src, ddepth, dx, dy, ksize)  进行sobel算子计算 参数说明:src表示当前图片,ddepth表示图片深度,这里使用cv2.CV_64F使得结果可 ...

  7. ABAP-多线程处理

    *&---------------------------------------------------------------------* *& Report ZRICO_TES ...

  8. 配置tomcat的开发环境

    第一步:鼠标右键计算机->属性->高级系统设置,进去之后,点击环境变量,如下图所示: 第二步:开始配置tomcat的环境变量,新建系统变量名CATALINA_BASE,值tomcat的安装 ...

  9. 池以及barrier简单

    用了下CyclicBarrier,注意线程池中的线程数量设置,还有就是DB连接的时候,需要考虑单个DB能承受的最大连接数目和每个连接上能同时打开的cursor等限制,需要时可以通过jstack查看堆栈 ...

  10. 使用hibernate与mysql时数据不能插入的原因及解决办法

    1.背景 之前从没用过hibernate,因此在网上搜了一下hibernate快速入门方面的信息,最后我按照<Myeclipse Hibernate 快速入门 中文版>(CSDN,百度文库 ...