javaScript对象的理解

本篇博客仅为自己学习中的一个小总结,总结的目的只是为了更方便记忆和理解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()
##方法说明:  
  需要将对象转换为原始值而非字符串的时候才会调用他,尤其是转换为数字的时候。


你可能感兴趣的:(javaScript对象的理解)