Object

创建对象

我们有很多种方法创建一个对象,Object.create, Object.assign

Object.create

//字面量
var o = {};
// 等同于
var o = Object.create(Object.prototype) // 字面量创建对象,建立属性
var obj = {name: "hello"};
// 等同于
var obj = Object.create(Object.prototype, {
name: {writable:true, configurable:true, value: "hello" }
}) // 构造器创建对象
var Obj = function() {
this.name = "hello";
}
var obj = new Obj;
// 等同于使用Obj的原型链创建
var obj = Object.create(Obj.prototype, {
name: {writable:true, configurable:true, value: "hello" }
}) obj.__proto__ == Obj.prototype // true

Object.assign

Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象身上,该方法使用源对象的 [ [ Get ] ] 和目标对象的 [ [ Set ] ],所以它会调用相关 getter 和 setter。因此,它分配属性而不是复制或定义新的属性。

语法

Object.assign(target, ...sources)

测试

var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 }; var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }, 注意目标对象自身也会改变。

所以对待浅拷贝我们一般使用这样的形式

var obj = Object.assign({}, o1, o2, o3);

继承属性和不可枚举属性是不能拷贝的

var obj = Object.create({foo: 1}, { // foo 是个继承属性。
bar: {
value: 2 // bar 是个不可枚举属性。
},
baz: {
value: 3,
enumerable: true // baz 是个自身可枚举属性。
}
}); var copy = Object.assign({}, obj);
console.log(copy); // { baz: 3 }

对象属性增删改

属性有几个特性:

  • configurable : 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,也能够被删除。默认为 false。configurable 特性表示对象的属性是否可以被删除,以及除 writable 特性外的其他特性是否可以被修改。
  • enumerable: 当且仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false。
  • value : 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
  • writable: 当且仅当该属性的 writable 为 true 时,该属性才能被赋值运算符改变。默认为 false
  • get:一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined
  • set :一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined

创建属性 Object.defineProperty

var o = {};

Object.defineProperty(o, "a", {
value : 37,
writable : true,
enumerable : true,
configurable : true
}); // 数据描述符和存取描述符不能混合使用
Object.defineProperty(o, "conflict", {
value: 0x9f91102,
get: function() {
return 0xdeadbeef;
}
});

修改属性 Object.defineProperty

如果描述符的 configurable 特性false(即该特性为non-configurable),那么除了 writable 外,其他特性都不能被修改,并且数据和存取描述符也不能相互切换。

var o = {};

Object.defineProperty(o, "a", {
value : 37,
writable : true,
enumerable : true,
configurable : false
}); Object.defineProperty(o, "a", {enumerable : false}) //TypeError: Cannot redefine property: a

设置多个属性 Object.defineProperties

使用 Object.defineProperties 设置多个属性

var obj = {};
Object.defineProperties(obj, {
"property1": {
value: true,
writable: true
},
"property2": {
value: "Hello",
writable: false
}
// 等等.
});

冻结对象 Object.freeze

Object.freeze() 方法可以冻结一个对象,浅冻结,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。

冻结对象的所有自身属性都不可能以任何方式被修改。任何尝试修改该对象的操作都会失败,可能是静默失败,也可能会抛出异常(严格模式中)。

var obj = {name:"hello"}

Object.isFrozen(obj) // false
Object.freeze(obj)
Object.isFrozen(obj) // true obj.name = "hello2" // 严格模式抛错
obj.name = "hello" // freeze

浅冻结

冻结的属性是不能修改的,但是引用的对象是可以修改的。冻结只是冻结对象的属性

var obj = {
name:"hello",
internal: {
name: "internal"
},
internalFunc: function(){
console.log("internal function")
}
} Object.freeze(obj)
obj.internal.name = "after freeze"
obj.internalFunc = function() {
console.log("after freeze")
} console.log(obj.internal.name) // after freeze
obj.internalFunc() // internal function

对象属性遍历

for...in 循环只遍历可枚举属性。像 Array 和 Object 使用内置构造函数所创建的对象都会继承自 Object.prototype 和 String.prototype 的不可枚举属性,例如 String indexOf() 方法或者 Object 的 toString 方法。

var obj = Object.create({
name: "kk",
nick: "kkj"
}, {
age: {writable:true, configurable:true, value: 27, enumerable: true }
}); for(let key in obj){
console.log(key); // age, name, nick
}

