JavaScript 当中一切皆为对象,这就充分体现出了 Object 对象在 JavaScript 当中的重要性。不过遗憾的是,我对于 Object 上挂载的众多属性和方法并不是很了解。究其原因嘛 ---- 应该是我真的没有对象所造成的吧。正因为 Object 的重要性,所以对于对于 Object 的理解显得有尤为重要。我输出了 Object 所有的属性与方法结合 mdn 进行了一遍扫盲,所以本文算是一篇转文。

理解 JavaScript 中 Object 的属性与方法

这其中有很多方法其实是 Object 的原型上挂载的方法,可以通过 Object.getOwnPropertyNames(Object.prototype) 方法来区分。下面开始正文(点击代码区域可直接运行):

#__defineGetter__

  • 概述: __defineGetter__ 方法可以将一个函数绑定在当前对象的指定属性上,当那个属性的值被读取时,你所绑定的函数就会被调用。该方法目前已经被抛弃,请使用 getter 方法代替。

  • 语法: obj.__defineGetter__(prop, func)

  • 参数:prop 一个字符串,表示指定的属性名。func 一个函数,当 prop 属性的值被读取时自动被调用。

var a = {};  
a.__defineGetter__('alert', function(){ alert('访问属性执行的方法'); });  
a.alert; // alert('访问属性执行的方法');  

#__defineSetter___

  • 概述: __defineSetter__ 方法可以将一个函数绑定在当前对象的指定属性上,当属性被赋值时,所绑定的函数就会被调用。

  • 语法: obj.__defineSetter__(prop, func)

  • 参数:prop 一个字符串,表示指定的属性名。func 一个函数,当试图去为 prop 属性赋值时被调用。通常你要给这个函数指定一个参数:

var b = {};  
b.__defineSetter__('alert', function( val ){ alert( val ); });  
b.alert;                // 无效果  
b.alert = '赋值即触发';   // alert('赋值即触发');  

#__lookupGetter___

  • 概述: __defineSetter__ 方法可以返回当前对象上指定属性的属性读取访问器函数(getter)。

  • 语法: obj.__lookupGetter__(sprop)

  • 参数:sprop 一个字符串,表示指定的属性名。

var c = {get alert(){ return 'get'; }};  
alert( c.__lookupGetter__('alert') ); // function alert(){ return 'get'; }  

#__lookupSetter___

  • 概述: __lookupSetter__ 方法可以返回当前对象上指定属性的属性访问器函数(setter)。

  • 语法: obj.__lookupSetter__(sprop)

  • 参数:sprop 一个字符串,表示指定的属性名。

var d = {set alert(){ return 'set'; }};  
alert( d.__lookupGetter__('alert') ); // function alert(){ return 'set'; }  

#observe

  • 概述: 方法用于异步的监视一个对象的修改。当对象属性被修改时,方法的回调函数会提供一个有序的修改流。

  • 语法: Object.observe(obj, callback)

  • 参数:obj 被监控的对象。callback 当对象被修改时触发的回调函数,其参数为: 一个数组,其中包含的每一个对象代表一个修改行为。每个修改行为的对象包含:

名称 描述
name 被修改的属性名称
object 修改后该对象的值
type 表示对该对象做了何种类型的修改,可能的值为"add", "update", or "delete"
oldValue 对象修改前的值。该值只在"update"与"delete"有效
var obj = {  
  foo: 0,
  bar: 1
};
Object.observe(obj, function(changes) {  
  console.log(changes);
});
obj.baz = 2; // [{name: 'baz', object: <obj>, type: 'add'}]  

#assign

  • 概述: 方法可以把任意多个的源对象所拥有的自身可枚举属性拷贝给目标对象,然后返回目标对象。

  • 语法: Object.assign(target, ...sources)

  • 参数:target 目标对象。sources 任意多个源对象。

var e = {1:1, 2:2, 3:3};  
var f = Object.assign({}, e);  
alert( JSON.stringify( e ) ); // {1:1, 2:2, 3:3}

var g = {get foo(){ alert('呵呵'); }, name: 'tom', age: 18};  
alert( JSON.stringify( Object.assign(e, g) ) ); // {1:1, 2:2, 3:3, name: 'tom', age: 18}  

#bind

  • 概述:方法会创建一个新函数,当这个新函数被调用时,它的this值是传递给bind()的第一个参数, 它的参数是bind()的其他参数和其原本的参数.

  • 语法:fun.bind(thisArg[, arg1[, arg2[, ...]]])

  • 参数:thisArg 当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用new 操作符调用绑定函数时,该参数无效。arg1, arg2, ... 当绑定函数被调用时,这些参数加上绑定函数本身的参数会按照顺序作为原函数运行时的参数。

var call = function(){ alert(this); };  
call.call("测试");  
var bind = foo.bind('测试');  
bind();  

#create

  • 概述:方法创建一个拥有指定原型和若干个指定属性的对象。

  • 语法:Object.create(proto, [ propertiesObject ])

  • 参数:proto 一个对象,作为新创建对象的原型。propertiesObject 可选。该参数对象是一组属性与值,该对象的属性名称将是新创建的对象的属性名称,值是属性描述符(这些属性描述符的结构与Object.defineProperties()的第二个参数一样)。注意:该参数对象不能是 undefined,另外只有该对象中自身拥有的可枚举的属性才有效,也就是说该对象的原型链上属性是无效的。

