本篇博客仅为自己学习中的一个小总结,总结的目的只是为了更方便记忆和理解javaScript的对象,总结的内容全部为《JavaScript权威指南》这本书中的内容,向原作者致敬,也希望大家能多多支持原著!如有侵权,请在博客下方留言,我会在第一时间删除。
/**
* javaScript中对象的基本理解:
* 1.javaScript的基本数据类型
* 2.对象是一种复合值,聚合了很多的值(例如:原始值、其他对象)
* 3.通过名字访问对象的值
* 4.每一个属性都是名字(键)/值对,属性是字符串
* 5.这种数据的叫法:"散列"(hash)、"散列表"(hashtable)、"字典"(dictionary)、关联数组(associative array)
//C、C++、Java等强类型语言,对象只有固定的数目的属性,并且这些属性名称必须提前定义好
//JavaScript为弱类型语言
*
*JavaScript特征:
* 1.不仅仅是字符串到值得映射,可以保持自有的属性,还可以从原型对象继承属性也可以称为"原型式继承"
* 2.动态特性的语言,可新增也可删除熟悉感,常用此特性模拟静态对象以及静态类型语言中的"结构体(strut)",有时也用做字符串的集合
* 3.除了字符串、数字、true、false、null和undefined之外,JavaScript中的值都是对象,但是它们的行为和不可变对象非常类似
*
*重点理解:
* 1.由于对象是可变的,使用的时候需要通过引用一个非值来操作对象
* 例如:var pp = yy,yy为指向一个对象的引用,而不是这个对象的副本。通过变量pp修改这个对象就会对变量x造成影响
*
* 常见的用法:
* 1.创建(create)、设置(set)、查找(query)、删除(delete)、检测(test)、枚举(enumerate)
**/
一、对象的创建方式:
一、直接量创建
var empty = {};
var point = {x:0,y:0};
var point2 = {x:point.x,y:point.y+1};
var book = {
"inpotTitle":"JavaScript",
'title':"我们需要努力!",
"for":"all audiences",
diaosi:{
firstname:"David",
suiName:"Flanagan"
}
};
二、new创建
var o = new Object();//创建一个空对象,和{}一样
var a = new Array();//创建一个表示空数组,和[]一样
var d = new Date();//创建一个表示当前时间的Date对象
var r = new RegExp("js");//创建一个可以进行模式匹配的EegEx对象
三、Object.create()创建
(1)、原型的理解
/*
1.除null之外都和另一个对象(原型对象)相关联
2.每一个对象都是从原型对象中继承属性
3.所有通过对象直接量创建的对象都具有同一个原型对象 通过Object.prototype获得对原型对象的引用
4.new、构造函数调用创建的对象原型就是构造函数的prototype 原型链
*/
(2)、Object.create()创建的对象的理解
/**
* Object.create() 是一个静态函数 不是供给某个对象调用的方法
*
* 1.使用create()创建对象的时候第一个参数为这个对象的原型。
* 2.第二个参数为可选参数 对对象的属性进一步描述
*/
var pp= Object.create({x:1,y:2});//pp继承了属性x和y
/**
* 1.null创建一个没有原型的新对象
* 2.不会继承任何的东西
* 3.不包括基础的方法例如:toString() 也就是不能与 "+"一起使用
* 4.传入null创建一个没有原型的新对象
*/
var nullObject = Object.create(null);
/**
*
* @param p 继承原型对象p的属性的新对象 但是不能为null
* @returns {Object}
*
* 注意:inherit()函数并不能完全代替Object.create()
* 不能传入null原型来创建对象,而且不能接受可选的第二个参数
*
* 作用:inherit()函数的作用就是放置库函数无意间恶意修改那些不受你控制的对象
* 特别注意:不是将对象直接传入函数,而是将'继承他的对象'传入函数
* 读取对象的属性时候,实际上读取的是继承来的值,所以修改属性值只会影响继承对象,不会影响原始对象
*/
function inherit(p) {
if(p == null) throw TypeError();//不能为空
if(Object.create) //如果Object.create()存在
return Object.create(p) //直接使用它
var t = typeof p;
if (t !== "object" && t !=="funtion") throw TypeError();
function f() {}//定义一个空构造函数
f.prototype = p;//将其原型属性设置为p
return new f();//使用f()创建p的继承对象
}
var str = {x:"你好屌丝!"};
test_function(inherit(o));//防止对o的意外修改
二、删除属性
//delete只是断开属性和宿主对象的联系,不会去操作属性中的属性
//只能删除自由属性,不能删除继承属性
console.log(delete book.diaosi);
a = {p:{x:1}};
b = a.p;
delete a.p;
console.log(b.x);//执行之后b.x的值依然是1
/**
* 原因:由于已经删除的属性的引用依然存在
* 所以在实际应用中这中不严谨的代码
* 可能造成内存泄漏
* 防止出现此情况的方法:
* 在销毁对象的时候,最好遍历一下属性中的属性,一次删除。
*
*
* */
var obj = {x:1};
console.log(delete obj.x);//删除x属性成功,返回true
console.log(delete obj.toString);//toString是继承过来的,返回true;
console.log(delete 1);//没有意义返回 true
delete Object.prototype;//不能删除,属性是不可配置的
var x = 1;//声明一个全局变量
delete this.x;//不能删除这个属性
function f(){}//声明一个全局函数
delete this.f;//也不能删除全局函数
/**
* var 开头声明的全局变量为不可配置的(配置性为false)不可以使用delete删除属性
* 不添加var的全局变量是可以配置的(配置属性为true)可以使用delete删除属性
* */
三、检测属性
var o = {x:1};
console.log("x" in o);//true "x"是o的属性
console.log("y" in o);//false:"y"不是o得属性
console.log("toString" in o);//true:o继承toString属性
/**
* 1.对象的hasOwnProperty()方法检测给定的名字是否为对象的自有属性,若为继承属性将返回false;
* 2.对象propertyIsEnumerable()为你hasOwnProperty的增强版,只有检测到是自有属性且这个属性的可枚举性
* 为true时它才返回true。某些内置属性是不可枚举的。JavaScript代码创建的属性都是可枚举的
* */
var oneObj = {x:1};
console.log(oneObj.hasOwnProperty("x"));//true:oneObj有一个自有属性
console.log(oneObj.hasOwnProperty("y"));//false:oneObj中不存在属性y
console.log(oneObj.hasOwnProperty("toString"));//false:toString不是继承属性
var testObj = inherit({y:2});
testObj.x = 1;
testObj.propertyIsEnumerable("x");//true :testObj有一个可枚举的自有属性x
testObj.propertyIsEnumerable("y");//false:y是继承过来了
Object.prototype.propertyIsEnumerable("toString");//false: 不可枚举
/**
*判断一个属性是否是undefined
* 两种方法:
* 1.使用 'in'运算符判断
* 2.使用 '!= ='判断
* */
var testDemo = {x:1}
testDemo.x !== undefined;//true:o中有属性x
testDemo.y !==undefined;
var testDemo1 = {x:undefined}//属性被显示赋值undefined
testDemo1.x !== undefined;//false:属性存在,但值为undefined
testDemo1.y !== undefined;//false:属性不存在
console.log("x" in testDemo1);//true:属性存在
console.log("y" in testDemo1);//false:属性不存在
console.log(delete testDemo1.x);//删除属性x
console.log("x" in testDemo1);//false:属性不再存在
四、枚举属性
var bb = {x:1,y:2,z:3};//3个可以枚举的自有属性
bb.propertyIsEnumerable("toString");//false,不可枚举
for (p in bb)//遍历属性
console.log(p);//输出x、y和z,不会输出toString
//许多实用的工具库给Object.prototype添加了新的方法和属性可以被所有对象继承并使用。再次之前是需要用for/in过滤一下
for(p in bb){
if (!bb.hasOwnProperty(p)) continue;//跳过继承的属性
if (typeof bb[p] ==="function") continue;//跳过方法
}
//用来枚举属性的对象工具函数
/**
* 1.把p中的可枚举属性复制到o中,并返回o;
* 2.如果o和p中含有同名属性,则覆盖o中的属性。
* 3.这个函数并不处理getter和setter以及复制属性
* */
function extend(o,p) {
for (prop in p){//遍历p中的所有属性
o[prop] = p[prop];//将属性添加至o中
}
return o;
}
function merge(o,p) {
for(prop in p){ //遍历p中的所有属性
if (o.hasOwnProperty[prop]) continue;//过滤掉已经在o中存在的属性
o[prop] = p[prop];//将属性添加至o中
}
return o;
}
/**
* 如果o中的属性在p中没有同名属性,则从o中删除这个属性返回o
* */
function restrict(o,p){
for (prop in o){//遍历o中的所有属性
if (!(prop in p)) delete o[prop];//如果在p中不存在,则删除
}
return o;
}
/**
* 如果o中的属性在p中存在同名属性,则从o中删除这个属性
* 返回o
* */
function subtract(o,p) {
for (prop in p){//遍历p中的所有属性
delete o[prop];//从o中删除(删除一个不存在的属性不会报错)
}
return o;
}
/**
* 返回一个新对象,这个对象同时拥有o的属性和p的属性
* 如果o和p中有重名属性,使用p中的属性值
* */
function union(o,p) { return extend(extend({},o),p);}
/**
*返回一个新的对象,这个对象拥有同时在o和p中出现的属性
* 很像求o和p的交集,但p中属性的值被忽略
* */
function intersection(o,p) {return restrict(extend({},o),p)}
/**
* 返回一个数组,这个数组中包含的是o中可枚举的自有属性的名字
*
* */
function keys(o) {
if (typeof o !== "object") throw TypeError();//参数必须是对象
var result = [];//将要返回的数组
for (var prop in o){//遍历所有可枚举的属性
if (o.hasOwnProperty(prop));//判断是否是自有属性
result.push(prop);//将属性名添加至数组中
}
return result;//返回这个数组
}
/**
* 枚举属性名称的方法:
* 1.for/in循环
* 1.Object.keys()它将返回一个数组,数组中存放的是属性名称
* 3.Object.getOwnPropertyNames()
* */
五、序列化对象
testbb = {x:1,y:{z:[false,null,""]}};//对象
s =JSON.stringify(testbb);//序列化
p = JSON.parse(s);//还原对象 p是o的深拷贝
stringify()方法为将对象序列化
parse()方法为将还原为对象
六、对象方法
1.toString()
##方法说明:
该对象没有参数,返回一个表示调用该方法的对象值的字符串。一般在需要将对象转换为字符串的时候,JavaScript都会调用这个方法。
2.toLocaleString()
##方法说明:
返回表示这个对象的本地化字符串。Object中默认的toLocaleString()方法并不做任何本地化自身的操作,仅仅调用toString()返回对应值。
3.toJSON()
##方法说明:
需要执行序列化的对象来讲,JSON.stringify()方法会调用toJSON()方法
4.valueOf()
##方法说明:
需要将对象转换为原始值而非字符串的时候才会调用他,尤其是转换为数字的时候。