【JavaScript】【对象】属性和方法的总结概括

构造函数、原型对象、实例对象之间的关系错综复杂,关于它们的属性和方法不少,长得也很像。这里概括出来,方便记忆和查阅。segmentfault

对象属性类型

数据属性

[[Configurable]]:表示可否经过delete删除属性从而从新定义属性、可否修改属性的特性、可否把属性修改成访问器属性。默认值为true
[[Enumerable]]:表示是否可枚举。默认值为true
[[Writable]]:表示可否修改属性的值。默认值为true
[[Value]]:包含属性的数据值,在这里读写属性。默认值为undefined数组

修改属性的特性:Object.defineProperty()Object.defineProperties()。调用这两个方法时,若是不指定,configurableenumerablewritable特性的默认值都是false函数

//定义一个属性
var person = {};
Object.defineProperty(person, 'name', {
    value: 'hiyohoo',
    configurable: true,
    enumerable: true,
    writable: true
});

//定义多个属性
var person = {};
Object.defineProperties(person, {
    name: {
        value: 'hiyohoo'
    },
    age: {
        value: 24,
        configurable: true,
        writable: true
    }
});

获取属性的特性:Object.getOwnPropertyDescriptor()只能用于实例属性,要取得原型属性的描述符,须要在原型上使用该方法。this

var descriptor = Object.getOwnPropertyDescriptor(person, 'age');
alert(descriptor.writable);    //true

访问器属性

[[Configurable]]
[[Enumerable]]
[[Get]]:读取属性时调用该函数。默认值为undefined
[[Set]]:写入属性时调用该函数。默认值为undefinedprototype

访问器属性不能直接定义,必须使用Object.defineProperty()来定义。访问器属性经常使用于改变该属性,其余属性也会变化的状况。code

var book = {
    _year: 2004,    //属性前面的下划线记号经常使用于表示只能经过对象方法访问的属性。
    edition: 1
};
Object.defineProperty(book, 'year', {
    get: function() {
        return this._year;
    },
    set: function(newValue) {
        if (newValue > 2004) {
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
});
book.year = 2016;
console.log(book.edition);    //13

属性和方法

如下的属性和方法均如下面的代码为例:对象

var Person = function(name) {
    this.name = name;
};
Person.prototype.school = 'HNU';
Person.prototype.sayName = function() {
    return this.name;
};

var person = new Person('hiyohoo');

构造函数

prototype指向原型对象,包含全部被实例共享的属性和方法。继承

console.log(Person.prototype);    //Person{}

原型对象

constructor指向构造函数。ip

console.log(Person.prototype.constructor === Person);    //true

isPrototypeOf()判断实例与原型之间的关系。原型链

console.log(Person.prototype.isPrototypeOf(person));    //true

实例对象

constructor沿着原型链找到原型中的constructor属性,最终指向构造函数。

console.log(person.constructor === Person);    //true

__proto__Firefox、Safari、Chrome支持这个属性,指向原型对象。

console.log(person.__proto__ === Person.prototype);    //true

hasOwnProperty()Object中继承而来,判断属性是不是实例的私有属性,而不是继承而来的共享属性。

console.log(person.hasOwnProperty('name'));    //true
console.log(person.hasOwnProperty('school'));    //false

Object

Object.getPrototypeOf() ECMAScript 5中新增的方法,返回实例的原型。

console.log(Object.getPrototypeOf(person));    //Person{}

Object.keys() ECMAScript 5中新增的方法,返回一个包含全部可枚举实例属性的字符串数组。

console.log(Object.keys(person));    //["name"]
console.log(Object.keys(Person.prototype));    //["school", "sayName"]

Object.getOwnPropertyNames()返回全部实例属性,不管是否可枚举。

console.log(Object.getOwnPropertyNames(person));    //["name"]
console.log(Object.getOwnPropertyNames(Person.prototype));    //["constructor", "school", "sayName"]

操做符

delete删除一个configurabletrue的私有属性。

delete person.name;
delete person.school;

console.log(person.name);    //undefined
console.log(person.school);    //HNU

for-in返回全部可以访问到的属性。

for (p in person) {
    console.log(p);    //name school sayName
}

in对象可以访问到属性时返回true

console.log('name' in person);    //true
console.log('sayName' in person);    //true
console.log('age' in person);    //false

同时使用hasOwnProperty()方法和in操做符,能够肯定一个属性是存在于对象中仍是存在于原型中。

function isPrototypeProperty(object, name) {
    if (!(name in object)) {
        return ("Can't find " + '"' + name + '"');
    } else if (object.hasOwnProperty(name)) {
        return false;
    } else {
        return true;
    }
}

console.log(isPrototypeProperty(person, 'name'));    //false
console.log(isPrototypeProperty(person, 'school'));    //true
console.log(isPrototypeProperty(person, 'age'));    //Can't find "age"

instanceof用于判断一个对象是不是某个对象的实例。

console.log(person instanceof Person);    //true
console.log(person instanceof Object);    //true

转载请注明出处:http://www.javashuo.com/article/p-mvigwoal-bh.html

文章不按期更新完善,若是能对你有一点点启发,我将不胜荣幸。

相关文章
相关标签/搜索