第六章 对象 梳理

对象是一种复合值,汇聚多个值并允许按名字存储和获取这些值。

创建对象的几种方式

1.对象字面量

创建对象最简单的方式。

let empty ={}   // 创建空对象
let point ={x:0,y:1}    //创建包含两个数值属性
let p2 = {x:point.x,y:point.y}    //创建包含两个复杂值的对象
let book ={
  "main title":"JavaScript",
  "sub-title":"The Definitive Guide",
  for:"all audiences",
  author:{
    firstname:"David",
    surname:"Flanagan"
  }
}

2.使用new创建对象

new操作符用于创建和初始化一个对象

let o = new Object()
let a = new Array()
let d = new Date()
let r = new Map()   //创建一个映射对象,用于存储键/值映射

原型prototype

原型:每个js对象都有另一个与之关联的对象,该对象被称为原型
通过对象字面量创建的所有对象都有相同的原型。使用new关键字创建的对象,它们的原型为objectName.prototype。

3.Object.create()

Object.create()用于创建新对象,能以任意原型创建新对象。使用第一个参数作为新对象的原型:

let o1 = Object.create({x:0,y:1})

创建一个没有原型的对象,只需要传入null。

let o2 = Object.create(null)

创建一个普通空对象,有原型

let o3 = Object.create(Object.prototype)

查询和设置属性

1.使用点操作符

let author = book.author;    //获取book.author属性
book.author = "greace";    //修改book.author属性

2.使用[]操作符

let title = book["main title"]    //获取book."main title"属性
book["main title"] = "ECMAScript";    //修改"main title"属性

作为关联数组的对象

关联数组是使用object.[字符串]形式,看起来像访问数组,不过是以字符串而不是数值作为索引的数组,这种形式被称为关联数组(或散列、映射、字典)

function addStock(protfolio, stockName, shares) {
  protfolio[stockName] = shares;
}
let protfolio ={}
addStock(protfolio,"stock1",1.2)
addStock(protfolio,"stock2",1.3)
console.log(protfolio)

此案例演示了使用数组表示法灵活的为对象添加属性。

继承

js对象有一组自有属性,同时也从它们的原型对象继承一组属性。

let o ={}   //o从Obejct.prototype继承对象方法
o.x = 1    //现在它有自有属性x
let p = Object.create(o)  //p从o和Obejct.prototype继承属性
p.y = 2    //p有一个自有属性y
let q = Object.create(p)   //q从p、o、Obejct.prototype继承属性
q.z = 3   //q有一个自有属性z
let f = q.toString()    //toString继承自Object.prototype
console.log(q.x+q.y)    //3 x和y分别继承自o和p

属性赋值查询原型链只是为了确定是否允许赋值。如果允许赋值,则只会在原始对象上创建或设置属性,而不会修改原型链中的对象。

属性访问错误

查询不存在的属性不是错误,表达式的求值结果是undefined。
查询不存在对象的属性则是错误。

let len = book.surtitle.length    //TypeError,book.surtitle本身不存在为undefined,undefined没有length

还有一种错误是,尝试设置只读属性时也会报错

删除属性

delete操作符用于移除对象中的属性。
delete只删除自有属性,不删除继承属性。

测试属性

检查对象是否有一个给定名字的属性

1.in操作符

自有属性和继承属性都返回true

let o = [x:1}
"x" in o    //true
"y" in o    //false
"toString" in o    //true

2.hasOwnProperty()

对继承属性都返回false

let o = [x:1}
o.hasOwnProperty("x")    //true
o.hasOwnProperty("y")    //false
o.hasOwnProperty("toString")    //false

3.propertyIsEnumerable()

自有属性且该属性为可枚举都返回true

4.使用!==

let o = [x:1}
o.x !== undefined    //true
o.y !== undefined    //false
o.toString !== undefined    //true

可枚举属性

for/in

用于遍历对象的每个可枚举属性。将属性名赋值给循环变量。对象的继承的内置方法不会被遍历。
还可以先获取对象所有属性名的数组,然后在通过for/of循环遍历数组

4个获取属性名数组的函数

  1. Object.keys()返回可枚举自有属性名的数组
  2. Object.getOwnPropertyNames()返回所以是字符串格式的属性名数组
  3. Object.getOwnPropertySymbols()返回所有是符号的属性名数组
  4. Reflect.ownKeys()返回所有属性名

扩展对象assign() ES6

把一个对象复制到另一个对象。
接收两个或多个对象作为参数,其中第一个对象作为目标对象,之后的对象作为源对象。
每个来源对象会把自身的可枚举自有属性复制到目标对象,第一个来源对象的属性会覆盖目标对象的同名属性,第二个来源对象属性会覆盖第一个来源对象的同名属性。

序列化对象

对象序列化是把对象的状态转换为字符串的过程,之后再从中恢复到对象的状态。
JSON.string()用于将对象转为字符串,只序列化对象的可枚举自由属性
JSON.parse()用于恢复字符串为对象格式

对象方法

  1. toString()方法不接收参数,返回调用它的对象的值的字符串。
  2. toLocaleString()方法,返回对象的本地化字符串表示。
  3. valueOf()方法,用于把对象转换为某些非字符串原始值时被调用。
  4. toJSON()

对象字面量扩展语法

简写属性

ES6同名属性可以简写

let x = 1, y =2;
let o ={x,y};
o.x+o.y;    //3

计算的属性名(ES6)

使用如下:

const PROPERTY_NAME = "p1";
function computedPropertyName(){return "p"+2;};

let o = {};
o[PROPERTY_NAME] = 1;
o[computedPropertyName()] = 2;
//或使用对象字面量的写法
let p ={
  [PROPERTY_NAME]: 1,
  [computedPropertyName()]: 2

这种语法可以在方括号中加入任何js表达式,这个表达式求值得到的结果会作为属性的名字。
可能需要计算属性的场景是,一个js代码库,需要给这个库传入一个包含一组特定属性的对象,而这组属性的名字在该库中是以常量定义的。

符号作为属性名

const extension = Symbol('my extension symbol');
let o ={
  [extension]:{}
}
o[extension].x = 0

使用符号是为了js对象定义安全的扩展机制。符号非常适合用于创建唯一的属性名。

扩展操作符...

扩展运算符只能扩展对象的自有属性,可用于将已有的对象扩展到其他对象上

let o = {x:1}
let p ={x:0,...o}  //对象o的值覆盖了初始值

简写方法

把函数定义为对象属性时,称为该函数为方法

//  ES6之前的写法
let square ={
  area: function(){return this.side * this.side;},
  side:10
}
square.area()  //100
//  ES6之后的写法
let square ={
  area (){return this.side * this.side;},
  side:10
}
square.area()  //100
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355

推荐阅读更多精彩内容