能使用{}创建对象就不要使用new Object,能使用[]创建数组就不要使用new Array,JS中字面量的访问速度要高于对象。

1、通过object构造函数创建单个对象

var o = new Object();
o.name = 'camille';
o.age = 24;
o.getName = function() {
  return '我的名字是:'+ this.name;
};
o.getAge = function() {
  return '我的年龄是:' + this.age;
};

2、通过对象字面量创建单个对象,JSON(常用)

var personObj = {
  name: 'camille',
  age: 25,
  getName: function(){
    return '我的名字是:'+ this.name;
  },
  getAge: function(){
    return '我的年龄是:' + this.age;
  }
}
personObj.getAge();

使用同一个接口创建很多对象,会产生大量的重复代码。

3、稳妥构造函数模式
所谓稳妥对象,指的是没有公共属性,而且其方法也不引用this的对象。

function Person(name, age) {
  var o = new Object();
  o.getName = function() {
    return '我的名字是:'+ name;
  };
  o.getAge = function() {
    return '我的年龄是:' + age;
  };
  return o;
}
var nobj = Person('camille',25);
console.log(nobj.getAge());

与寄生构造函数模式类似,使用稳妥构造函数模式创建的对象与构造函数之间没有什么关系,因此instanceof操作符对这种对象也没有意义。

4、工厂模式:带参数的函数,返回对象,流水线工作。在函数内定义对象,并定义对象的各种属性,虽然属性可以是方法,但是建议在函数外定义属性为方法的属性,这样可以避免重复创建该方法。解决了创建多个相似对象的问题,但却没有解决对象识别的问题。

function Person(name, age) {
  var o= new Object();
  o.name = name;
  o.age = age;
  o.getName = function() {
    return '我的名字是:'+ this.name;
  };
  o.getAge = function() {
    return '我的年龄是:' + this.age;
  };
  return o;
}
var nobj = Person('camille',25);
console.log(nobj.getAge());

5、寄生构造函数模式
创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后在返回创建对象。

function Person(name, age) {
  var o = new Object();
  o.name = name;
  o.age = age;
  o.getName = function() {
    return '我的名字是:'+ this.name;
  };
  o.getAge = function() {
    return '我的年龄是:' + this.age;
  };
  return o;
}
var nobj = new Person('camille',25);
console.log(nobj.getAge());

返回的对象与构造函数或者与构造函数的原型之间没有关系,也就是说,构造函数返回的对象与在构造函数外部创建的对象没什么不同。为此,不能依赖instanceof操作符来确定对象的类型。由于存在这一问题,我们建议在可以使用其他模式的情况下不要使用这种模式。

6、构造函数模式:没有显式的创建对象,直接将属性和方法赋给了this对象,没有return语句;创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型。每个方法都要在每个实例上重新创建一遍。

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.getName = function() {
    return '我的名字是:'+ this.name;
  };
  this.getAge = function() {
    return '我的年龄是:' + this.age;
  };
}
var nobj = new Person('camille',25);
console.log(nobj.getAge());

注意!如果不加new关键字,Person就不是构造函数,会意外地给它的外部作用域即window添加属性,为了安全,这里的new是必须的。

7、原型模式:属性没有在函数内定义,而是利用prototype属性对属性进行定义。所有的属性,方法都是共享的,不能让对象具体化。实例中的指针仅指向原型,而不指向构造函数。

//写法1
function Person() {
}
Person.prototype.name = 'camille';
Person.prototype.age = 26;
Person.prototype.getName = function() {
  return '我的名字是:'+ this.name;
};
Person.prototype.getAge = function() {
  return '我的年龄是:' + this.age;
};
var nobj = new Person();
console.log(nobj.getAge());
//写法2
function Person() {
}
Person.prototype = {
  constructor: Person,//必须手动设置这个属性,不然就断了与构造函数的联系了。没有实例共享原型的意义了。
  name: 'camille',
  age: 26,
  getName: function() {
    return '我的名字是:'+ this.name;
  },
  getAge: function() {
    return '我的年龄是:' + this.age;
  }
};
var nobj = new Person();
console.log(nobj.getAge());

8、构造-原型组合模式(推荐)

构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性。

