1.属性的查询和设置

①基本语法

这个简单,可以通过点(.)或方括号([])运算来获取属性的值,注意点运算符后的标识符不能是保留字,方括号内的表达式必须返回字符串或返回一个可以转换成字符串的值。

var person = {
name:'jaychou',
height:172,
sayName:function () {
console.log(this.name);
}
};
console.log(person['name']);
console.log(person.height);

往往有一些场景使用方括号比点语法更灵活:

var addr = "";
for(var i=0;i<4;i++){
//读取customer对象的address0,address1,address2,address3属性
addr += customer["address"+i] + '\n';
}

②继承相关的影响

原型链实现了属性的继承。简单说,如果给对象o的属性x赋值,如果o中已经有属性x(自有属性,不是继承来的),那就会改变这个已有属性x的值。如果o中不存在属性x,那么赋值操作给o添加一个新属性x。如果之前o继承了属性x,那么这个继承的属性就创建的同名属性覆盖了。当然,如果属性的writable是false,就会抛出错误。

但是如果这个继承来的属性是具有setter方法的存取器属性,这时会调用setter方法而不是给o创建一个属性x。继承来的属性是只读的,才会在o上创建属性。

③属性访问错误

查询一个不存在的属性不会报错,返回undefined。但如果尝试查询这个不存在的对象它的属性就会报错。

给null和undefined设置属性会报类型错误,严格模式下,设置属性操作只要失败都会抛出类型错误异常。

2.删除属性

delete运算符可以删除对象的属性,注意的是delete只是断开属性和宿主对象的联系,而不会去操作属性中的属性,而且为了避免内存泄漏,在销毁对象的时候,要遍历属性中的属性,依次删除。

delete运算符只能删除自有属性(这是肯定的,否则就影响了整个原型链的对象)。

3.检测属性

判断某个属性是否存在于某个对象中即为检测属性,常用方法:in运算符、hasOwnProperty()、propertyIsEnumerable(),或者之前提及的属性查询也可以。

//in运算符:如果对象的自有属性或继承属性中包含这个属性则返回true:
var o = {x:1};
console.log("x" in o);//true:
console.log("y" in o);//false
console.log("toString" in o);//true:
//hasOwnProperty:检测是否是对象的自有属性
console.log(o.hasOwnProperty("x"));//true
console.log(o.hasOwnProperty("y"));//false
console.log(o.hasOwnProperty("toString"));//false
//propertyIsEnumerable:hasOwnProperty的增强版,是自有属性且可枚举
console.log(o.propertyIsEnumerable("x"));//true
console.log(Object.prototype.propertyIsEnumerable("toString"));//false:不可枚举

其他小办法:!==判断一个属性是否是undefined(缺陷:!==无法区分不存在的属性和存在但值为undefined的属性)

console.log(o.x !== undefined);//true
console.log(o.y !== undefined);
console.log(o.toString !== undefined);//true

4.枚举属性

常用的遍历对象属性的方法(未包括ES6):for-in循环、Object.keys()、Object.getOwnPropertyNames()。

①for-in循环

for-in循环可以遍历对象中所有可枚举的属性(包括自有属性和继承属性):

var o1 = {x:1,y:1,_z:111};
Object.defineProperty(o1,'sayX',{
value:function () {
console.log(this.x);
},
enumerable:false
});
Object.defineProperty(o1,'z',{
get:function () { return this._z; },
set:function (v) { this._z = v; },
enumerable:false
})
//打印x,y,_z,不会打印sayX和z,因为其enumerable为false
for(var p in o1) console.log(p);

②Object.keys()

返回一个数组,这个数组由对象中可枚举的自有属性的名称组成。

//打印["x", "y", "_z"]
console.log(Object.keys(o1));

③Object.getOwnPropertyNames()

和Object.keys()类似,只是它返回对象的所有自有属性的名称,包括不可枚举的。

//打印["x", "y", "_z", "sayX", "z"]
console.log(Object.getOwnPropertyNames(o1));
//打印["constructor", "__defineGetter__", "__defineSetter__",
// "hasOwnProperty", "__lookupGetter__", "__lookupSetter__",
// "isPrototypeOf", "propertyIsEnumerable", "toString",
// "valueOf", "__proto__", "toLocaleString"]
console.log(Object.getOwnPropertyNames(Object.prototype));

④小拓展

给Object.prototype添加一个不可枚举的extend()方法,这个方法将作为参数传入的对象的所有自有属性(包括不可枚举的)一一复制,除了值,也复制属性的所有特性,除非在目标对象中存在同名的属性。

Object.defineProperty(Object.prototype,'extend',{
configurable:true,
enumerable:false,//不可枚举
writable:true,
value:function (o) {
//先获取o的全部自有属性(包括不可枚举的)
var names = Object.getOwnPropertyNames(o);
for(var i=0,len=names.length;i<len;i++){
//如果属性已经存在,跳过
if(names[i] in this) continue;
//获取属性的描述符
var desc = Object.getOwnPropertyDescriptor(o,names[i]);
//创建属性到this
Object.defineProperty(this,names[i],desc);
}
}
}); 使用:
var emptyO = {_z:10};
//除了已有的属性_z,其他o1的所有属性描述符都复制过去了
emptyO.extend(o1);
console.log(emptyO);

