资讯专栏INFORMATION COLUMN

关于创建对象的三种写法 ---- 字面量,new构造器和Object.create()

Jiavan / 1513人阅读

摘要:前言重新梳理一下发现以前说的有问题顺便比较两两写法之间的差异性使用对象字面量表示法函数字面量运行时间嵌套函数字面量调用方法函数字面量运行时间函数字面量运行时间使用操作符后跟构造函数详情可参考关于中的运算符构造函数与原型链一些理解构造函数原型

前言

PS:2018/04/14: 重新梳理一下发现以前说的有问题,顺便比较两两写法之间的差异性.

1、使用“对象字面量”表示法
console.time("函数字面量运行时间");
//嵌套函数字面量
var Person = {
  name: "one"
};
Person.getName = function () {
  console.log(this.name);
}
//调用方法
Person.getName(); // one
console.timeEnd("函数字面量运行时间") // 函数字面量运行时间: 4.969ms
2、使用new操作符后跟Object构造函数

详情可参考关于Javascript中的new运算符,构造函数与原型链一些理解

//构造函数
function Person(name) {
  this.name = name
}
//原型添加方法
Person.prototype.getName = function () {
  console.log(this.name);
}

console.time("构造函数运行时间");
//生成实例
var Person = new Person("two");
//调用方法
Person.getName(); // two
console.timeEnd("构造函数运行时间"); // 构造函数运行时间: 5.435ms

当代码执行时会经过几个步骤:

1,一个继承自Person.prototype的新对象被创建.
2,创建执行的时候,同时上下文(this)会被指定为这个新实例
3,执行构造函数中的代码(设置新对象的__proto__属性指向构造函数的prototype对象等)
4,new出来的结果为步骤1创建的对象
3、使用Object.create(prototype, descriptors)

这是E5中提出的一种新的对象创建方式,对主流浏览器友好,创建一个具有指定原型且可选择性地包含指定属性的对象。(详情可参考Object.create 函数 (JavaScript))

参数 描述
prototype(必需) 要用作原型的对象,可以为 null
descriptors(可选) 包含一个或多个属性描述符的 JavaScript 对象
返回值

一个具有指定的内部原型且包含指定的属性(如果有)的新对象;

异常

prototype 参数不是对象且不为 null;

descriptors 参数中的描述符具有 value 或 writable 特性,并具有 get 或 set 特性;

descriptors 参数中的描述符具有不为函数的 get 或 set 特性;

需要注意descriptors“数据属性”是可获取且可设置值的属性.数据属性描述符包含 value 特性,以及 writableenumerableconfigurable 特性.如果未指定最后三个特性,则它们默认为 false.只要检索或设置该值,“访问器属性”就会调用用户提供的函数. 访问器属性描述符包含 set 特性和/或 get 特性.即

//构造函数
function Person(name) {
  this.name = "name"
}
//原型添加方法
Person.prototype.getName = function () {
  console.log(this.name);
}

console.time("Object.create运行时间")
//生成实例
var Person = Object.create(Person.prototype, {
  name: {
    value: "three"
  }
});
Person.getName(); // three
console.timeEnd("Object.create运行时间") // Object.create运行时间: 3.272ms

允许修改需要设置writable属性

//构造函数
function Person(name) {
  this.name = "name"
}
//原型添加方法
Person.prototype.getName = function () {
  console.log(this.name);
}

//生成实例
var Person = Object.create(Person.prototype, {
  name: {
    value: "three",
    writable: true,
  }
});
Person.name = "four";
Person.getName(); // four
new和Object.create区别
function Person(name) {
  this.name = 1
}
Person.prototype.name = 2;

//生成实例
var Person_new = new Person();
var Person_create = Object.create(Person);
var Person_create_prototype = Object.create(Person.prototype);

console.log(Person_new, Person_create, Person_create_prototype);
// Person { name: 1 } Function {} Person {}