hasOwnProperty

可以使用对象的原型链上的hasOwnProperty 方法判断对象是否具有指定的属性作为自身(不继承)属性。

var obj = Object.create({
name: "kk",
nick: "kkj"
}, {
age: {writable:true, configurable:true, value: 27, enumerable: true },
sex: {writable:true, configurable:true, value: 'male', enumerable: false}
}); for(let key in obj){
if(obj.hasOwnProperty(key)){
console.log(key); // age
}
}

这里因为 sex 不可枚举,所以在 for…in 中没有遍历出来,如果

obj.hasOwnProperty("sex") // true

getOwnPropertyNames

返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性)组成的数组。

var obj = Object.create({
name: "kk",
nick: "kkj"
}, {
age: {writable:true, configurable:true, value: 27, enumerable: true },
sex: {writable:true, configurable:true, value: 'male', enumerable: false}
}); Object.getOwnPropertyNames(obj) // ["age", "sex"]

Object.key

返回一个由给定对象的自身 可枚举属性 组成的数组

var obj = Object.create({
name: "kk",
nick: "kkj"
}, {
age: {writable:true, configurable:true, value: 27, enumerable: true },
sex: {writable:true, configurable:true, value: 'male', enumerable: false}
}); Object.keys(obj) // ["age"]

Object.values

返回一个给定对象自己的所有可枚举属性值的数组

var obj = Object.create({
name: "kk",
nick: "kkj"
}, {
age: {writable:true, configurable:true, value: 27, enumerable: true },
sex: {writable:true, configurable:true, value: 'male', enumerable: false}
}); Object.values(obj) // [27]

getOwnPropertyDescriptor

返回指定对象上一个自有属性对应的属性描述符。

var obj = Object.create({
name: "kk",
nick: "kkj"
}, {
age: {writable:true, configurable:true, value: 27, enumerable: true },
sex: {writable:true, configurable:true, value: 'male', enumerable: false}
}); Object.getOwnPropertyDescriptor(obj, "name") // undefined
Object.getOwnPropertyDescriptor(obj, "nick") // undefined
Object.getOwnPropertyDescriptor(obj, "age") // {value: 27, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(obj, "sex") // {value: "male", writable: true, enumerable: false, configurable: true}

getOwnPropertyDescriptors

用来获取一个对象的所有自身属性的描述符。

var obj = Object.create({
name: "kk",
nick: "kkj"
}, {
age: {writable:true, configurable:true, value: 27, enumerable: true },
sex: {writable:true, configurable:true, value: 'male', enumerable: false}
}); Object.getOwnPropertyDescriptors(obj) {
"age": {
"value": 27,
"writable": true,
"enumerable": true,
"configurable": true
},
"sex": {
"value": "male",
"writable": true,
"enumerable": false,
"configurable": true
}
}

原型

getPrototypeOf

返回指定对象的原型

let proto = {};
let obj = Object.create(proto); Object.getPrototypeOf(obj) === proto; // true

isPrototypeOf

isPrototypeOf 和 instanceof operator 是不一样的。在表达式 object instanceof AFunction 中,检测的是AFunction.prototype 是否在object 的原型链中,而不是检测 AFunction 自身。

let proto = {};
let obj = Object.create(proto); proto.isPrototypeOf(obj) // ture