//写法1
function Person(name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.getName = function() {
  return '我的名字是:'+ this.name;
};
Person.prototype.getAge = function() {
  return '我的年龄是:' + this.age;
};
var nobj = new Person('camille',25);
console.log(nobj.getAge());
//写法2
function Person(name, age) {
  this.name = name;
  this.age = age;
}
/**
 * 为了让属性和方法更好的体现封装的效果,减少不必要的输入,原型的创建可以使用字面量方式
 */
Person.prototype = {
  constructor: Person,//必须手动设置这个属性,不然就断了与构造函数的联系了。没有实例共享原型的意义了。
  getName: function() {
    return '我的名字是:'+ this.name;
  },
  getAge: function() {
    return '我的年龄是:' + this.age;
  }
};
var nobj = new Person('camille',25);
console.log(nobj.getAge());
//写法3
function Person(name, age) {
  this.name = name;
  this.age = age;
}
(function() {
  this.getName = function() {
    return '我的名字是:'+ this.name;
  };
  this.getAge = function() {
    return '我的年龄是:' + this.age;
  };
}).call(Person.prototype);
var nobj = new Person('camille',25);
console.log(nobj.getAge());

9、动态原型模式:可以理解为构造-原型组合模式的一个特例,在函数内定义属性为方法的属性,if语句保证创建该对象的实例时,属性的方法不会被重复创建。(推荐)

function Person(name, age) {
  this.name = name;
  this.age = age;

  if (typeof this.getName != "function") {
    //使用动态原型模式时,不能使用对象字面量重写原型。如果在已经创建了实例的情况下重写原型,就会切断现有实例与新原型之间的联系
    Person.prototype.getName = function () {
      alert(this.name);
    }
  }
}

通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型。

Javascript实现对象的创建的更多相关文章

  1. JavaScript面向对象—对象的创建和操作

    JavaScript面向对象-对象的创建和操作 前言 虽然说在JavaScript编程语言中,函数是第一公民,但是JavaScript不仅支持函数式编程,也支持面向对象编程.JavaScript对象设 ...

  2. JavaScript(对象的创建模式)

    JavaScript和其他语言略有不同,在JavaScript中,引用数据类型都是对象(包括函数).不过,在JavaScript中并没有“类”的概念,这决定了在JavaScript中不能直接来定义“类 ...

  3. Javascript之对象的创建

    面向对象语言有一个非常显著的标志,那就是它们都有类的概念,通过类之间的继承就可以达到任意创建具有相同属性方法的对象.而在ECMAScript中并没有类的概念,它把对象定义为:无序属性的集合,其属性包含 ...

  4. JavaScript原生对象及扩展

    来源于 https://segmentfault.com/a/1190000002634958 内置对象与原生对象 内置(Build-in)对象与原生(Naitve)对象的区别在于:前者总是在引擎初始 ...

  5. 《JavaScript高级程序设计》读书笔记--(4)对象的创建

    ECMAScript支持面向对象(OO)编程,但不使用类或者接口.对象可以在代码执行过程中创建或增强,因此具有动态性而非严格定义的实体.在没有类的情况下,可以采用下列模式创建对象. 对象的创建 工厂模 ...

  6. JavaScript对象的创建之使用json格式定义

    json: javascript simple object notation. json就是js的对象,但是它省去了xml中的标签,而是通过{}来完成对象的说明. 定义对象 var person = ...

  7. javascript中对象的不同创建方法

    javascript中的对象与一般的面向对象的程序设计语言(c++,Java等)不同,甚至很少有人说它是面向对象的程序设计语言,因为它没有类.javaScript只有对象,不是类的实例.javascr ...

  8. javascript对象的创建--相对java 怎样去创建了"类"i以及实例化对象

    由于javascript没有java那么多基本类型,同时也没有提供class这个东西,那么我们想实现javascript的对象创建应该怎么办呢,我简单地从w3c提供的课件中提取了一下几种方法: 一.工 ...

  9. Javascript我学之五对象的创建与使用

    本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘. 对象的创建 JavaScript对象有两种类型   1).Native:在ECMAScript标准中定义和描述,包括JavaScript内置 ...

随机推荐

  1. Your Database is downloaded and backed up on....(腾讯云的mysql被攻击)

    今天发现自己的服务器被黑客攻击,自己的mysql服务器的库被删掉,并且新创了一个warning库,只有一个readme表.不知道原因,也许是自己再github上的项目暴漏了自己的密码,还要0.6比特币 ...

  2. LOJ 2483: 洛谷 P4655: 「CEOI2017」Building Bridges

    题目传送门:LOJ #2483. 题意简述: 有 \(n\) 个数,每个数有高度 \(h_i\) 和价格 \(w_i\) 两个属性. 你可以花费 \(w_i\) 的代价移除第 \(i\) 个数(不能移 ...

  3. 【转】Python中的eval()、exec()及其相关函数

    [转]Python中的eval().exec()及其相关函数 刚好前些天有人提到eval()与exec()这两个函数,所以就翻了下Python的文档.这里就来简单说一下这两个函数以及与它们相关的几个函 ...

  4. java.sql.SQLException: ORA-28040: 没有匹配的验证协议(12c或者12c rac)

    1.plsql可以连接,java程序不能连接,报如下错误: 一直以来用的都是服务器上的Oracle数据库,今天改成连接本地Oracle 12c数据库是出问题了.hibernate连接Oracle12c ...

  5. python动态函数名的研究

    所谓动态函数名,就是使用时完全不知道是叫什么名字,可以由用户输入那种. 一般人习惯性会想到eval或exec, 但是众所周知,这样的写法不安全而且容易引起问题,而且不pythonic.而且使用时必须把 ...

  6. MySQL数据库——安装教程(5.7版本)

    一.配置MySQL数据库 1.解压绿色版mysql,并改名为mysql5.7,如下图 对比一下下图5.6以前的版本,少data目录(存放数据)和my-default.ini文件(配置信息) 二.安装服 ...

  7. VS2017编译boost库

    1.http://www.boost.org/     下载boost库. 2.解压到 D:\ProgramFiles\boost 3.环境配变量配置     VS2017更加注重跨平台性,安装文件较 ...

  8. 本地ssh key连接多个git账号

    在开发过程中,可能需要在本地同时连接到多个gitlab账户,但是一个用户的ssh key只能连接到一个git账户,这就需要创建多个ssh key,分别连接到不同的账户.具体步骤如下: 1.生成ssh ...

  9. linux unzip 中文乱码解决方法

    引自:https://blog.csdn.net/abyjun/article/details/48344379 unzip -O CP936 xxx.zip (用GBK, GB18030也可以)

  10. LeetCode(43):字符串相乘

    Medium! 题目描述: 给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式. 示例 1: 输入: num1 = &quo ...