js创建对象的几种方式(推荐)

本文深入解析JavaScript中创建对象的九种方法,包括对象字面量、构造函数、原型模式等,探讨每种方法的优缺点及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.通过对象字面量创建

var a = {};   //最简单最直接的方法,是第二种的简写方式

2.通过object构造函数创建

var a = new Object();  // 这行代码创建了Object引用类型的一个新实例,然后把实例保存在变量a中。
a.name = 'pingfan';
console.log(a);  // 此时打印出来的是{name: 'pingfan'}

3.通过Object.create(__proto__, propertiesObject)创建

var a = Object.create(null);  // 新创建出来的对象的原型指向null,也就是没有原型
console.log(a);  // {}

__proto__ 是必填参数,就是新创建出来的对象的原型。
propertiesObject是可选参数,作用就是给新对象添加新属性以及描述器。

4.通过工厂模式创建

实际上是把创建对象的方式放在了一个函数里面,然后通过这个函数返回出一个对象。代码如下:

function creatObject(name) {
    var a = new Object();
    a.name = name;
    a.sayName=function(){
        alert(this.name);
    };
    return a;
}
var b = creatObject('pingfan');  
console.log(b instanceof creatObject);  // false 判断a的类型
// 用一个变量去接收函数返回的对象,var b = {name: 'pingfan', sayName:function(){ alert(this.name);}}
b.sayName();  // 调用b对象的sayName方法。
我们可以把creatObject函数看作是一个工厂在制造商品,而return出来的就是商品(对象),而这个b就是买商品的人,当我们买了一件商品的时候我们就可以去使用这件商品了

优点:可以重复调用creatObject函数,解决了创建多个相似对象的问题。
缺点:虽然它能创建多个相似的对象,但是不能识别这个对象属于哪个类型。

5.使用构造函数创建对象(Constructor)

对比工厂模式,它是工厂模式的进化版,因为它少了创建对象的步骤(实际上创建了,隐藏了),也没有return语句,代码如下:

function CreatObject(name) {  // 首字母要大写,标明这是一个构造函数
    this.name = name;
    this.sayName = function() {
      console.log(this.name);
    };
  }
var a = new CreatObject('pingfan');   // 使用new实例化构造函数
console.log(a)   // CreatObject {name: "pingfan", sayName: ƒ} f代表的函数 CreatObject代表的是对象类型
console.log(a instanceof Object);  // true 解决了工厂模式不能判断类型的问题
console.log(a instanceof CreatObject); // true
console.log(a.constructor == CreatObject); //true

优点:
可以重复new实例化构造函数,解决了工厂模式不能判断类型的问题
可以将构造函数的实例标识为某种特定的类型
采用new操作符调用构造函数
函数中隐式地创建对象
将属性和方法复制给了this对象
没有return语句
缺点:
实例对象都可以继承构造器函数中的属性和方法。但是,同一个对象实例之间,无法共享属性
构造函数中的每个方法都要在实例上重新创建一遍,封装性不好,原因如下:

var b = new CreatObject('xiaoran');
console.log(a.name);  // pingfan
console.log(b.name);  // xiaoran
console.log(a.sayName === b.sayName );  //false !!!!注意这里

由上可见a.sayName !== b.sayName,也就意味着每一次实例都要创建一遍,怎么办呢,继续优化呗。

6.使用原型模式(propotype)

因为构造函数创建对象也有缺点怎么办呢?这时候原型就蹦了出来,解决了构造函数的缺点。每个数据类型都是对象(undefined和null除外),而每个对象都是继承自一个原型对象,只有null除外,它没有自己的原型对象,最终的Object的原型为null,涉及到原型链知识点。代码如下:

function CreatObject() {  // 首字母要大写,标明这是一个构造函数
}
CreatObject.prototype.name = 'pingfan';
CreatObject.prototype.sayName = function() {
    alert(this.name);
};
var a = new CreatObject();   // 使用new实例化构造函数
var b = new CreatObject();
console.log(a.name); // a   pingfan
console.log(b.name); // b   pingfan
console.log(b.propotype.constructor); // CreatObject()
console.log(a.sayName === b.sayName);  // true   a和b都可以公用sayName方法

propotype是构造函数CreatObject的属性,而consructor则是构造函数的prototype的属性它所指向的是CreatObject构造函数
重写CreatObject.prototype对象会造成propotype.constructor属性不会指向CreatObject构造函数,实例对象拥有一个[[prototype]]指针,指向的是最初的原型对象,如果重写了原型对象,就相当于切断了构造函数和最初原型对象之间的联系

function CreatObject() {  // 首字母要大写,标明这是一个构造函数
}
CreatObject.prototype = {
	name: 'pingfan',
	love: ['lol','98k'],
	sayName: function() {
    	alert(this.name);
	}
}
var a = new CreatObject();   // 使用new实例化构造函数
var b = new CreatObject();
a.love.push('you')
console.log(a.love); // a   lol,98k,you
console.log(b.love); // b   lol,98k,you
console.log(a.sayName === b.sayName);  // true   a和b都可以公用sayName方法
console.log(b.propotype.constructor); // undefined

优点:
方法不会重新创建。共享原型对象上的方法
缺点:
不能初始化参数。共享原型对象上的属性(比如属性的值是一个数组,当使用push方法添加元素的时候原数组被改变了)

7.组合模式

构造函数模式与原型模式的一起来,代码如下:

function CreatObject(name) {
   this.name = name;
}
CreatObject.prototype = {
    constructor: CreatObject,
    getName: function () {
          console.log(this.name);
    }
};
var a = new CreatObject('pingfan');
var b = new CreatObject('xiaoran');
console.log(a);  // CreatObject {name: "pingfan"}
a.getName();  // pingfan
b.getName();  // xiaoran
console.log(a.getName === b.getName);  // true

优点:
以上问题都解决,该公用的公用,私用的私用
缺点:
封装性不是很好,

8.寄生构造函数模式

写法跟工厂模式和构造函数模式很像,构造函数的头,工厂模式的身体,构造函数的实例,推荐特殊情况下使用

function Person(name) {
  var o = new Object();
  o.name = name;
  o.getName = function () {
    console.log(this.name);
  };
  return o;
}
  
var person1 = new Person('pingfan');
console.log(person1 instanceof Person) // false
console.log(person1 instanceof Object) // true

9.稳妥构造函数模式

没有公共属性,而且其方法也不引用 this 的对象。新创建的实例方法不引用 this,也不使用 new 操作符调用构造函数

function person(name){
  var o = new Object();
  o.getName = function(){
    console.log(name);
  };
  return o;
}
 
var person1 = person('kevin');
person1.getName(); // kevin
person1.name = "daisy";
person1.getName(); // kevin
console.log(person1.name); // daisy

--------------------------------------------------------------------------------------(完)-------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值