Javascript的对象

2017-07-26  本文已影响0人  吾木逝水

本文章为笔记,如有错误请指正,万分感谢

JavaScript的对象是属性的无序集合,并且方法(函数)是属性,属性也是对象。

创建对象

function Test(i) {
    this.i = i;
}
Test.prototype.z = 5;
var testObj = new Test(1);
testObj.i;//1
testObj.z;//5

对象的结构

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} 

检测属性是否存在

对象的属性标签

Object.getOwnPropertyDescriptor([对象],[属性名])该方法可以给出属性的标签及其对应值

Object.getOwnPropertyDescriptor({pro : true}, 'pro');
// Object {value: true, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor({pro : true}, 'a'); // undefined
属性标签的值所造成的影响

对象属性的值的读写

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(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}
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
上一篇 下一篇

猜你喜欢

热点阅读