创建对象的3个方法(js基础——对象(1))


title: (犀牛书)

tags: 创建对象,对象直接量,new创建对象 ,原型,Object.create()


创建对象

  • 三个方法:通过对象直接量、关键字new、Object.create()函数创建对象

1.1对象直接量

  • 什么是对象直接量?

由若干名/值对组成的映射表,名/值对中间由冒号(:)分隔,名/值对之间用逗号(,)分隔,整个映射表用花括号({})括起来 。如:


var student = {

name: 'xiaoming',

age: 12,

isStudent: true

};

  • 其中属性名可以是:标识符 / 字符串直接量(包含空字符串)

  • 属性值可以是: 任意类型的js表达值(表达式的值可以是原始值,也可以是对象值)


var empty = {};      //没有任何属性的对象

var point = {x: 0, y: 0};      //有两个属性的对象

var point = {x: point.x, y: point.y+1};    //一个更复杂的值

var book = {

"main title": "helloJS",  //1

"sub-title": "The Definitive Guide",    //2

"for": "all audiences",    //3

author: {

firstname: "David",

surname: "Flanagan"

}

};

  • 注意,上面代码中标注1,2,3 的地方。 属性名分别是用字符串来表示的,为什么?
  1. "main title" 属性名字里含有空格,必须使用字符串表示
  1. "sub-title" 属性名字里含有连字符,必须使用字符串
  1. "for" 属性名字里含有保留字,必须使用字符串
  • 对象直接量的特点
  1. 对象直接量是一个表达式

  2. 这个表达式每次运算都会创建 并初始化 一个 新的对象

  3. 每次计算对象直接量的时候,也都会计算它的每个属性值

  4. 所以,在一个重复调用函数体中,的循环体内,使用了对象直接量,它将创建很多新对象,并且每一次创建的对象的属性值也有可能不一样。

1.2通过new创建对象

关键字new后跟随一个函数调用(这里的函数成为:构造函数),就可以创建并初始化一个新对象。之后赋值给一个变量(一变以后的调用)。

  • 这里的构造函数用于初始化一个新创建的对象。

  • js中的原始类型————都包含内置构造函数。如:


var o = new Object();  //创建一个空对象,与{}一样

var a = new Array();    //创建一个空数组,与[]一样

var d = new Date();    //创建一个可以表示当前时间的对象

var r = new RegExp("js")    //创建一个可以进行匹配模式的RegExp对象

1.3原型

  • 每一个js对象(null除外)都和另一个对象相关联,“另一个”对象就是我们熟知的————原型。每一个对象都从原型继承属性。
  • 所有通过对象直接量创建的对象都具有同一个原型对象,并可以通过Object.prototype获得对原型对象的引用。
  • 通过关键字new和构造函数调用创建的对象的原型就就是——构造函数的prototype属性的值。

因此,通过new Object()创建的对象继承自Object.prototype,通过new Array()创建的对象的原型就是Array.prototype,通过new Date()创建的对象的原型就是Date.prototype

  • 注意:1. Object.prototype是一个没有原型的对象,它不继承任何属性。其余的对象都是普通对象,普通对象都具有原型。

    1. 所有的内置构造函数(以及大部分自定义的构造函数)都有一个继承自Object.prototype的原型。

例如:Date.prototype的属性————继承自————Object.prototype.

因此由new Date创建的Date对象的属性,同时继承自————Date.prototype和Object.prototype

1.4 Object.create()

ES5中定义了一个名为——Object.create()的方法,其作用是:创建一个新对象。

Object.create(proto[, propertiesObject])

这个语法的第一个参数是:新创建对象的原型。第二个参数是可选值,可以对对象的属性进行操作。

通过传入一个原型对象来创建一个新对象,新对象继承自原型的属性和方法。

  • Object.create()是一个静态函数,不能作为不能作为某个对象的调用方法来使用。只需要传入所需要的原型对象即可。如:

var o = Object.create({name:xiaoming, age:16 });    //o继承了原型的属性name与age

  • 那么,如果传入的原型(参数)是:null,会怎么样? Object.create(null);??

首席null(空),被创造的新对象,没有任何可继承的方法与属性。如:不能与任何运算符工作。甚至也不包括toString()方法。


var n = Object.create(null);    //代码运行返回的结果是:{}。 但是n 不继承任何方法与属性,

  • Object.create(proto)方法创建一个新对象,会继承自原形的属性与方法,那么如果我们想创建一个普通的空对象,比如:通过对象直接量{},或new Object()这样的方法,应该怎么办?

只需要传入一个Object.prototype即可,例如:


var o2 = Object.create(Object.prototype);  //创建的新对象与{}和new Object一样。

总结(一个强大的特性):

  1. 任意的原型都能创造新对象。
  1. 任意的对象都可以被继承给新对象。

ES3中可以用类似以下的代码来模拟原型继承:

(也是一个对象继承函数的案例)


//inherit()返回一个继承自原型对象P的属性的新对象

//以下代码中Object.create()是ES5的方法,需要验证是否可用。(特性侦查)

//如果不存在Object.create()方法,则退化使用其他方法。

function inherit(p) {

if(p == null) throw TypeError()  //如果对象是null,则抛出异常

if(Object.create)

return Object.create(p)  //如果存在此方法优先使用

var t = typeof p;      //否则进行进一步检查

if(t !== "object" && t !== "function") throw TypeError();

function f(){};      //定义一个空构造函数。

f.prototype = p;        //将构造函数f的原型设置为p,函数f就继承自p的属性了

return new f();        //使用f()创建p的继承对象

}

  • inherit()与Object.create()的区别

相同点:都是以参数为原型, 返回的新对象继承自原型的属性。

不同点:1. inherit()不能传入null原形来创建对象。 2. inherit()不能接受可选的第二个参数。

  • inherit()用作:防止库函数无意间修改那些不受你控制的对象。

因为:inherit()不是将对象直接作为参数传入函数,而是将它的继承对象传入函数。

所以:实际上读取的是继承来的值。如果给继承属性赋值,则这些属性只会影响继承属性自身,而不是原始对象。例:


var o = {x: "don't change this value"}

library_function(inherit(o));  //防止对o的意外修改。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 3,023评论 4 14
  • 博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...
    _Dot912阅读 1,449评论 3 12
  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 4,661评论 0 5
  • 词法阶段 词法作用域是由你在写代码时将变量和块作用域写在哪里来决定的,因此当词法分析器处理代码时会保持作用域不变(...
    后发而先制阅读 626评论 0 0
  • [TOC] 声明 该系列文章只是记录本人回顾java多线程编程时候记录的笔记。文中所用语言并非严谨的专业术语(太严...
    hylexus阅读 260评论 0 0