JavaScript原生对象详解版
创建对象的3种方式:
对象直接量
<script>
var abc={
name: "xiaoou",
"sex": "女",
eating: function () {
console.log("我会吃饭!");
},
boyFriend: {
name: "carol",
sex: "男"
}
};
</script>
通过new创建对象:
<script>
var o=new Object({a:"1"});
</script>
自定义一个构造函数 自定义对象 – 构造函数方式
<script>
function GirlFriend(){
//this 代表实例之后的对象 gf gf.sex
this.sex = "女";
this.age = 60;
this.cooike = function(){
console.log("我会做饭!");
}
}
//gf 是一个对象 实例化对象
var gf = new GirlFriend();
gf.cooike();
console.log(gf.sex);
var gf1 = new GirlFriend();
gf1.cooike();
//
function C(){
this.a="1";
}
var bnew C();
console.log(b.a);
</script>
访问方式:
var obj = {
"1": 1,
"name 1" : "dddd",
"other": "....."
}
console.log(obj["name 1"]);
// 设置
obj["name 1"] = "今天是高考!";
console.log(obj["name 1"]);
obj.other = "在网吧上网一个晚上! 玩的是传奇!";
console.log(obj.other);
对象的操作:
delete方法:
delet {}.属性名称
delete { }(属性名称)
需要注意,delete只是断开属性和宿主对象的联系,而不会去操作内存中对象的属性的值的存在与否.
检测对象属性
我们经常会检测集合中成员的所属关系——判断某个属性是否存在于某个对象中。可以通过in运算符、hasOwnProperty() 方法来完成这个工作,甚至仅通过属性查询也可以做到这一点。
<script>
var c{
x:"1",
y:"2"
}
c.hasOwenProperty(x)//true
c.hasOwenPorperty(z)//false
</script>
枚举对象属性
除了检测对象的属性是否存在,我们还会经常遍历对象的属性, 通常使用for/in循环遍历for/in循环可以在循环体中遍历对象中所有可枚举的属性(包括自有属性和继承的属性)对象继承的内置方法不可枚举的,但在代码中给对象添加的属性都是可枚举的
<script>
var abc={
x:"1",
y:"2",
z:"3"
}
abc.propertyEnumberable("toString")//=>faslse,不可枚举
for(p in abc){
console.log(p)//逐一输出,不会输出toString
}
</script>
对象属性的特性
属性的特性所服务的对象是JavaScript的解析引擎, 是JavaScript引擎的内部值, 所以作为程序员是无法直接获取到的. 在JavaScript中对象的属性有两种, 分别是数据属性和访问器属性.为了表示特性是内部值,该规范把它们放在了两对儿方括号中,例如[[Enumerable]]
数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有4 个描述其行为的特性。
[Configurable]]:表示能否通过delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
[[Enumerable]]:表示能否通过for-in 循环返回属性。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
[[Writable]]:表示能否修改属性的值。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
[[Value]]:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。这个特性的默认值为undefined。
var point={
x:“1”,
y:“2”
};
比如point对象的x属性, 该属性的特性如下
[[Configurable]]:true
[[Enumerable]]:true
[[Writable]]:true
[[Value]]:0
获取对象特性Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor()只能得到自有属性的描述符。要想获得继承属性的特性,需要遍历原型链
<script>
var o={
x:1,
y:2,
z:3
};
console.log(o.getOwnPropertyDescriptor(o));
</script>
设置对象属性的特性Object.defineProperty()
语法:Object.defineProperty(obj, prop, descriptor)
obj
要定义属性的对象。
prop
要定义或修改的属性的名称或 Symbol 。
descriptor
目标属性所拥有的特性
该方法允许精确地添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,在枚举对象属性时会被枚举到(for…in 或 Object.keys 方法),可以改变这些属性的值,也可以删除这些属性。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty() 添加的属性值是不可修改(immutable)的。
<script>
var o = {}; // 创建一个新对象
// 在对象中添加一个属性与数据描述符的示例
Object.defineProperty(o, "a", {
value : 35,
writable : true,
enumerable : true,
configurable : true
});
// 对象 o 拥有了属性 a,值为 35
// 在对象中添加一个设置了存取描述符属性的示例
var bValue;
Object.defineProperty(o, "b", {
// 使用了方法名称缩写(ES2015 特性)
// 下面两个缩写等价于:
// get : function() { return bValue; },
// set : function(newValue) { bValue = newValue; },
get() { return bValue; },
set(newValue) { bValue = newValue; },
enumerable : true,
configurable : true
});
o.b; // 38
// 对象 o 拥有了属性 b,值为 38
// 现在,除非重新定义 o.b,o.b 的值总是与 bValue 相同
// 数据描述符和存取描述符不能混合使用
Object.defineProperty(o, "conflict", {
value: 0x9f91102,
get() { return 0xdeadbeef; }
});
</script>
Writable 属性
当 writable 属性设置为 false 时,该属性被称为“不可写的”。它不能被重新赋值。
<script>
var o = {}; // 创建一个新对象
Object.defineProperty(o, 'a', {
value: 37,
writable: false
});
console.log(o.a); // logs 37
o.a = 25; // No error thrown
</script>
Enumerable 属性
enumerable 定义了对象的属性是否可以在 for…in 循环和 Object.keys() 中被枚举。
Configurable 属性
configurable 特性表示对象的属性是否可以被删除,以及除 value 和 writable 特性外的其他特性是否可以被修改。
Object.defineProperty()注意事项
var p2={
};
Object.defineProperty(p2,"gs",{
get:function () {
return this.gs;
},
set:function (gs) {
this.gs=gs;
}
})
上述代码,在浏览器运行
alert(p2.gs);后浏览器报错了
Uncaught RangeError: Maximum call stack size exceeded
由于在js中调用的是由于其p2.gs调用的其实是gs.get方法,由于在函数内部this.gs调用的还是gs.get方法,导致其一直在循环调用,最后堆栈报错了
加个下划线表示私有变量。
var p2={
_gs:123
};
Object.defineProperty(p2,“gs”,{
get:function () {
return this._gs;
},
set:function (gs) {
this._gs=gs;
}
})
由于在js中调用的是由于其p2.gs调用的其实是gs.get方法,由于在函数内部this.gs调用的还是gs.get方法,导致其一直在循环调用,最后堆栈报错了
加个下划线表示私有变量。
var p2={
_gs:123
};
Object.defineProperty(p2,“gs”,{
get:function () {
return this._gs;
},
set:function (gs) {
this._gs=gs;
}
})