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()
##方法说明:  
  需要将对象转换为原始值而非字符串的时候才会调用他,尤其是转换为数字的时候。


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

推荐阅读更多精彩内容

  • 原文地址在我的博客, 转载请注明出处,谢谢! 标签: [es5对象、原型, 原型链, 继承] 注意(这篇文章特别长...
    莫凡_Tcg阅读 181评论 0 1
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,544评论 25 707
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,482评论 6 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,087评论 18 139
  • 今天起了个早床,开车从武昌跑到江夏,一路堵堵堵,就为了看个所谓的油纸伞,哎 还没入园就看到…… 这……有点恐怖 老...
    九号咖啡屋阅读 476评论 3 7