ECMAScript Obejct 属性操作API的更多相关文章

  1. jQuery-1.9.1源码分析系列(八) 属性操作

    jQuery的属性操作主要包括 jQuery.fn.val jQuery.fn.attr jQuery.fn.removeAttr jQuery.fn.prop jQuery.fn.removePro ...

  2. jQuery属性操作

    jQuery 的属性操作的核心部分其实就是对底层 getAttribute().setAttributes()等方法的一系列兼容性处理 ...if ( notxml ) { name = name.t ...

  3. HTML5新增video标签及对应属性、API详解

    知识说明: 比不上很牛的前端开发人员,但自始至终明白“万丈高楼平地起”,基础最重要,初学HTML5,稳固基础第一步,把最基本的整理下来,留下自己学习的痕迹.HTML5新增的video标签,将其属性以及 ...

  4. HTML5文件操作API

    HTML5文件操作API       一.文件操作API 在之前我们操作本地文件都是使用flash.silverlight或者第三方的activeX插件等技术,由于使用了这些技术后就很难进行跨平台.或 ...

  5. Js 常用字符串操作 API

    常用的一些字符串操作 API 整理 1.str.charAt(index).str.charCodeAt(index) - 返回指定位置的字符 / 字符编码(0~65535) index - 必须,表 ...

  6. python 全栈开发,Day54(jQuery的属性操作,使用jQuery操作input的value值,jQuery的文档操作)

    昨日内容回顾 jQuery 宗旨:write less do more 就是js的库,它是javascript的基础上封装的一个框架 在前端中,一个js文件就是一个模块 一.用法: 1.引入包 2.入 ...

  7. SharePoint 使用ECMAscript对象模型来操作Goup与User

    这里总结了关于使用ECMAscript对象模型来操作Goup与User的常用情况,内容如下:     1.取得当前Sharepoint网站所有的Groups     2.获取当前登录用户的Title与 ...

  8. 文件的概念以及VC里的一些文件操作API简介

    文件的基本概念 所谓“文件”是指一组相关数据的有序集合. 这个数据集有一个名称,叫做文件名. 实际上在前面的各章中我们已经多次使用了文件,例如源程序文件.目标文件.可执行文件.库文件 (头文件)等.文 ...

  9. Shader Object及Program操作API

    Shader Object及Program操作API Program:  1. GLuint glCreateProgram( void );//创建 2. void glDeleteProgram( ...

随机推荐

  1. 重装系统后恢复wubi安装的Ubuntu(未实测)

     wubi安装成功,但是后来windows系统重装了,如何修复ubuntu系统的引导?[另外完全可以复制别人的wubi安装的ubuntu,但是要放在同一个盘符下]  将X:/ubuntu/winboo ...

  2. 世纪怎么换算成具体的年份?eg:19世纪60年代=19??年?

    http://zhidao.baidu.com/question/339742625.html&__bd_tkn__=6ab5183c226b84031b08b849ecac35b396039 ...

  3. Linux在中国正在走向没落

    在中国,Linux正在走向没落,一片萧条景象. 在这样的大背景下.居然有人愿意接手中科红旗,令人佩服! 在中国,没有一个关于国际Linux的官方刊物(或站点)反映国际Linux运动的真实声音.Linu ...

  4. Objective-C学习笔记(十九)——对象方法和类方法的相互调用

    事实上在OC的对象方法(减号方法)和类方法(加号方法)并非相互独立的,它们也能够发生千丝万缕的关系,今天我们来研究下它们两者相互调用的问题.该样例还是以People类为基础. (一)对象方法调用类方法 ...

  5. wifi认证Portal开发系列(四):portal协议的java封装

     一.报文封装类 AbstractPortalMsg.java Portal协议数据报文封装类 package org.yoki.edu.common.protocol.portal.msg; imp ...

  6. Python操作Execl 实现自动化填表

    任务简述: 表1是一个简单的数据表,共有110行,25列.第1行是表头,例如“负责人”.“事项”.“期限”等. 第2行——第110行是对应的数据,如“张三”.“搬砖头”.“3天”. 想要做的表(表2) ...

  7. python创建迅雷批量任务

    其实不是真的创建了批量任务,而是用python创建一个文本文件,每行一个要下载的链接,然后打开迅雷,复制文本文件的内容,迅雷监测到剪切板变化,弹出下载全部链接的对话框~~ 实际情况是这样的,因为用py ...

  8. 开启Java远程调试

    在JDK启动时,加入 -Xrunjdwp:transport=dt_socket,address=9900,server=y,suspend=n -Dcom.sun.management.jmxrem ...

  9. SkipList跳表(一)基本原理

    一直听说跳表这个数据结构,说要学一下的,懒癌犯了,是该治治了 为什么选择跳表 目前经常使用的平衡数据结构有:B树.红黑树,AVL树,Splay Tree(这个树好像还没有听说过),Treep(也没有听 ...

  10. Mysql 5.7.18 利用 MySQL proxies_priv(模拟角色)实现类似用户组管理

    利用 MySQL proxies_priv(模拟角色)实现类似用户组管理 角色(Role)可以用来批量管理用户,同一个角色下的用户,拥有相同的权限. MySQL5.7.X以后可以模拟角色(Role)的 ...