对象
对象是动态的——可以新增属性也可以删除属性,但是对象经常用来模拟静态对象以及静态类型语言中的“结构体”。对象的属性是可以增加和删除的。
对象特性

对象原型(prototype):指向另外一个对象,本对象的属性继承自它的原型对象。
对象的类(class):是一个表示对象类型的字符串。
*对象的扩展标记(extensible flag):指明是否可以向该对象添加新属性。
属性特性

可写 (是否可以设置属性值)
可枚举 (是否可以通过for in 循环返回该属性)
可配置 (是否可以删除或者修改属性)
对象的创建

对象直接量
创建对象最简单的方法是通过对象直接量。

var empty = {}; //没有任何属性的对象var point = {x:0, y:0}; // 两个属性var point2 = {x:point.x, y:point.y+1}; var student = {name:"Allen",                //属性名可以不用引号age:23,school:{                      //这个属性值是一个对象,"primary school" :"试验小学",//属性名中有空格,必须字符串"middle-school" :"育才中学" ,//属性名中有连接符,必须用字符串
}
}
/*最后注意一点,属性名尽量避免使用空格、连接符、或者关键字,如果必须使用的话,尽量用引号引起来*/

通过new 创建对象

var mObj = new Object(); // 创建一个空对象,和{}一样var arr = new Array(); // 创建一个空数组,和[]一样
var mDate = new  Date(); // 创建一个表示当前时间的Date对象

通过 Object.create()
在这里,我们先弄清楚一个名词——原型,每一个JS对象(除了null)都和另一个对象相关联。“另一个”对象就是我们所说的原型,每一个对象都从原型继承属性。
所有通过对象直接量创建的对象都具有同一个原型对象,并可以通过JS代码Object.prototype获得对原型对象的引用。通过关键字new和构造函数调用创建的对象的原型就是构造函数的prototype属性的值。因此,同使用{}创建对象一样,通过new Object()创建对象也继承自Object.prototype

