你的浏览器不支持canvas

Enjoy life!

javasript - Object

Date: Author: JM

本文章采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。

其他链接:

以下内容全部源于: 《JavaScript高级程序设计(第3版)》

一、Object 的创建方法

1.1 new操作符

var obj1 = new Object();

// 括号可以省略,但不推荐
var obj2 = new Object;

1.2 对象字面量表示法

var obj = {};

二、读写对象属性

var person = {
    'age': 19
};

// 对象属性的读取
// 第一种:方括号
console.log(person['age']);

// 第二种:点表示
console.log(person.age);

// 对象属性的设置
// 第一种:方括号
person['age'] = 20;

// 第二种:点表示
person.age = 20;

如果属性名中包含会导致语法错误的字符,或者属性名使用的是关键字或保留字,也可以使用方括 号表示法。 person["first name"] = "Nicholas";

三、对象实例属性和方法

Object 的每个实例都具有下列属性。

  • 1.constructor
    • 保存用于创建当前对象的函数。
    var person = new Object();
    console.log(person.constructor); // function Object(){}

Object 的每个实例都具有下列方法。(propertyName参数须以字符串形式指定。)

  • 1.hasOwnProperty(propertyName)
    • 用于检查给定的属性是否在当前对象实例中(不是在实例的原型中)。
var person = {
    name: 'baby',
    sex: 'girl'
};
console.log(person.hasOwnProperty('sex')); // true
  • 2.isPrototypeOf(Object)
    • 检查传入的对象是否是传入对象的原型
  • 3.propertyIsEnumerable(propertyName)
    • 检查给定的属性是否能用for-in枚举。

  • 4.toLocaleString()
    • 返回对象的字符串表示,该字符串与执行环境的地区对应
  • 5.toString()
    • 返回对象的字符串表示
  • 6.valueOf
    • 返回对象的字符串、数值、布尔值表示。通常与 toString()方法的返回值相同。

四、属性类型

ECMAScript 中有两种属性:数据属性和访问器属性。

4.1 数据属性

数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有 4 个描述其行为的特性。

  • 1.[[Configurable]]
    • 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。
    • 默认值:true
  • 2.[[Enumerable]]
    • 表示能否通过for-in循环返回属性。
    • 默认值:true
  • 3.[[Writable]]
    • 表示能否修改属性的值。
    • 默认值:true
  • 4.[[Value]]
    • 包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。
    • 默认值:undefined
var person = {
    name: "Nicholas"
}; 
// [[Configurable]]、[[Enumerable]]、[[Writable]]特性都被设置为 true,
// 而[[Value]]特性被设置为指定的值:Nicholas

4.2 访问器属性

  • 1.[[Configurable]]
    • 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。
    • 默认值:true
  • 2.[[Enumerable]]
    • 表示能否通过for-in循环返回属性。
    • 默认值:true
  • 3.[[Get]]
    • 在读取属性时调用的函数。
    • 默认值:undefined
  • 4.[[Set]]
    • 在写入属性时调用的函数。
    • 默认值:undefined

五、定义单个属性:Object.defineProperty()

5.1 基本定义

  • Object.defineProperty(obj, attrName, descriptor):修改属性默认的特性。
    • obj:属性所在的对象
    • attrName:属性的名字
    • descriptor:描述符对象
      • 描述符对象的属性必须是:configurableenumerablewritablevalue
      • 设置其中的一或多个值,可以修改对应的特性值。
  • 支持浏览器:IE9+(IE8 只是部分实现)、Firefox 4+、Safari 5+、Opera 12+ 和 Chrome 。

    5.2 数据属性的有关实例

  • 可读不可修改
    • 这个属性的值是不可修改的,如果尝试为它指定新值,则在非严格模式下,赋值操作将被忽略;在严格模式下,赋值操作将会导 致抛出错误。
var person = {};
Object.defineProperty(person, 'name', {
    writable: false,
    value: "jm"
});
console.log(person.name); // "jm"
person.name = "bb";
console.log(person.name); // "jm"
  • 不可配置
    • configurable 设置为 false,表示不能从对象中删除属性。
    • 如果对这个属性调用 delete,则在非严格模式下什么也不会发生,而在严格模式下会导致错误。
    • 一旦把属性定义为不可配置的,就不能再把它变回可配置了
var person = {};
Object.defineProperty(person, 'name', {
    configurable: false,
    value: "jm"
});
console.log(person.name); // "jm"
person.name = "bb";
console.log(person.name); // "jm"

