版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://ligang.blog.csdn.net/article/details/42590565
1. 对象是一种复合值:它将很多值聚合在一起,可以通过名字访问这些值。对象也可以看做是属性的无序集合,每个属性都是一个名/值对。属性名是字符串,因此我们可以把对象看成是从字符串到值的映射。 2. 除了字符串、数字、true、false、null和undefined之外,JavaScript中的值都是对象。 3. 对象时可变的,问题通过引用而非值来操作对象。
每个对象拥有三个相关的对象特性: 1. 对象的原型(prototype)指向另外一个对象,本对象的属性继承自它的原型对象; 2. 对象的类(class)是一个标识对象类型的字符串; 3. 对象的扩展标记(extensible flag)指明了是否可以向该对象添加新属性。 属性特性: 1. 可写(writable attribute),表明是否可以设置该属性的值; 2. 可枚举(enumerable attribute),表明是否可以通过for/in循环返回该属性; 3. 可配置(configurable attribute),表明是否可以删除或修改该属性。
可以通过对象直接量、关键字new和(ECMAScript 5中的)Object.create()函数来创建对象。 1. 对象直接量
var book = {
'main title':"javascript", //属性名字里有空格,必须用字符串表示
'sub-title':'The Definitive Guide', //属性名字里有连字符,必须用字符串表示
'for':'all audiences', //属性名字是保留字,必须用字符串表示
author:{
firstname:'lee',
surname:'gang'
}
};
如果在一个重复调用的函数中的循环体内使用了对象直接量,它将创建很多新对象,并且每次创建的新对象的属性值也有可能不同。 2. 通过new创建对象
var obj = new Object(); //创建一个空对象,和{}一样
3. Object.create()
var obj = Object.create({x:1,y:2}); //obj继承了属性x和y
其创建一个对象,其中第一个参数是这个对象的原型;第二个可选参数,用以对对象的属性进行进一步描述
1. 没有原型的对象为数不多,Object.prototype就是其中之一。它不继承任何属性。 2. new Date() 创建的Date对象的属性继承自Date.prototype,Date.prototype的属性继承自Object.prototype。这一系列链接的原型对象就是所谓的“原型链”。 3. 通过原型继承创建一个新对象:
function inherit(p){
if(p == null) throw TypeError();
if(Object.create)
return Object.create(p);
var t = typeof p;
if(t !== "object" && t !== "function") throw TypeError();
function(){};
f.prototype = p;
return new f();
}
[]运算符,它使用字符串值(字符串值是动态的,可以在运行时更改) .运算符,它使用标识符(标识符是静态的,必须写死在程序中)
var a = {x:1,y:2};
for(item in a){
a.item = 3;
}
// 结果:a.x = 1 a.y = 2
var a = {x:1,y:2};
for(item in a){
a[item] = 3;
}
// 结果:a.x = 3 a.y = 3
属性赋值操作首先检查原型链,以此判断是否允许赋值操作。如果允许属性赋值操作,它也总是在原始对象上创建属性或对已有的属性赋值,而不会去修改原型链。在JavaScript中,只有在查询属性是才会体会到继承的存在,而设置属性则和继承无关。
// 一种更简练的常用方法,获取sub-title的length
var len = book && book.sub-title && book.sub-title.length;
delete只是断开属性和宿主对象的联系,而不会去操作属性中的属性。 delete运算符只能删除自有属性,不能删除继承属性(要删除继承属性必须从定义这个属性的原型对象上删除它,而且这会影响到所有继承自这个原型的对象)
a = {p:{x:1}};
b = a.p;
delete p;
console.log(b.a); //仍然是1
所以在销毁对象的时候,要遍历属性中的属性,一次删除。
a = {p:{x:1}};
delete a.p.x;
delete a.p;
某些内置对象是不可配置的,比如通过变量声明和函数声明创建的全局对象的属性:
delete Object.prototype;
var x = 1;
delete this.x;
function f(){}
delete this.f;
上述三种情况均不能被删除
Javascript对象可以看做属性的集合。 1. in运算符,如果对象的自有属性或继承属性中包含这个属性则返回true。 2. hasOwnPrototype()方法,用来检测给定的名字是否是对象的自有属性。 3. propertyIsEnumerable(),只有检测到是自有属性且这个属性的可枚举性为true才返回true。
null == undefined //true
null === undefined //false
for-in循环可以在循环体中遍历对象中所有可枚举的属性(包括自身属性和继承属性) 对象.propertyIsEnumerable("属性") //检测是否可枚举
1. 由getter和setter定义的属性称做“存取器属性”,其不同于“数据属性”,数据属性只有一个简单的值。 2. 存储器属性4个特性分别是:读取(get)、写入(set)、可枚举性(enumerable)和可配置性(configurable)。 3. 数据属性的4个特性分别是:值(value)、可写性(writable)、可枚举性(enumerable)和可配置性(configurable)。 4. Object.getOwnPropertyDescriptor()只能得到自有属性的描述符,要想获得继承属性的特性,需要遍历原型链,获取原型的方法Object.getPrototypeOf()。
设置属性的特性(不能修改继承属性):
var o = {};
Object.defineProperty(o,"x",{value:1,
writable:true,
enumerable:false,
configurable:true});
1. 原型属性 Object.getPrototypeOf()可以查询它的原型;检查一个对象是否是另一个对象的原型,可使用isPrototypeOf()。 Mozilla实现的JavaScript对外暴漏了一个专门命名为__proto_的属性,用以直接查询/设置对象的原型。 2. 类属性 默认的toString()方法,返回[object class],然后提取第8个到倒数第二个位置之间的字符。但是大部分对象会重写toString()方法,所以建议使用Object.prototype.toString().call() 3. 可扩展性 Object.isExtensible()判断对象是否可扩展,Object.preventExtensions()转换为不可扩展的。 一旦将对象转换为不可扩展的,将无法再将其转换回可扩展的了。 需要注意,Object.preventExtensions()只影响到对象本身的可扩展性,如果给一个不可扩展的对象的原型添加属性,这个不可扩展的对象同样会继承这些新属性;至此提供了一种从“可扩展”->“不可扩展”之后的思路!! Object.preventExtensions()[不可扩展] -> Object.seal()[不可扩展、自有属性不可配置] -> Object.freeze()[不可扩展、自有属性不可配置、数据属性设置为只读]
对象序列化(serialization)是指将对象的状态转换为字符串,也可将字符串还原为对象。 JSON.stringify()[只能序列化可枚举自有属性]和JSON.parse()