(1)内置对象:(数组,函数,日期。正则表达式)
(2)宿主对象:是由JavaScript解释器所嵌入的宿主环境定义的。
(3)自定义对象:运行中的JS代码创建的对象。
(4)自由属性:直接再对象中定义的属性
(5)继承属性:对象的原型对象中定义的属性。
首先解释一下
原型:每一个JS对象(null除外)都和另一个对象(原型)相关联。每个新创建出来的对象都会直接或间接继承Object.prototype;例:new Date()同时继承自Date.prototype和Object.prototype,这就是原型链。
三种方法:
(1)对象直接量: var book = {“main tital” : "JavaScript"}; //注意:属性名有空格,横杠和保留字的话需要带引号。
(2)new创建对象:var o = new Object();
(3)var o = Object.create({x:1,y:2})
查询的方法有两种:
(1) “.” ; (2)“[ ]”
(1)是通过标识符(静态)作为索引查找已知的属性;
(2)是通过字符串值(动态)作为索引对属性进行访问。例如作为一个传入对象的函数来说,方法内就应该用[ ]访问
继承:
(1)查询对象o的属性x,如果o中不存在x,那么将会继续再o的原型对象中查询属性x。如果还没有会一直往上查找,找到一个原型是null的对象为止。
(2)属性复制操作前,首先检查原型链,以此判断是否允许赋值操作。(只读的不能进行赋值和修改属性值)。
(3)如果继承的不是只读属性,是可以通过override 也就是通过新创建对象的同名属性进行覆盖(重写),但是不会修改原型链。
(1)delete 只能删除自有属性,不能删除继承属性。(不报错,操作没有任何意义)
例: o = {x:1}; delete o.toString;//没有任何意义
(2)某些不可配置的属性,还有通过变量声明和函数声明创建的全局对象属性是不能删除的。
例: delete Object.prototype;//不可配置,不能删除
var o = 1; function f() {}; 这个也是不能删除的啦 delete o ; delete this.f;
3种方法:
(1)in运算符: “x” in o; //true:是对象的属性;false:不是对象的属性(继承属性也可以,"toString" in o);
(2)hasOwnPreperty()方法:
var o = {x:1};
o.hasOwnProperty("x");//true:是对象的自有属性;false:不是对象的自有属性(只能是自有属性,继承属性不行,"toString" hasOwnProperty o;)
(3)propertyIsEnumerable()方法:是hasOwnProperty()的增强版。不仅要自有还要是可枚举属性的。
(4)除了使用in运算符还可以用“!==”判断是否是undefined: o.x ! == undefined; 和if(o.x)一个道理。
(1)for/in 循环可以再循环体中遍历对象中所有可枚举的属性(包括自有属性和继承属性);
(2)(ES5)Object.keys(),返回一个数组,这个数组由可枚举的自有属性的名称组成。(属性名称组成的数组);
(3)(ES5)Object.getOwnPropertyNames(),返回对象的所有自有属性名称,而不仅仅是可枚举的。
getter和setter定义的属性称作“存取器属性”。
(1)对象属性是由名字,值和一组特性(attrbute)构成的。
可以认为,一个属性包含:1个名称和4个属性;
(1)数据属性,的4个特性分别为:值(value),可写性(writable),可枚举型(enumerable),可配置性(configurable)
(2)存取器属性,不具有值(value)特性和可写性。它的可写性是由setter方法存在与否决定的。因此存取器属性的4个特 性是:读取(get),写入(set),可枚举性,和可配置性。
(3)查看某个对象特定属性的描述方法:Object.getOwnPropertyDescriptor(Object,"x");
(4)想要设置属性的特性:1.Object.defineProperty(Object,"x",{//属性});2.Object.defineProperties({},{})(放多个对象);
// 'use strict'
var o = {};//创建一个空对象;
//添加一个不可枚举的属性数据x,并赋值为1
Object.defineProperty(o,"x",{
value : 1,
writable : true,
enumerable : false,
configurable : true
})
//属性是存在的,但不可枚举
console.log(o.x); // => 1
console.log(Object.keys(o)); //=> []
//现在对属性x做修改,让它变为只读。
// Object.defineProperty(o,"x",{writable : false});
//试图更改这个属性的值
o.x = 20;//操作失败但是不报错,而在严格模式中抛出类型错误异常。
// console.log(o.x);
//属性值依然是可以配置的,因此可以通过这种方式对它进行修改:
Object.defineProperty(o,"x",{
value : 2
})
//现在对属性x做修改,让它变成可修改。
//若之前对属性x的configurable设置为false时候,就不可修改其配置属性(不能设置为true,会抛出类型错误)。
Object.defineProperty(o,"x",{
// configurable : true
})
//现在将x从数据属性修改为存取器属性。
//x属性的configurable一定要为true才能从新设置。
Object.defineProperty(o,"x",{
get:function () {
return 0;
}
})
(5)1.Object.defineProperty(Object,"x",{//属性});2.Object.defineProperties({},{}) 的相关规则
······如果对象是不可扩展的,则可以编辑已有的自有属性,但不能给它添加新属性。
······如果属性是不可配置的,则不能修改它的可配置性和可枚举性。
······如果存取器属性是不可配置的,则不能修改其getter和setter方法,也不能将它转换为数据属性。
······如果数据属性是不可配置的,则不能将它转换为存取器属性。
······如果数据属性是不可配置的,则不能将他的可写性从false修改为true,但可以从true修改为false。
······如果数据属性是不可配置且不可写的,则不能修改它的值。然而可配置但不可写属性的值是可以修改的(实际上是将它标记为可写的,然后修改它的值,最后转换为不可写的)。
(6)复制属性的特性。
/******复制属性的特性******/
/*
*
*给Object.prototype添加一个不可枚举的extend()方法,
*这个方法继承自调用它的对象,将作为参数传入的对象的属性一一复制,
*除了值之外,也复制属性的所有特性,除非在目标对象中存在同名的属性,
*参数对象的所有自有对象(包括不可枚举的属性)也会一一复制。
*
*/
Object.defineProperty(Object.prototype,
"extend", //定义 Object.prototype.extend
{
writable : true,
enumerable : false, //定义为不可枚举的
configurable : true,
value : function (o) { //值就是这个函数
//得到所有的自有属性,包括不可枚举属性。
var names = Object.getOwnPropertyNames(o);
// 遍历它们
for (var i = 0; i < names.length; i++) {
//如果属性已经存在,则跳过
if (names[i] in this) continue;
//获得o中的属性的描述符
var desc = Object.getOwnPropertyDescriptor(o,names[i]);
//用它给this创建一个属性
Object.defineProperty(this,names[i],desc);
}
}
});
关于instanceof运算符:希望左操作数是一个对象,右操作数是标识对象的类
8.1:原型属性
(1)检测一个对象是否是另一个对象的原型(或处于原型链中):isPrototypeOf()
var p = {x:1}
var o = Object.create(p);
p.isPrototypeOf(o) //true
Object.prototype.isPrototypeOf(o) //true
8.2:类属性
(1)对象的类属性(calss attribute)是一个字符串,用以表示对象的类型信息。
//写个函数来获取类。只要能使用toString方法的参数都可以传入,“1”这种数字例外
//只要能使用toString方法的参数都可以传入,“1”这种数字例外
var a = [1,2,3];
function classof(o) {
if(o === null ) return "Null";
if(o === undefined) return "Undefined";
return Object.prototype.toString.call(o).slice(8,-1);
//Object.prototype.toString.call(o) ==>以对象O的方法来调用Object.prototype.toString()方法
}
console.log(classof(a));
console.log(a instanceof Array); //第二种检测是否是数组的方法
8.3:可扩展性
(1)对象的可扩展性用以表示是否可以给对象添加新属性。
(2)对象一旦转换为不可扩展的,就无法将其转化回可扩展的。
(3)相关方法:
preventExtensions(obj)==》无法扩展属性
Object.isExtensible(obj) //true 可扩展
seal(obj)==》无法扩展属性,不可删除属性
Object.isSealed(obj) // true 已封闭
freeze(obj)==》无法扩展属性,不可删除属性,不可修改属性
Object.isFrozen(obj)// true 已冻结
最后都可以通过给原型对象添加属性而增加其属性
引用文章:https://blog.csdn.net/xiaobaixiaye/article/details/79457369
对象序列化是指将对象的状态转换为字符串,也可将字符串还原为对象。
(1)序列化JS对象:JSON.stringify()
(2)还原JS对象:JSON.parse()
(3)函数,RegExp,Error对象,undefined值不能进行序列化和还原
(4)JSON.stringify()只能序列化对象可枚举的自有属性