// 再调用 Object.defineProperty()方法修改除 writable 之外的特性,都会导致错误:

//抛出错误
Object.defineProperty(person, "name", {
 configurable: true,
 value: "Nicholas"
}); 

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

5.3 访问器属性的有关实例

  • 访问器属性不能直接定义,必须使用 Object.defineProperty()来定义。
var book  = {
    _year: 2004,
    editor: 1
};

Object.defineProperty(book, "year", {
    get: function() {
        return this._year;
    },
    set: function(newValue) {
      if (newValue > 2004) {
         this._year = newValue;
         this.editor += newValue - 2004; 
      }
    }
})

booke.year = 2005;
console.log(book.editor); // 2
  • 在严格模式下,尝试写入只指定了 getter 函数的属性会抛出错误。只指定 setter 函数的属性也 不能读,否则在非严格模式下会返回 undefined,而在严格模式下会抛出错误。

5.4 defineGetter()和__defineSetter__()

  • Object.defineProperty()前要创建访问器属性,一般都使用两个非标准的方法: __defineGetter__()__defineSetter__()
var book = {
 _year: 2004,
 edition: 1
};
//定义访问器的旧有方法
book.__defineGetter__("year", function(){
 return this._year;
});
book.__defineSetter__("year", function(newValue){
 if (newValue > 2004) {
 this._year = newValue;
 this.edition += newValue - 2004;
 }
});
book.year = 2005;
alert(book.edition); //2 

在不支持 Object.defineProperty() 方法的浏览器中不能修改 [[Configurable]][[Enumerable]]

六、 定义多个属性:Object.defineProperties()

  • Object.defineProperties(obj1, desObj)
    • obj1:要添加和修改其属性的对象
    • desObj:第二个对象的属性与第一个对象中要添加或修改的属性一一对应。
  • 支持浏览器:IE9+、Firefox 4+、Safari 5+、Opera 12+和Chrome。
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;
             }
         }
    }
}); 
  • 以上代码在 book 对象上定义了两个数据属性(_yearedition)和一个访问器属性(year)。 最终的对象与上一节中定义的对象相同。唯一的区别是这里的属性都是在同一时间创建的。

七、读取属性的特性 Object.getOwnPropertyDescriptor()

  • Object.getOwnPropertyDescriptor(obj,descriptorName)
    • obj:属性所在的对象
    • descriptorName:要读取其描述符的属性名称
  • 返回值是一个对象
    • 如果是访问器属性,这个对象的属性有 configurableenumerablegetset
    • 如果是数据属性,这个对象的属性有 configurableenumerablewritablevalue
  • 支持这个方法的浏览器有 IE9+、Firefox 4+、Safari 5+、Opera 12+和 Chrome。
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;
             }
         }
     }
});
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
alert(descriptor.value); //2004
alert(descriptor.configurable); //false 
alert(typeof descriptor.get); //"undefined"

var descriptor = Object.getOwnPropertyDescriptor(book, "year");
alert(descriptor.value); //undefined
alert(descriptor.enumerable); //false
alert(typeof descriptor.get); //"function" 

在 JavaScript 中,可以针对任何对象——包括 DOMBOM 对象,使用 Object.getOwnPropertyDescriptor()方法。

八、Object.create()

  • Object.create(newObj, obj)
    • newObj:用作新对象原型的对象
    • obj:(可选的)一个为新对象定义额外属性的对象
  • 在传入一个参数的情况下,Object.create()object()方法的行为相同。
  • 支持 Object.create()方法的浏览器有 IE9+、Firefox 4+、Safari 5+、Opera 12+和 Chrome。
var person = {
    name: 'jm',
    friends: ['aa', 'bb', 'cc']
}

var anPerson = Object.create(person);
anPerson.name = "Greg";
anPerson.friends.push("Rob");

var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");

console.log(person.friends); //"aa,bb,cc,Rob,Barbie" 
console.log(person.name, anPerson.name); // jm, Greg

// 第二个参数
var anotherPerson = Object.create(person, {
 name: {
 value: "Greg"
 }
});

alert(anotherPerson.name); //"Greg" 
  • 分析上述代码:
    • anPersonyetAnotherPerson其实是person这个对象的副本。
      • 对于基本类型的值是不会改变的,例如:name
      • 对于引用类型,如:数组,一变则全变。例如:friends

对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。