JavaScript对象API解密

JavaScript对象API解密

创建对象得俩种方式

var o = new Object()
var o = {} // 推荐使用

该构造器可以接受任何类型得参数,并且会自动识别参数得类型,并选择更合适得构造器来完成相关得操作

var o = new Object('something');
o.constructor; // ƒ String() { [native code] }
var n = new Object(123);
n.constructor; // ƒ Number() { [native code] }

Object构造器得成员

Object.prototype

该属性是所有对象得原型(包括Object对象本身),语言中得其他对象正是通过对该属性上添加东西来实现它们之间得继承关系得,所有要小心使用

var s = new String('smallPig')
Object.prototype.num = 1
console.log(s.num)  //1

Object.prototype得成员

Object.prototype.constructor

该属性只想用来构造该函数对象得构造器,在这里为Object()

Object.prototype.constructor ===  Object // true
var o = new Object()
o.constructor === Object //true
Object.prototype.hasOwnProperty(pop)

该方法仅在目标属性为对象自身属性时返回true,而当该属性是从原型链中继承而来或根本不存在时,返回false

var o = {prop:1};
o.hasOwnProperty('prop'); // true
o.hasOwnProperty('toString'); // false
o.hasOwnProperty('formString'); // false
Object.prototype.isPrototypeOf(obj)

如果目标对象是当前对象得原型,该方法就会返回true,而且,当前对象所在原型上得所有对象都能通过该测试,并不局限与他得直系关系

var s = new String('');
Object.prototype.isPrototypeOf(s); // true
String.prototype.isPrototypeOf(s); // true
Array.prototype.isPrototypeOf(s); // false

ES5中附加得Object属性

Object.defineProperty()

[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty]:

ES5中引入了属性描述符得概念,我们可以通过对所定义的属性有更大的控制权

  • value ==>当视图获取属性时所返回的值
  • writable==>该属性是否可写
  • enumerable==>该属性在for in循环中是否会被枚举
  • configurable==>该属性是否可被删除
  • set==>该属性的更新操作所调用的函数
  • get==>获取属性值所调用的函数

数据描述符(其中属性为:enumerableconfigurablevaluewritable)与存取描述符(其中属性为enumerableconfigurableset()get())之间是有互斥关系的。 在定义了set()get()之后,描述符会认为存取操作已被 定义了,其中再定义valuewritable引起错误

ES3风格的属性定义方式

var person = {}
person.legs = 2

等价的ES5通过数据描述符定义属性的方式

var person = {}
Object.defineProperty(person,'legs',{
	value:2,
	writable:true,
	configurable:true,
	enumerable:true
})

其中,除了value的默认值为undefined以外,其他的默认值都为false.这就意味着,如果想要通过这一方式定义一个可写的属性,必须显示讲它们设为true.或者,我们也可以通过ES5的存储描述符来定义

var person = {}
Object.defineProperty(person, 'legs', {
    set:function(v) {
        return this.value = v;
    },
    get: function(v) {
        return this.value;
    },
    configurable: true,
    enumerable: true
});
person.legs = 2;

这样一来,多了许多可以用来描述属性的代码,如果想要防止别人篡改我们的属性,就必须要用到它们。

var person = {};
Object.defineProperty(person, 'heads', {value: 1});
person.heads = 0; // 0
person.heads; // 1  (改不了)
delete person.heads; // false
person.heads // 1 (删不掉)
Object.defineProperty(obj, prop, descriptor) (ES5)

Vue.js文档:如何追踪变化 把一个普通 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。Object.defineProperty 是仅 ES5 支持,且无法 shim 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器的原因。

Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

Object.defineProperties(obj, props) (ES5)

该方法的作用与defineProperty()基本相同,只不过它可以用来一次定义多个属性。 比如:

var glass = Object.defineProperties({}, {
    'color': {
        value: 'transparent',
        writable: true
    },
    'fullness': {
        value: 'half',
        writable: false
    }
});
glass.fullness; // 'half'

Object.freeze(obj)(ES5)

Object.isFrozen(obj)(ES5)

