JavaScript Object 静态方法之 Object.create()

240 1 年前
Object.create()是ECMAScript 5又一个能创建对象的方法,从此规范化了原型式继承,作用是创建一个具有指定原型且可选择性地包含指定属性的对象。

创建一个对象的方法有构造函数和对象字面量两种方法,ES5提供的Object.create方法也是一个创建对象的方法,这个方法允许为创建的对象选择原型对象,不需要定义一个构造函数。

Object.create()

Object.create(prototype, descriptors)

prototype:必需。要用作原型的对象。可以为 null。(必须是对象或 null)

descriptors:可选。包含一个或多个属性描述符的 JavaScript 对象。

返回一个具有指定的内部原型且包含指定的属性(如果有)的新对象。

var obj = Object.create(Object.prototype, {
    name: {
        value: "Tom"
    }
})
console.log(obj.name);//Tom
var myMammal = {
    name : 'Herb the Mammal',
    get_name : function () {
        return this.name;
    },
    says : function () {
        return this.saying || '';
    }
}

var myCat = Object.create(myMammal);
myCat.name = 'Henrietta';
myCat.saying = 'meow';
myCat.get_name = function () {
   console.log(this.says + ' ' + this.name + this.says);
}
console.log(myCat.says());//meow

对象属性的类型

Javascript中对象的属性有两种:数据属性访问器属性,在每种属性内部定义了描述这个属性(property)的特性(attribute)。

数据描述符和存取描述符均具有以下可选键值

  • configurable:当且仅当该属性的 configurable 为 true 时,该属性才能够被改变,也能够被删除。默认为 false。
  • enumerable:当且仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false。

数据描述符同时具有以下可选键值

  • value:该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
  • writable:当且仅当该属性的 writable 为 true 时,该属性才能被赋值运算符改变。默认为 false。

存取描述符同时具有以下可选键值

  • get:一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。 -set:一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。

数据属性

数据属性包含一个数据值(value)特性,这个特性可以读取和写入值。数据属性有 4 个描述其行为的特性。

  • [[Configurable]]:表示这个属性能否通过 delete 删除和此属性的特性能否修改。
  • [[Enumerable]]:表示此属性能否被枚举(for-in 循环遍历出来)。
  • [[Writable]]:表示能否修改属性的值。
  • [[Value]]:这个属性读取写入的数据值。属性值默认值为 undefined。
var person = {
 name: "Nicholas"
};
person.age = 28;

像上面例子中的 name 和 age 它们的[[Configurable]]、[[Enumerable]]和[[Writable]]特性都被设置为 true,而[[Value]]特性被设置为指定的值。

访问器属性

访问器属性不包含数据值;它们包含一对 getter 和 setter 函数,访问器属性有如下 4 个特性。

  • [[Configurable]]:表示这个属性能否通过 delete 删除和此属性的特性能否修改。
  • [[Enumerable]]:表示此属性能否被枚举(for-in 循环遍历出来)。
  • [[Get]]:在读取属性时调用的函数。默认值为 undefined。
  • [[Set]]:在写入属性时调用的函数。默认值为 undefined。
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 = 2005;
alert(book.edition); //2

修改属性默认的特性,必须使用 ECMAScript 5 的 Object.defineProperty()方法和Object.defineProperties()方法

var person = {};
Object.defineProperty(person, "name", {
 writable: false,
 value: "Nicholas"
});
alert(person.name); //"Nicholas"
person.name = "Greg";
alert(person.name); //"Nicholas"

创建了一个名为 name 的属性,它的值"Nicholas"是只读的

var person = {};
Object.defineProperty(person, "name", {
 configurable: false,
 value: "Nicholas"
});
alert(person.name); //"Nicholas"
delete person.name;
alert(person.name); //"Nicholas" 
var book = {};
Object.defineProperties(book, {
    _year: {
        value: 2004
    },

    edition: {
        value: 1
    },
    year: {
        get: function(){
            return this._year;
        },
        set: function(newValue){
            if (newValue > 2004) {
                this._year = newValue;
                this.edition += newValue - 2004;
            }
        }
    }
});

把 configurable 设置为 false,表示不能 delete 删除对象属性。

在调用 Object.defineProperty()方法时,如果不指定,configurableenumerablewritable 特性的默认值都是 false。

key: {
        value:"",
        enumerable: true,   //能否被枚举
        writable: true,     //能否被修改
        configurable: true  //属性的特性能否被修改/属性能否删除
   }

注意点:

1、数据属性里value是必须有的,其他三个可以不加,默认取值是false

2、enumerable表示能否被枚举,简单来说,就是for in遍历属性时,是否会遍历到这个属性。true则会,false不会

3、writable表示值赋予之后,能否被修改。true为能,false为不能

4、configurable决定属性的特性能否被修改,属性能否被删除(true能false不能),但不影响对value修改。

5、假如configurable为false,writable为true时,value可以被修改,writable可以被修改。一旦writable修改为false,那么就无法改回来了(因为configurable的原因)

6、修改这三个属性,需要用Object.defineProperty方法或Object.defineProperties来进行,而不能直接通过例如obj.prop.writable这样。

7、一旦定义了取值函数get(或存值函数set),就不能将writable属性设为true,或者同时定义value属性,否则会报错。

8、configurable(可配置性)一个布尔值,决定了是否可以修改属性特性和删除属性。也就是说,configurablefalse时,valuewritableenumerableconfigurable特性都不能被修改了,注意writable只有在false改为true会报错,true改为false是允许的。至于value,只要writableconfigurable有一个为true,些特性就允许改动。另外,configurablefalse时,直接为对象属性赋值,不报错,但不会成功(严格模式会报错)。

function Car(desc){
        this.desc = desc;
        this.color = 'red';
    }
Car.prototype = {
	getInfo:function(){
		return 'A ' + this.color + ' ' + this.desc + '.'; 
	}
}
var car = Object.create(Car.prototype);
car.color = 'blue';
var info = car.getInfo();
console.log(info);//A blue undefined.
var obj = Object.defineProperty({}, 'p', {
  get: function () {
    return 'getter';
  },
  set: function (value) {
    console.log('setter: ' + value);
  }
});

obj.p // "getter"
obj.p = 123 // "setter: 123"
var obj = {
  get p() {
    return 'getter';
  },
  set p(value) {
    console.log('setter: ' + value);
  }
};

注意,取值函数get不能接受参数,存值函数set只能接受一个参数

分类栏目
© 2018邮箱:11407215#qq.comGitHub沪ICP备12039518号-6