var h = Object.create(Object.prototype, {  
    size: {
        value: 'large',
        enumerable: true
    },
    shape: {
        value: 'round',
        enumerable: true
    }
});
alert( JSON.stringify( h ) );  

propertiesObject 的四种状态:

名称 描述
value 属性值
writable 可写入
configurable 可配置
enumerable 可枚举
var i = Object.create({}, {  
    name: {
        value: 'tom',
        writable: false,
        enumerable: true
    }
});
i.name = 'jack';  
alert( JSON.stringify( i ) ); // {"name": "tom"}  

#defineProperties

  • 概述:方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。

  • 语法:Object.defineProperty(obj, prop, descriptor)

  • 参数:obj 需要定义属性的对象。prop 需被定义或修改的属性名。descriptor 需被定义或修改的属性的描述符。

var j = {};  
Object.defineProperties(j, {  
  "property1": {
    value: true,
    writable: true
  },
  "property2": {
    value: "Hello",
    writable: false
  }
});
alert( JSON.stringify( j ) );  

#defineProperty

  • 概述:方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。

  • 语法:Object.defineProperty(obj, prop, descriptor)

  • 参数:obj 需要定义属性的对象。prop 需被定义或修改的属性名。descriptor 需被定义或修改的属性的描述符。

var k = {};  
Object.defineProperty(k, "key", { value: "static" });  

#freeze

  • 概述:方法可以冻结一个对象。冻结对象是指那些不能添加新的属性,不能修改已有属性的值,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性的对象。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。

  • 语法:Object.freeze(obj)

  • 参数:obj 将要被冻结的对象。

var l = {age: 18, name: 'tom'};  
Object.freeze( l );  
l.age = 19;  
alert( JSON.stringify( l ) ); // {age: 18, name: 'tom'}  

#getOwnPropertyDescriptor

  • 概述:返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

  • 语法:Object.getOwnPropertyDescriptor(obj, prop)

  • 参数:obj 在该对象上查看属性。prop 一个属性名称,该属性的属性描述符将被返回。

var m = {get name(){ return 'tom'; }};  
var n = Object.getOwnPropertyDescriptor(m, 'name');  
alert( JSON.stringify( n ) ); // {"enumberable": "true", "configurable": "true"}  

#getOwnPropertyNames

  • 概述:方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性)组成的数组。

  • 语法:Object.getOwnPropertyNames(obj)

  • 参数:obj 一个对象,其自身的可枚举和不可枚举属性的名称被返回。

alert( Object.getOwnPropertyNames( Object ) );  

#getPrototypeOf

  • 概述:返回指定对象的原型(也就是该对象内部属性[[Prototype]]的值)。

  • 语法:Object.getPrototypeOf(object)

  • 参数:object 返回该对象的原型。

var o = {};  
var p = Object.create(o);  
alert( Object.getPrototypeOf(p) === o ) // true  

#hasOwnProperty

  • 概述:方法用来判断某个对象是否含有指定的自身属性。

  • 语法:obj.hasOwnProperty(prop)

  • 参数:prop 要检测的属性名称。

var q = new Object();  
q.name = 'tom';  
alert( q.hasOwnProperty('name') );    // true  
alert( q.hasOwnProperty('toString') );// false  

#is

  • 概述:方法用来判断某个对象是否含有指定的自身属性。

  • 语法:Object.is(value1, value2)

  • 参数:value1 需要比较的第一个值。value2 需要比较的第二个值。

alert(Object.is(window, window)); // true  
alert(Object.is(0, -0)); // false  

#isExtensible

  • 概述:方法用来判断某个对象是否含有指定的自身属性。

  • 语法:Object.is(value1, value2)

  • 参数:value1 需要比较的第一个值。value2 需要比较的第二个值。

// 新对象默认是可扩展的.
var r = {};  
alert( Object.isExtensible(r) ); // === true

// ...可以变的不可扩展.
Object.preventExtensions(r);  
alert( Object.isExtensible(r) ); // === false

// 密封对象是不可扩展的.
var s = Object.seal({});  
alert( Object.isExtensible(s) ); // === false

// 冻结对象也是不可扩展.
var t = Object.freeze({});  
alert( Object.isExtensible(t) ); // === false  

#isPrototypeOf

  • 概述:方法测试一个对象是否存在于另一个对象的原型链上。

  • 语法:prototype.isPrototypeOf(object)

  • 参数:prototype 检查该对象是否在参数object的原型链上。object 在该对象的原型链上搜寻。

#keys

  • 概述:方法会返回一个由给定对象的所有可枚举自身属性的属性名组成的数组,数组中属性名的排列顺序和使用for-in循环遍历该对象时返回的顺序一致(两者的主要区别是 for-in 还会遍历出一个对象从其原型链上继承到的可枚举属性)。

  • 语法:Object.keys(obj)

  • 参数:obj 返回该对象的所有可枚举自身属性的属性名。

var u = Object.create({}, { getFoo : { value : function () { return this.foo } } });  
u.foo = 1;  
alert( Object.keys(u) ); // 只弹出foo