fe-interview icon indicating copy to clipboard operation
fe-interview copied to clipboard

[js] 第45天 写出几种创建对象的方式,并说说他们的区别是什么?

Open haizhilin2013 opened this issue 6 years ago • 8 comments

第45天 写出几种创建对象的方式,并说说他们的区别是什么?

haizhilin2013 avatar May 30 '19 20:05 haizhilin2013

const a = new Object() // 创建, 不推荐
const b = {} // 赋值, 性能比a要好
const c = Object.create() // 继承创建, Object.create(null) 很多框架都有用来做性能优化

wenyejie avatar May 31 '19 02:05 wenyejie

new Object()

直接通过构造函数创建一个新对象。

var obj = new Object()
//等同于 var obj = {}

使用字面量的方式更简单,其实他俩是一样的。 优点是足够简单,缺点是每个对象都是独立的。

工厂模式

function createObj(name,age){
    var obj = {};
    obj.name=name;
    obj.age=age;
    return obj
}
var Anson = createObj('Anson', 18)
console.log(Anson)
//{name: "Anson", age: 18}

优点是 可以解决创建多个相似对象的问题,缺点是 无法识别对象的类型。

构造函数

function Person(name,age){
    this.name =name;
    this.age=age;
    this.sayName =function (){ alert(this.name) }
}
var person = new Person('小明',13);
console.log(person);
//Person {name: "小明", age: 13, sayName: ƒ}

优点是 可以创建特定类型的对象,缺点是 多个实例重复创建方法

(构造函数+原型)组合模式

function Person(name, age){
    this.name = name;
    this.age = age;
    Person.prototype.sayName = function (){ alert(this.name) }
 }
var person = new Person('小白',18)
console.log(person);
//Person {name: "小白", age: 18} __proto__ -> sayName: ƒ ()

优点 多个实例引用一个原型上的方法 比较常用

动态原型

function Person(name,age){
    this.name=name
    this.age =age
    if(typeof this.sayName != 'function'){
        Person.prototype.sayName = function(){ alert(this.name) }
  }
}
var person = new Person('小红',15)
console.log(person);
//Person {name: "小红", age: 15} 动态创建sayName: ƒ ()

优点 可以判断某个方法是否有效,来决定是否需要初始化原型,if只会在仅在碰到第一个实例调用方法 时会执行,此后所有实例共享此方法,需要注意的一点是,不能重新原型对象。

寄生构造函数模式

function Person(name,age,job){
    var o=new Object();
    o.name=name;
    o.age=age;
    o.job=job;
    o.sayName=function(){
        console.log(this.name)
    }
    return o;
}
var friend=new Person("her",18,"Front-end Engineer");
friend.sayName();
//her

除了使用new操作符,其他的和工厂函数一样,可以为对象创建构造函数。

稳妥模式

function Person(name, age){
    var o={};
    o.sayName=function(){ alert(name) }
    return o;
}
var person = ('小亮',24);
person.sayName();//’小亮‘

除了使用person.sayName()之外 ,没有办法在访问到name的值,适合在某些安全执行环景下使用。

Object.create()

const person = {
  isHuman: false,
  printIntroduction: function () {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};

const me = Object.create(person);

me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

me.printIntroduction();
// expected output: "My name is Matthew. Am I human? true"

传入一个原型对象,创建一个新对象,使用现有的对象来提供新创建的对象的__proto__,实现继承。

参考:《JavaScript高级程序设计第三版》、MDN

AnsonZnl avatar May 31 '19 02:05 AnsonZnl

  • 字面量
let obj = {}
  • new 实例化
let obj = new Object
  • Object.create
let obj = Object.create({})

myprelude avatar Jun 13 '19 06:06 myprelude

我的博客

zxl-lxz avatar Mar 31 '20 05:03 zxl-lxz

const a = new Object() // 创建, 不推荐
const b = {} // 赋值, 性能比a要好
const c = Object.create() // 继承创建, Object.create(null) 很多框架都有用来做性能优化

smile-2008 avatar Nov 06 '20 01:11 smile-2008

  1. new Object(),直接通过构造函数创建一个新对象 var obj = new Object(); var obj = {};
  2. 工厂模式 function createObj(name, age) { var obj = {}; obj.name = name; obj.age = age; return obj; }
  3. 构造函数模式 function Person(name, age) { this.name = name; this.age = age; this.sayName = function () { console.log(this.name); } }
  4. 构造函数+原型 对于共同使用的方法,可以将其添加到原型上,避免重复创建
  5. 动态原型 在构造函数内部判断是否应该初始化原型
  6. 寄生构造函数模式 基本和工厂模式相同,但是在调用时多一个new
  7. 稳妥模式 只能通过特定的方法来访问内部的值,适用于安全状态要求较高的场景
  8. Object.create() 传入一个原型对象、创建一个新对象,使用现有的对象来提供新创建对象的__proto__,实现继承

HNHED avatar Sep 04 '21 15:09 HNHED

// 创建对象 // 1 字面量形式 var obj = {} // 2 api create var obj = Object.create() // 3 工厂函数 无法区分对象类型,因为都是Object类型 function createObj(name, age) { var o = new Object() o.name = name o.age = age return o } // 构造函数模式 每个实例的函数都会占据不同的内存空间 function createObj1(name, age) { this.name = name this.age = age this.sayName = function() { console.log(this.name) } } var oo = new createObj1('xq', 18) var oo1 = new createObj1('xq', 18) console.log(oo.sayName == oo1.sayName)

// 原型模式   原型属性会共享相同的属性 如果改变其他属性,原型实例也会跟着变动
function createObj2() {

}
createObj2.prototype.name = 'xq'
createObj2.prototype.age = 18
createObj2.prototype.sayName = function() {
  console.log(this.name)
}

// 混合模式 构造函数+原型
function createObj3(name, age) {
  this.name = name
  this.age = age
}
createObj3.prototype.sayName = function() {
  console.log(this.name)
}

xiaoqiangz avatar Jun 06 '22 06:06 xiaoqiangz

第一种 字面量 var obj = {} 第二种 new实例化 var obj = new Object(); 第三种 Object原型上的create方法 Object.create()

wyy-g avatar Sep 19 '22 14:09 wyy-g