ECMAScript 5 定义了一个名为Object.create()的方法,它创建一个新的对象,其中第一个参数就是对象原型,第二个参数是可选参数,用以对对象的属性进行进一步描述。
Object.create()`是静态函数,而不是提供给某一个对象调用的方法。

var obj = Object.create({x:1,y:2}); // obj继承了属性x,y
var obj2 = Object.create(obj); //obj2的原型是obj,继承了属性x,y;
// 如果想创建一个普通的空对象(比如通过{}或者new Object()创建的对象 ),需要传入Object.prototype
var obj3 = Object.create(Object.prototype);//obj3和{}和new Object()一样

现在我们来看看如何自己写一个函数来通过原型来创建对象,看例子

function createObject(obj){// 先对obj对象进行判断,看是否为null,如果是抛出异常if(obj == null) throw TypeError();// Object.create是否可用,可用则返回if(Object.create)  return Object.create(obj);// 不可用时,检测对象的类型var objType = typeof obj;// 如果对象类型不是Object 也不是函数的话,抛出异常if(objType !=="object" && objType !=="function") throw TypeError();// 定义一个空构造函数 并且将函数的原型设置成objfunction mfunc(){};mfunc.prototype = obj;return new mfunc();}

属性
对象访问属性的方法有两个,通过(.)和([])运算符来获取属性值。这里不做解释。
下来我们详细讲解一下通过([])获取属性值,这种获取属性值的方法很像数组,只是数组的索引是数字,而它的索引是字符串。这种数组就是我们将要说明的关联数组,也成散列、映射或字典。由于JS是弱类型语言,在任何对象中程序都可以创建任意数量的属性。通过([])来访问对象的属性时,属性名是字符串,这样更利于我们在程序运行时进行修改和创建属性。
我们举个例子来说明它的灵活性吧,假设我们去超市购买东西,我们把需要买的东西放入购物车,这辆购物车的作用就是显示我们放入的商品名称,以及商品的单价和数量。你有没有思路呢?学过类似C语言的同学,可以想想如何来实现。简单说一下我的思路吧(用类似C语言的方式的思路,大神勿喷,可以留下你的思路),此处的购物车我们用一个类似字典的对象来表示,字典的Key就是我们的商品名称,Value则是一个对象,对象中的属性包含:商品价格、数量。现在想想用JavaScript如何,思路其实同我上面说的类似,直接看代码吧。

var shoppingCart = {};//这里是购物车
// 添加商品的方法
function addGoods(name,price,count){shoppingCart[name] = {m_price:price,m_count:count};
}

(一)继承(属性的查询和设置)

JS对象有自有属性和继承属性,我觉得通过举例更容易说明这两个属性的关系。
查询对象的属性举例:
假设要查询对象obj的属性x,如果obj中不存在x,那么将会继续在obj的的原型对象中查询属性x,如果原型对象也没有x,但是这个原型对象也有原型(原型不为null),那么继续在这个原型对象的原型上执行查询,直到找到x或者查找到一个原型为null的对象为止。
给对象的属性赋值举例:
假设给对象obj的属性x赋值,如果obj中已经有属性x(这个属性不是继承来的),那么这个赋值操作只改变这个已有属性x的值。如果obj中不存在属性x,那么赋值操作给obj添加一个新属性x。如果之前obj继承自属性x,那么这个继承的属性就会被新创建的同名属性覆盖。
小总结:对象的属性赋值,不会修改原型的属性值的,只会创建属性或者对自有属性赋值。但是需要注意的是,属性赋值操作首先是检查原型链,以此判断是否允许赋值,如果继承的属性是只读的,则赋值操作是不允许的
看一个例子:

var obj = {x:1,y:2};
var obj2 = Object.create(obj);
console.log(obj);   // ==> {x:1,y:2}
console.log(obj2);   // ==> {x:1,y:2}
//----看点 1-----
// 现在对obj2 属性x值进行修改,看看obj 和 obj2的变化
obj2.x = 100;
console.log(obj);   // ==> {x:1,y:2}
console.log(obj2);   // ==> {x:100,y:2}
/*可以看出————对象的属性不会修改原型的属性*/
// -------------------------------------------------------
//----看点 2-----
// 这个时候我们对obj 属性x进行修改,看看变化
obj.x = 111;
console.log(obj);   // ==> {x:111,y:2}
console.log(obj2);   // ==> {x:100,y:2}
/*可以看出————对象属性赋值的时候只会创建属性或者对自有属性进行赋值,因为在之间对obj2的x属性进行赋值的时候,obj2的自有属性中没有x属性,所以obj2会创建新的属性x并赋值,同时覆盖掉继承属性x的值*/
// -------------------------------------------------------
//----看点 3-----
// 我们现在对obj 属性y进行修改,看看变化
obj.y = 222;
console.log(obj);   // ==> {x:111,y:222}
console.log(obj2);   // ==> {x:100,y:222}
/*这里就可以体现我们上面说到的对象属性的查询过程,因为obj的y属性修改为222,当我们查询obj2的y属性的时候,obj2的自有属性中没有y值,所以obj2就会到它的原型(obj)中查找,原型中的y属性经过修改变成222,所以查询的obj2属性y的结果就是222*/
// -------------------------------------------------------
//----看点 4-----
// 我们来看看访问一个不存在的属性,
console.log(obj2.m_string); // ==> undefined
console.log(obj2.m_string.length); // ==>  这里会报错
/*当访问的属性不存在的时候,系统会返回一个undefined,而null和undefined值是没有属性的,因此上述第二行代码会报错。*/
// 我们可以通过判断的方法来避免错误的出现
var strLength;
if(obj2 && obj2.m_string)  strLength = obj2.m_string.length;
//还有一种更简练的方法
strLength = obj2 && obj2.m_string && obj2.m_string.length;

经过上面的例子,你是否搞懂继承了?

#####(二)属性的删除、检测、枚举
删除属性
说先我们来了解一下delete运算符,该运算符可以删除对象的属性。但是delete只是断开属性和宿主对象的关系,而不会去操作属性中的属性。delete表达式删除成功时会返回true。
需要注意的是,delete运算符只能删除自有属性,不能删除继承属性,也不能删除不可配置的属性。

// 删除属性的操作
var mframe = {point:{x:11,y:22},size:{width:100,heght:50}};
// 这里用p对象引用mfram的point属性
var p = mframe.point;
// 当我们执行删除操作之后,来打印p看看结果
delete mframe.point;
console.log(p);  // ==> {x:11,y:22};
/*执行代码之后,我们知道mframe已经没有了point属性,但是由于已经删除的属性的引用依然存在,因此在JS的某些实现中,可能因为这种不严谨的代码而造成内存泄漏,所以在销毁对象的时候,要遍历属性中的属性,依次删除*/

检测属性
检测属性主要是来判断某属性是否存在于某个对象中,我们用代码来介绍一下检测属性。

// in运算符来检测属性,左侧是 属性名(字符串),右侧是对象
var mpoint = {x:1,y:2};
console.log("x" in mpoint);   //==> true
console.log("z" in mpoint);   //==> false
console.log("toString" in mpoint);  //==> true,toString是继承属性;
// -------------------------------------------------------
// hasOwnProperty()方法用来检测给定的名字是否是对象的自有属性,对于继承属性它将返回false。
console.log(mpoint.hasOwnProperty("x")); //==> true
console.log(mpoint.hasOwnProperty("z")); //==> false
console.log(mpoint.hasOwnProperty("toString")); //==> false
// -------------------------------------------------------
// propertyIsEnumerable()是hasOwnProperty()的加强版,只有检测到是自有属性且这个属性是可枚举的才会返回ture.这里就不做举例了

枚举属性
我们经常会遍历对象的属性,通常使用for/in循环来遍历。for/in 循环可以遍历对象中所有可枚举的属性(包括自有属性和继承属性)。
有许多实用工具库给Object.prototype添加了新的方法或属性,这些属性可以被所有对象继承并使用,但是在ECMAScript 5标准之前,这些新添加的方法是不能定义为不可枚举的,因此使用for/in循环进行枚举的时候,这些属性会被枚举出来。为了避免这种情况,我们需要在for/in 中进行过滤,有两种常见的方法:

for(p in obj){if(!obj.hasOwnProperty(p)) continue;  // 跳过继承的属性
}
//---------------------------------
for(p in obj){if(typeof obj[p] === "function") continue;  // 跳过方法
}

除了for/in循环之外,ECMAScript 5 定义了两个用以枚举属性名称的函数。

Object.keys(),它返回一个数组,这个数组由对象中可枚举的自有属性的名称组成。
Object.getOwnPropertyNames(),它返回对象的所有自有属性的名称(包括自有属性中的可枚举属性和不可枚举属性).

JavaScript对象(一)相关推荐

  1. 如何获取HTML元素对应JavaScript对象?

    <!DOCTYPE html> <html><head><meta charset="UTF-8"><title>< ...

  2. JavaScript对象,方括号和算法

    by Dmitri Grabov 德米特里·格拉波夫(Dmitri Grabov) JavaScript对象,方括号和算法 (JavaScript Objects, Square Brackets a ...

  3. 我对javascript对象的理解

    前言 JavaScript这门语言除了基本类型都是对象,可以说JavaScript核心就是对象,因此理解JavaScript对象及其种种特性至关重要,这是内功.本文介绍了我对es5对象,原型, 原型链 ...

  4. 《JavaScript启示录》——1.21 JavaScript对象和Object()对象

    本节书摘来自异步社区<JavaScript启示录>一书中的第1章,第1.21节,作者:[美]Cody Lindley著,更多章节内容可以访问云栖社区"异步社区"公众号查 ...

  5. 《JavaScript启示录》——第1章 JavaScript对象 1.1创建对象

    本节书摘来自异步社区<JavaScript启示录>一书中的第1章,第1.1节,作者:[美]Cody Lindley著,更多章节内容可以访问云栖社区"异步社区"公众号查看 ...

  6. 如何通过其值获取JavaScript对象中的键?

    本文翻译自:How to get a key in a JavaScript object by its value? I have a quite simple JavaScript object, ...

  7. 如何从JavaScript对象中删除项目[重复]

    本文翻译自:How to remove item from a JavaScript object [duplicate] Possible Duplicate: 可能重复: How to remov ...

  8. 如何遍历JavaScript对象?

    本文翻译自:How to iterate over a JavaScript object? I have an object in JavaScript: 我在JavaScript中有一个对象: { ...

  9. 打印JavaScript对象的内容? [重复]

    本文翻译自:Print content of JavaScript object? [duplicate] This question already has an answer here: 这个问题 ...

  10. 通过属性值从对象数组中获取JavaScript对象[重复]

    本文翻译自:Get JavaScript object from array of objects by value of property [duplicate] This question alr ...

最新文章

  1. 读书笔记之:C/C++程序员实用大全—C/C++最佳编程指南
  2. 什么是mysql分发版_MySQL:使用源码分发版还是二进制分发版
  3. android socket_附详尽答案,新版精选Android中高级面试题二
  4. 任务队列和异步接口的正确打开方式(.NET Core版本)
  5. ASM_PREFERRED_READ_FAILURE_GROUPS
  6. 关于六年级定格动画计算机教案,定格动画教案
  7. 解决pathForResource返回nil / 无法读取plist文件问题
  8. IntelliJ IDEA常用快捷键——基于Eclipse
  9. python3怎么使用mnist_loader_Python读取mnist
  10. 基于JAVA+SpringMVC+Mybatis+MYSQL的漫画社区
  11. 迪士尼收购福克斯,传媒巨头江山瓦解?
  12. Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作
  13. 一组开源asp.net用户控件
  14. SpringBoot 2.0.0 注入SpingCloud 有bug(目前只有SpringBoot 1.5+ 版本的支持)
  15. 数据库SQL语言的使用
  16. 概率论——马尔科夫链
  17. 【产业互联网周报】阿里云栖大会、百度世界大会召开:阿里重推“云端一体”、百度AI全面升级...
  18. html校验邮箱格式,邮箱格式验证 方法总结
  19. 通过 经纬度 获取 地理位置(Python、高德地图)
  20. 第十五天PAT-A1124 Raffle for Weibo Followers简单模拟测试点三错误说明

热门文章

  1. Excel设置excel打印每页都有表头标题
  2. schedule浪子何时回头?
  3. FreeType粗体研究
  4. Python -- 抽象类、包装器
  5. 操作系统笔记(II:从进程同步到文件管理)
  6. Aop中动态横切与静态横切
  7. Vue路由 传参几种方式
  8. ubuntu 安装kde桌面_Ubuntu下安装KDE桌面环境
  9. 爬虫之SSL-校验网站证书
  10. 《经济学的思维方式》精髓:学好经济学,你才能了解人类社会的运转规律。