本文章为笔记,如有错误请指正,万分感谢
JavaScript的对象是属性的无序集合,并且方法(函数)是属性,属性也是对象。
创建对象
- 使用关键字new
语法var obj = new [构造函];
使用该方法创建对象,创建对象的__proto__
属性会指向构造函数的prototype
属性。
例如:
function Test(i) {
this.i = i;
}
Test.prototype.z = 5;
var testObj = new Test(1);
testObj.i;//1
testObj.z;//5
- 直接使用字面量
语法var obj={[属性1],[属性2],...};
- 使用Object.create()方法创建
语法var obj = Object.create([对象]);
使用该方法创建对象,创建对象的__proto__
属性会指向传入的对象。
对象的结构
function foo(){}
foo.prototype.z = 3;
var obj =new foo();
obj.y = 2;
obj.x = 1;
对象的标签
先解释下什么是
"标签"
,在这里指的是固有属性,即对象被创建时就会拥有的属性,下面的属性标签
也是,当属性被创建时就会拥有的属性。这些标签
可以控制对象和属性的状态
——以上是我的理解,好像没有官方文档这样说明
__proto__标签(属性)
__proto__
是原型的意思,其值是对象的原型(是个对象),是个对象都拥有的标签,她是对象的隐性属性,不建议调用,兼容性较差。
class标签
class标签是记录对象的类型。class标签的值是无法直接得到的,我们可以使用Object.prototype.toString.call([对象])
方法来的到其的值
extensible标签
extensible
标签是用于控制对象是否允许添加和删除属性的,默认允许(true)。
Object.isExtensible([对象])
可以检测对象的extensible
标签值
Object.preventExtensions([对象]);
可以阻止对象扩展属性,即extensible
标签值为false
。
var obj = {x : 1, y : 2};
Object.isExtensible(obj); // true
Object.preventExtensions(obj);
Object.isExtensible(obj); // false
obj.z = 1;
obj.z; // undefined, add new property failed
Object.getOwnPropertyDescriptor(obj, 'x');
// Object {value: 1, writable: true, enumerable: true, configurable: true}
Object.preventExtensions([对象]);
方法通常会配合如下方法使用
Object.seal(obj);//该方法可以将对象下所有属性的configurable标签值变为false
Object.getOwnPropertyDescriptor(obj, 'x');
// Object {value: 1, writable: true, enumerable: true, configurable: false}
Object.isSealed(obj); // true
Object.freeze(obj);//该方法可以将对象下所有属性的configurable标签和writable标签的值变为false
Object.getOwnPropertyDescriptor(obj, 'x');
// Object {value: 1, writable: false, enumerable: true, configurable: false}
Object.isFrozen(obj); // true
对象的属性
JavaScript的对象属性是以键值对的的方式存放的,键值对的key必须是字符串类型,如果不是则会被toString操作。
例如
var obj = {a : "a" ,b : 1}
检测属性是否存在
- 使用
in
关键字
语法[属性名] in [对象]
该方法可以检测出对象在原型链上的的属性 - 使用
hasOwnProperty()
方法
语法[对象].hasOwnProperty([属性名])
该方法无法检测出对象在原型链上的的属性
对象的属性标签
Object.getOwnPropertyDescriptor([对象],[属性名])
该方法可以给出属性的标签及其对应值
Object.getOwnPropertyDescriptor({pro : true}, 'pro');
// Object {value: true, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor({pro : true}, 'a'); // undefined
-
writable
标记对象属性是否可写,值为ture/false -
enumerable
标记对象属性是否可枚举或被遍历,值为ture/false -
configurable
标记对象属性的标签是否可配置,对象属性是否可删除,值为ture/false -
value
对象属性的值,赋值的属性的值为undefined(而不是null)。 - get/set
对象属性的值的读写
var obj = {x : 1, y : 2};
使用.
操作符来读写属性值
obj.x; // 1
obj.y = 4;
由于JavaScript的对象属性是以键值对的的方式存放的所以我们可以使用key来读写属性值
obj["y"]; // 2
obj[x] = 3;
如果该对象的属性不属于该对象而属于该对象的原型链上的则只会覆写同名属性而不是改变属性的值
属性的删除
使用delete
关键字删除,成功删除会返回true
否则会返回false
如果对象属性的configurable
标签值为true
或者对象属性不存在又或者对象的属性属于原型链上的而不属于对象本身的都会删除失败
例如
var person = {age : 28, title : 'fe'};
delete person.age; // true
delete person['title']; // true
person.age; // undefined
delete person.age; // true
delete Object.prototype; // false,
var descriptor = Object.getOwnPropertyDescriptor(Object, 'prototype');
descriptor.configurable; // false
如果该属性曾被覆写,则删除该属性后则该属性依然存在并且会还原该属性在原型链上的值;
例如
function person(){}
var person= new person;
person.prototype.misYesr = 0;
person.misYesr = 1;
delete person.misYesr;//true
person.misYesr;//0
属性的枚举
使用for in
来枚举对象的属性key
枚举的内容可能是无序的,也会枚举原型链上可枚举的属性
使用方法:
var o = {x : 1, y : 2, z : 3};
var key;
for (key in o) {
console.log(key); // x, y, z
}
使用propertyIsEnumerable()
方法可以检测该属性是否可被枚举
例如:
o.propertyIsEnumerable('toString'); // false
其他创建对象属性的方法
- 自定义对象属性
语法Object.defineProperty([对象],[属性名],[对象标签及其值(不设定默认为false,value的值默认为undefined)])
例如:
Object.defineProperty(person, 'name', {configurable: true, value : '本拉登'});
当然也可以一次性创建多个
Object.defineProperties(person, {
title : {value : 'fe', enumerable : true},
corp : {value : 'BABA', enumerable : true},
salary : {value : 50000, enumerable : true, writable : true}
});
/**********/
Object.getOwnPropertyDescriptor(person, 'salary');
// Object {value: 50000, writable: true, enumerable: true, configurable: false}
Object.getOwnPropertyDescriptor(person, 'corp');
// Object {value: "BABA", writable: false, enumerable: true, configurable: false}
- 使用
get/set
方法
var man = {
get age() {
return new Date().getFullYear() - 1988;
},
set age(val) {
console.log('Age can\'t be set to ' + val);
}
}
console.log(man.age); // 27
man.age = 100; // Age can't be set to 100
console.log(man.age); // still 27
/**
*我们可以随时使用 Object.defineProperty() 给一个已经存在的对象添加一个 setter。
*/
var o = { a:0 };
Object.defineProperty(o, "b", { set: function (x) { this.a = x / 2; } });
o.b = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
console.log(o.a) // 5
get/set在原型链上的注意事项
function foo() {}
Object.defineProperty(foo.prototype, 'z', {get : function(){return 1;}});
var obj = new foo();
obj.z; // 1
obj.z = 10;
obj.z; // still 1
/*******************/
/**
*只能使用Object.defineProperty()方法来覆盖
*/
Object.defineProperty(obj, 'z', {value : 100, configurable: true});
obj.z; // 100;
delete obj.z;
obj.z; // back to 1