Javascript的对象

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

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;
Javascript的对象_第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
Javascript的对象_第2张图片
属性标签的值所造成的影响

对象属性的值的读写

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

你可能感兴趣的:(Javascript的对象)