js知识梳理2:对象属性的操作的更多相关文章

  1. 页面循环绑定(变量污染问题),js面向对象编程(对象属性增删改查),js字符串操作,js数组操作

    页面循环绑定(变量污染问题) var lis = document.querySelectorAll(".ul li") for ( var i = 0 ; i < lis. ...

  2. js 中对象--属性相关操作

    查询属性: 可以用 对象.属性 来查询属性和属性方法               或者                    对象[“属性”]  来查询属性和属性方法 演示代码: <script ...

  3. js知识梳理5:关于函数的要点梳理(1)

    写在前面 注:这个系列是本人对js知识的一些梳理,其中不少内容来自书籍:Javascript高级程序设计第三版和JavaScript权威指南第六版,感谢它们的作者和译者.有发现什么问题的,欢迎留言指出 ...

  4. js知识梳理6:关于函数的要点梳理(2)(作用域链和闭包)

    写在前面 注:这个系列是本人对js知识的一些梳理,其中不少内容来自书籍:Javascript高级程序设计第三版和JavaScript权威指南第六版,感谢它们的作者和译者.有发现什么问题的,欢迎留言指出 ...

  5. js知识梳理4.继承的模式探究

    写在前面 注:这个系列是本人对js知识的一些梳理,其中不少内容来自书籍:Javascript高级程序设计第三版和JavaScript权威指南第六版,感谢它们的作者和译者.有发现什么问题的,欢迎留言指出 ...

  6. js知识梳理3:创建对象的模式探究

    写在前面 注:这个系列是本人对js知识的一些梳理,其中不少内容来自书籍:Javascript高级程序设计第三版和JavaScript权威指南第六版,感谢它们的作者和译者.有发现什么问题的,欢迎留言指出 ...

  7. 原来JS是这样的 - 对象属性

    引子 在上一篇(原来JS是这样的 (2))刚发布的时候就阅读了那篇文章的人可能会注意到那篇曾用过"JavaScript 中万物皆对象"的说法,而在随后我发现错误后立即更新改掉了这个 ...

  8. js之oop <二> 对象属性

    js中对象属性可以动态添加和删除.删除对象属性用delete关键字. function obj(){ } var oo = new obj(); oo.a = "a"; oo.b ...

  9. JavaScript对象属性赋值操作的逻辑

    对象进行属性赋值操作时,其执行逻辑如下所示: 1. 当前对象中是否有该属性?有,进行赋值操作:没有,进行下一步判断. 2. 对象的原型链中是否有该属性?没有,在当前对象上创建该属性,并赋值:有,进行下 ...

随机推荐

  1. 17-7-26-react-router入门

    完蛋了,上司最近都和颜悦色的,搞得我跑路的决心大大减退,不过还是要跑路.毕竟面向工资编程.今天一天基本都在挑项目的CSS,由于是别人哪里直接copy的,然后css我也直接copy的codepen上的源 ...

  2. 445. Add Two Numbers II【Medium】【两个链表求和】

    You are given two non-empty linked lists representing two non-negative integers. The most significan ...

  3. LCA算法笔记

    LCA,最近公共祖先,实现有多种不同的方法,在树上的问题中有着广泛的应用,比如说树上的最短路之类. LCA的实现方法有很多,比如RMQ.树链剖分等. 今天来讲其中实现较为简单的三种算法: RMQ+时间 ...

  4. WAR/EAR 概念

    In J2EE application, modules are packaged as EAR, JAR and WAR based on their functionality JAR: EJB ...

  5. Web移动应用调试工具——Weinre

          如今人们也越来越习惯在手机上浏览网页,而在手机上这些针对桌面浏览器设计的网页经常惨不忍睹.Web应用开发者需要针对手机进行界面的重新设计,但是手机上并没有称心如意的调试工具(如Firebu ...

  6. Codeforces Round #449 (Div. 2)ABCD

    又掉分了0 0. A. Scarborough Fair time limit per test 2 seconds memory limit per test 256 megabytes input ...

  7. 【树形dp】Rebuilding Roads

    [POJ1947]Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 11934   Accep ...

  8. 【动态规划】POJ1661 Help Jimmy

    Help Jimmy Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11621   Accepted: 3827 Descr ...

  9. Problem D: 零起点学算法83——数组中删数

    #include<stdio.h> int main(void) { int n,i,t,x,flag; while(scanf("%d",&n)!=EOF) ...

  10. [WikiOI "天梯"1281] Xn数列

    题目描述Description 给你6个数,m, a, c, x0, n, g Xn+1 = ( aXn + c ) mod m,求Xn m, a, c, x0, n, g<=10^18 输入描 ...