全面了解JavaScript对象进阶
要了解JavaScript对象,我们可以从对象创建、属性操作、对象方法这几个方面入手。概括起来,包括以下几模块
1.创建对象
1.1 对象直接量
对象直接量是创建对象最简单的方式,由若干名/值对组成映射表:
var point = {x: 0, y: 0 };
属性名也没有什么限制,可以是js的关键字或者任意字符串,如果是这两种情况,属性需要用双引号引起来
var empty = {}; va point = {x: 0, y: 0 }; var book = { "main title": "Javascript", "sub-title": "The definitive Guide", "for": "all audience", author: { firstName: "Davide", lastName: "Flanagan" } };
对象直接量创建对象十分简单,但一般都不会这样使用。代码可复用性低,如果想要在其他地方使用该对象并且属性值不一样,那这么办?是不是又得重新创建一份代码?
1.2 通过new创建对象
通过new创建对象之前,先要创建一个函数,new把这个函数当做构造函数(constructor)。例如通过new创建一个Person对象
function Person(){ //构造函数 } var person = new Person();
Javscript语言核心中的原始类型都包含内置构造函数
var a = new Array(); var d = new Date(); var r = new RegExp(“js”);
1.3 Object.create()
在了解Object的create方法之前,我们想看看什么是原型。每一个Javascript对象(null除外)都和另一个对象相关联。“另一个”对象就是我们所说的原型。每一个对象都从原型继承属性。
所有通过对象直接量创建的对象都具有同一个原型对象Object.prototype。关键字new和构造函数创建的对象原型就是构造函数的prototype属性的值。通过new Array()创建对象的原型为Array.prototype,通过new Date()创建的对象原型为Date.prototype。原型暂介绍到这里。
Object.create方法包含两个参数,第一个参数是对象的原型,第二个参数可选,用于描述对象属性。使用很简单,只需传入所需的原型对象即可
var o1 = Object.create({x: 1, y: 2 }); //原型为Object.prototype
如果想创建一个没有原型的对象,可通过传入null作为参数。这样创建的对象不会继承任何属性,也没有像toString这样的方法
var o2 = Object.create(null); //没有原型
如果想创建一个普通的空对象,直接传入Object.prototype
var o3 = Object.create(Object.prototype);
如果是自定义的对象,和创建空对象一样。直接传入对象名.prototype:
function Person(){ } var o4 = Object.create(Person.prototype);
2.属性管理
2.1 属性查询和设置
对象的属性可通过点(.)或方括号([])运算符获取。如果使用点获取属性,属性名必须是简单的表示符。不能是保留字,比如,o.for或者o.class。
ar author = book.author; //正确 var name = author.surname; //正确 var title = book[“main title”]; //正确 var className = book.class; //错误
object[“property”]这种语法看起来更像数组,只是这个数组的元素是通过字符串索引而不是数字索引。这种数组就是我们所说的关联数组,也称为散列、映射或字典。Javascript对象都是关联数组。
既然对象是关联数组,那么Javascript也为我们提供了属性的遍历方式for/in。狼蚁网站SEO优化的例子利用for/in计算portfolio的总计值
function getvalue(portfolio){ var total = 0.0; for(stock in portolio){ var shares = portolio[stock]; var price = getquote(stock); total += shares price; } return total; }
继承Javascript对象具有自有属性(own property),也有一些属性是从原型对象继承而来。我们先看看一个实现继承功能的函数inherit
function inherit(p){ if (p == null) throw TypeError(); //p是一个对象,大不能是null if(Object.create){ return Object.create(p); //直接使用Object.create方法 } var t = typeof p; if(t !== "object" && t !== "function") throw TypeError(); function f() {}; f.prototype = p; //将其原型属性设置为p return new f(); }
假设要查询对象o的属性x,如果o中不存在x,将会继续在o的原型对象中查询属性x。如果原型对象中也没有x,但这个原型对象也有原型,那么继续在这个原型对象的原型上执行查询,直到找到x或者查询到一个原型为null的对象为止。
var o = {}; //o从Object.prototype继承对象属性 o.x = 1; //给o定义x属性 var p = inherit(o); //p继承o和Object.prototype p.y = 2; //p定义属性y var q = inherit(p); //q继承p、o和Object.prototype q.z = 3; //给q定义属性z var s = q.toString(); //toString继承自Object.prototype q.x + q.y // => 3x和y分别继承自o和p
2.2 删除属性
delete运算符可以删除对象的属性
delete book.author; delete book[“main title”];
delete只能删除自有属性,不能删除继承属性。要删除继承属性,必须从定义这个属性的原型对象上删除它,而且这会影响到所有的继承自这个原型的对象。删除成功会返回true。
ar o = {x: 1}; delete o.x; //删除x,返回true delete o.x; //x已经不存在了,什么都没做,返回true。 delete o.toString; //什么都没做,返回true。 delete不能删除可配置型为false的属性。某些内置对象的属性是不可配置的,比如通过变量声明和函数声明创建的全局对象的属性 delete Object.prototype //不能删除,属性是不可配置的 var x = 1; delete this.x; //不能删除这个属性 function f() {} delete this.f; //不能删除全局函数
2.3 检测属性
判断某个属性是否存在于某个对象中,可通过in运算符、hasOwnProperty()和propetyIsEnumerable()方法来检测。
in运算符运算符左侧是属性名,右侧是对象。如果对象的自有属性或者继承属性包含属性则返回true
var o = {x: 1}; "x" in o; //truex是o的属性 "y" in o; //falsey不是o的属性 "toString" in o; //trueo继承toString属性
hasOwnProperty()方法检测给定的名字是否是对象的自有属性。对于继承属性它将返回false
var o = {x: 1}; o.hasOwnProperty("x"); //trueo有一个自由属性x o.hasOwnProperty("y"); //falseo中不存在属性y o.hasOenProperty("toString"); //falsetoString是继承属性
propertyIsEnumerable()方法是hasOwnProperty的增强版,只有检测到自有属性并且这个属性是可枚举行为true时才返回true
var o = inherit({y: 2}); o.x = 1; o.propertyIsEnumerable("x"); //true o有一个可枚举属的自有属性x o.propertyIsEnumerable("y"); //falsey是继承来的 Object.prototype.propertyIsEnumerable("toString"); //false:不可枚举
2.4 枚举属性
通常使用for/in循环遍历对象属性,遍历的属性包括自有属性和继承属性。对象继承的内置方法是不可枚举的,但在代码中给对象添加的属性都是可枚举的。例如
var o = {x: 1, y: 2, z: 3}; //三个可枚举的自有属性 o.propertyIsEnumeable("toString"); //false,不可枚举 for (p in o) //遍历属性 console.log(p); //输出x、y和z,不会输出toString
有时候我们只想遍历自有属性,并且属性不为函数
for(p in o){ if(!o.hasOwnProperty(p)) continue; if(typeof o[p] === "function") continue; }
我们可通过枚举遍历功能实现可枚举属性的复制
/ 把p中的可枚举属性复制到o中,并返回o 如果o和p含同名属性,则覆盖o中的属性 这个函数并不处理getter和setter以及复制属性 / function extend(o, p){ for(prop in p){ //遍历p中的所有属性 o[prop] = p[prop]; //将属性添加到o中 } return o; }
ES5定义了两个用以枚举属性名称的函数。第一个是Object.keys(),返回由对象中可枚举属自有属性名称组成的数组。第二个枚举函数是Object.getOwnPropertyNames(),和Object.keys()类似,它返回对象的所有自有属性,而不仅仅是可枚举属性。
3.属性封装
3.1 属性getter和setter
对象属性由名字、值和一组特性(attribute)构成的。在ES5中,属性值可以用一个或两个方法替代,这两个方法就是getter和setter。由getter和setter定义的属性称做“存取器属性”,它不同于“数据属性”,数据属性只有一个简单的值。
和数据属性不同,存取器属性不具有可写性(writeable atribute)。如果属性具有getter和setter方法,那么它是一个读/写属性。如果它只有getter方法,那么它是一个只读属性,如果它只有setter方法,那么它是一个只写属性。读取只写属性总是返回undefined。
存取器属性定义语法也比较简单,函数定义没有使用function关键字,而是使用get或set
var o = { //普通的数据属性 data_prop: 1, //存取器属性都是成对定义的函数 get aessor_prop(){/ 这里是函数体
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程