freeze()方法用于执行一切不受seal()方法限制的属性值变更。Object.freeze() 方法可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。

var deadline = Object.freeze({date: 'yesterday'});
deadline.date = 'tomorrow';
deadline.excuse = 'lame';
deadline.date; // 'yesterday'
deadline.excuse; // undefined
Object.isSealed(deadline); // true;
Object.isFrozen(deadline); // true
Object.getOwnPropertyDescriptor(deadline, 'date');
// {value: "yesterday", writable: false, enumerable: true, configurable: false} (不可配置,不可写)
Object.keys(deadline); // ['date'] (可枚举)

Object.keys(obj)(ES5)

该方法时一种特殊得for in循环。它只返回当前对象得属性(不像for-in),而且这些属性也必须是可枚举的(这点和Object.getOwnPropertyNames()不同,不论是否可以枚举)。返回值是一个字符串数组。

Object.prototype.customProto = 101;
Object.getOwnPropertyNames(Object.prototype);
// [..., "constructor", "toLocaleString", "isPrototypeOf", "customProto"]
Object.keys(Object.prototype); // ['customProto']
var o = {own: 202};
o.customProto; // 101
Object.keys(o); // ['own']

ES6中附加得Object属性

Object.is(value1,value2)(ES6)

该方法用来比较两个值是否严格相等。它与严格比较运算符(===)的行为基本一致。 不同之处只有两个:一是+0不等于-0,而是NaN等于自身。

Object.is('小猪头', '小猪头'); // true
Object.is({},{}); // false
Object.is(+0, -0); // false
+0 === -0; // true
Object.is(NaN, NaN); // true
NaN === NaN; // false

ES5可以通过以下代码部署object.is

Object.defineProperty(Object,'is',{
	value:function(x,y){
		 if (x === y) {
           // 针对+0不等于-0的情况
           return x !== 0 || 1 / x === 1 / y;
        }
        // 针对 NaN的情况
        return x !== x && y !== y;
	},
	configurable: true,
    enumerable: false,
    writable: true
})

Object.assign(target,...sources)(ES6)

该方法用来源对象sources得所有可枚举得属性赋值到目标对象target.它至少需要俩个对象作为参数,第一个参数时目标对象target,后面得参数都是源对象source只要一个参数不是对象,就会抛出TypeError错误

var target = {a: 1};
var source1 = {b: 2};
var source2 = {c: 3};
obj = Object.assign(target, source1, source2);
target; // {a:1,b:2,c:3}
obj; // {a:1,b:2,c:3}
target === obj; // true
// 如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
var source3 = {a:2,b:3,c:4};
Object.assign(target, source3);
target; // {a:2,b:3,c:4}

Object.assign只复制自身属性,不可枚举的属性(enumerablefalse)和继承的属性不会被复制。

Object.assign({b: 'c'},
    Object.defineProperty({}, 'invisible', {
        enumerable: false,
        value: 'hello'
    })
);
// {b: 'c'}

属性名为Symbol值的属性,也会被Object.assign()复制。

Object.assign({a: 'b'}, {[Symbol('c')]: 'd'});
// {a: 'b', Symbol(c): 'd'}

对于嵌套的对象,Object.assign()的处理方法是替换,而不是添加。

Object.assign({a: {b:'c',d:'e'}}, {a:{b:'hello'}});
// {a: {b:'hello'}}

Object.values(obj)(ES8)

Object.values() 方法与Object.keys类似。返回一个给定对象自己的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 ( 区别在于for-in循环枚举原型链中的属性 )。

var obj = {a:1,b:2,c:3};
Object.keys(obj); // ['a','b','c']
Object.values(obj); // [1,2,3]

Object.entries(obj)(ES8)

Object.entries() 方法返回一个给定对象自己的可枚举属性[key,value]对的数组,数组中键值对的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致(区别在于一个for-in循环也枚举原型链中的属性)。

var obj = {a:1,b:2,c:3};
Object.keys(obj); // ['a','b','c']
Object.values(obj); // [1,2,3]
Object.entries(obj); // [['a',1],['b',2],['c',3]]

原文链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值