区别
属性 new构造函数 Object.create(构造函数) Object.create(构造函数原型)
实例类型 实例对象 函数 实例对象
实例name 1
原型name 2 2
小结
对比 new Object.create
使用目标 函数 函数和对象
返回实例 实例对象 函数和实例对象
实例属性 继承构造函数属性 不继承构造函数属性
原型链指向 构造函数原型 构造函数/对象本身
对象字面量和Object.create区别
//构造函数
function Person(name) {
  this.name = 1
}
Person.prototype.name = 2;
//生成实例
var Person1 = {
  name: 1
};
var Person_create_prototype = Object.create(Person.prototype);
console.log(Person1, Person_create_prototype);
// { name: 1 } Person {}

区别
属性 对象字面量 Object.create
实例类型 纯对象 实例对象
实例name 1
原型name 2
原型链指向 Object Person
小结
对比 对象字面量 Object.create
使用目标 纯对象 函数和对象
返回实例 纯对象 函数和实例对象
实例属性 非继承属性 不继承构造函数属性
原型链指向 Object 构造函数/对象本身
个人总结:

对象字面量是最简洁的写法;

Object.create()可以实现一个继承目标且可高度配置的对象;

Object.create(null)可以得到无继承的最纯净对象;

console.log(Object.create(null)) // [Object: null prototype] {}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106170.html

相关文章

  • 关于javascript的原型原型链,看我就够了(一)

    摘要:要用作原型的对象。函数对象可以创建普通对象,这个我们上面讲过了回顾一下这是一个自定义构造函数普通对象没法创建函数对象,凡是通过创建的对象都是函数对象,其他都是普通对象通常通过创建,可以通过来判断。 关于js的原型和原型链,有人觉得这是很头疼的一块知识点,其实不然,它很基础,不信,往下看要了解原型和原型链,我们得先从对象说起 创建对象 创建对象的三种方式: 对象直接量 通过对象直接量创建...

    MoAir 评论0 收藏0
  • __proto__prototype之区别联系

    摘要:当这步完成,这个对象就与构造函数再无联系,这个时候即使构造函数再加任何成员,都不再影响已经实例化的对象了。此时,对象具有了和属性,同时具有了构造函数的原型对象的所有成员,当然,此时该原型对象是没有成员的。 学到原型的时候感觉头都大了/(ㄒoㄒ)/~~ 尤其是prototype和__proto__ 傻傻分不清,通过多番查找资料,根据自己的理解,记录下最近研究对象的一些心得,做一个记录与总...

    paulli3 评论0 收藏0
  • 关于原生js的一些研究

    摘要:这个属性本身又是一个类型的对象,原型对象都包含一个指向构造函数的指针,而每一个实例也都包含一个指向原型对象内部的指针。 前阵子忙于准备CET-6,没时间更新文章,之后大概一个月将忙于准备期末考,也应该不会更新了,今天趁周末有时间再更新一篇最近研究的一些东西吧。 callee和caller function inner(){ console.log(arguments.calle...

    wind3110991 评论0 收藏0
  • javascript对象详解:__proto__prototype的区别联系

    摘要:当这步完成,这个对象就与构造函数再无联系,这个时候即使构造函数再加任何成员,都不再影响已经实例化的对象了。此时,对象具有了和属性,同时具有了构造函数的原型对象的所有成员,当然,此时该原型对象是没有成员的。 前言 本篇文章用来记录下最近研究对象的一些心得,做一个记录与总结,以加深自己的印象,同时,希望也能给正在学习中的你一点启发。本文适合有一定JavaScript基础的童鞋阅读。原文戳这...

    chavesgu 评论0 收藏0
  • 关于javascript的原型原型链,看我就够了(三)

    摘要:对于中的引用类型而言,是保存着它们所有实例方法的真正所在。高级程序设计构造函数陌上寒原型对象有一个属性,指向该原型对象对应的构造函数为什么有属性那是因为是的实例。 温故 我们先回顾一下前两天讨论的内容 创建对象的三种方式 通过对象直接量 通过new创建对象 通过Object.create() js中对象分为两种 函数对象 普通对象 原型对象prototype 每一个函数对象都...

    joyvw 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<