JSObject对象的⽅法总结(ES5与ES6)
ES5中的⽅法
Object 对象的静态⽅法
所谓“静态⽅法”,是指部署在Object对象⾃⾝的⽅法 ---(此句话摘⾃阮⼀峰博客)
Object.keys()⽅法与OwnPropertyNames⽅法很相似,⼀般⽤来遍历对象的(属性名,索引),并返回⼀个数组,该数组成员都是对象⾃⾝的(不是继承的),区别在于Object.keys⽅法只返回可枚举的属性,OwnPropertyNames⽅法还能返回不可枚举的属性名
1.Object.keys
// 定义⼀个 Array 对象
let arr = ["a", "b", "c"];
// 定义⼀个 Object 对象
let obj = { foo: "bar", baz: 42 };
// 定义⼀个类数组对象
let ArrayLike = { 0 : "a", 1 : "b", 2 : "c"};
// 类数组对象, 随机 key 排序
let anObj = { 100: 'a', 2: 'b', 7: 'c' };
/* getFoo 是个不可枚举的属性 */
var my_obj = ate({}, {
getFoo : { value : function () { return this.foo } }
}
);
my_obj.foo = 1;
// 打印结果
console.log(Object.keys(arr)); // ['0', '1', '2']
console.log(Object.keys(obj)); // ["foo","baz"]
console.log(Object.keys(ArrayLike)); // ['0', '1', '2']
console.log(Object.keys(anObj)); // ['2', '7', '100']
console.log(Object.keys(my_obj)); // ['foo']
返回数组中的排序与for..in是⼀致的,区别在于for..in循环还可以枚举原型链上的属性
OwnPropertyNames
// 定义⼀个数组
var arr = ["a", "b", "c"];
// 定义⼀个类数组对象
var obj = { 0: "a", 1: "b", 2: "c"};
/
/定义⼀个不可枚举属性
var my_obj = ate({}, {
getFoo: {
value: function() { return this.foo; },
enumerable: false
}
});
my_obj.foo = 1;
// 打印结果
console.OwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]
console.OwnPropertyNames(obj).sort()); // ["0", "1", "2"]
console.OwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
3.对象属性相关的⽅法
// 看此⽅法之前,我觉得应该先了解⼀下,对象的属性分为哪两种,插句题外话,O(∩_∩)O哈哈~
对象⾥⽬前存在的属性描述符有两种主要形式:数据描述符和存取描述符。
数据描述符:是⼀个具有值的属性,该值可能是可写的,也可能不是可写的。
访问器描述符:是由getter-setter函数对描述的属性。描述符必须是这两种形式之⼀;不能同时是两者。
数据描述符和存取描述符均具有以下可选键值:
configurable:当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默
认为 false。
enumerable:当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认
为 false。
value:该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
writable:当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false。
getter: ⼀个给属性提供 getter 的⽅法,如果没有 getter 则为undefined。该⽅法返回值被⽤作属性值。默认为 undefined。
setter: ⼀个给属性提供 setter 的⽅法,如果没有 setter 则为undefined。该⽅法将接受唯⼀参数,并将该参数的新值分配给该属性。默认为 undefined。
注意:如果⼀个描述符同时设置value,writable,get和set关键字,它将被认为是⼀个数据描述符。如果⼀个描述符同时有value或writable和get或set关键字,将产⽣异常。
记住,这些选项不⼀定是⾃⾝属性,如果是继承来的也要考虑。为了确认保留这些默认值,你可能要在这之前冻结,明确指定所有的选项,或者将 属性指向。
a).OwnPropertyDescriptor( obj, prop) 返回⼀个指定对象上的⾃有属性对应的属性描述(⾃由属性指,直接赋值的属性,不需要从原型上查的属性)
参数:
obj 需要查的⽬标对象
prop ⽬标对象内的属性名称
let o = { get foo() { return17; } };
let d = OwnPropertyDescriptor(o, "foo");
let o1 = { bar: 42 };
let d1 = OwnPropertyDescriptor(o1, "bar");
let o2 = {};
Object.defineProperty(o2, "baz", {
value: 8675309,
writable: false,
enumerable: false
});
let d2 = OwnPropertyDescriptor(o2, "baz");
console.log(d)// {configurable: true, enumerable: true, get: [Function: get foo],set: undefined}
console.log(d1)//{configurable: true, enumerable: true, value: 42, writable: true}
console.log(d2)// {value: 8675309, writable: false, enumerable: false, configurable: false}
注意事项:ES5第⼀个参数不是对象,就会产⽣TypeError, ES2015第⼀个参数不是对象的话,就会被强制转换成对象
b).Object.defineProperty( obj, prop, decriptor) 直接在⼀个对象上定义⼀个新属性,或修改⼀个对象的现有属性,并返回这个对象,默认情况下使⽤此⽅法添加的属性值是不能被修改的
参数:
obj 要在其上定义属性的对象
prop 要定义或修改的属性名称
decriptor 将被定义或修改的属性描述符
var o = {}; // 创建⼀个新对象
// 在对象中添加⼀个属性与数据描述符的⽰例
Object.defineProperty(o, "a", {
value : 37,
writable : true,
enumerable : true,
configurable : true
});
// 对象o拥有了属性a,值为37
/
/ 在对象中添加⼀个属性与存取描述符的⽰例
var bValue;
Object.defineProperty(o, "b", {
get : function(){
return bValue;
},
set : function(newValue){
bValue = newValue;
},
enumerable : true,
configurable : true
});
o.b = 38;
// 对象o拥有了属性b,值为38
// o.b的值现在总是与bValue相同,除⾮重新定义o.b
// 数据描述符和存取描述符不能混合使⽤
Object.defineProperty(o, "conflict", {
value: 0x9f91102,
get: function() {
return0xdeadbeef;
}
});
/
/ TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute(⽆效的属性描述符,不能同时指定访问器和值或可写属性)
c).Object.defineProperties()
d).OwnPropertyNames()
4.控制对象状态的⽅法
a).Object.preventExtensions() 防⽌对象扩展
b).Object.isExtensible() 判断对象是否可扩展
c).Object.seal() 禁⽌对象配置
d).Object.isSealed() 判断⼀个对象是否可配置
e).Object.freeze() 冻结⼀个对象
f).Object.isFrozen() 判断⼀个对象是否被冻结
5.原型链相关⽅法
a).at() 可以指定原型对象和属性,返回⼀个新的对象
b).PrototypeOf() 获取对的的Prototype对象
Object对象的实例⽅法
除了Object对象本⾝的⽅法,还有不少⽅法是部署在Object.prototype对象上的,所有Object的实例对象都继承了这些⽅法。Object实例对象的⽅法,主要有以下六个。(此句摘⾃ --阮⼀峰博客)
a). valueOf()返回当前对象对应的值
b). toString()返回当前对象对应的字符串形式,⽤来判断⼀个值的类型
c). toLocaleString()返回当前对象对应的本地字符串形式
d). hasOwnProperty()判断某个属性是否为当前对象⾃⾝的属性,还是继承⾃原型对象的属性
e). isPrototypeOf()判断当前对象是否为另⼀个对象的原型
f). propertyIsEnumerable()判断某个属性是否可枚举
ES6新增⽅法
(摘⾃阮⼀峰ECMAScript 6 ⼊门 )
1.属性的简洁写法
ES6 允许在对象之中,直接写变量。这时,属性名为变量名, 属性值为变量的值。
属性简写
function f(x, y) {
return {x, y};
}
// 等同于
function f(x, y) {
return {x: x, y: y};
}
f(1, 2) // Object {x: 1, y: 2}
⽅法名简写
const o = {
method() {
return"Hello!";
}
};
// 等同于
const o = {
method: function() {
return"Hello!";
}
};
属性简写与⽅法名简写,例:
let birth = '2000/01/01';
const Person = {
name: '张三',
//等同于birth: birth
birth,
// 等同于hello: function ()...
hello() { console.log('我的名字是', this.name); }
};
CommonJS 模块输出⼀组变量,就⾮常合适使⽤简洁写法
let ms = {};
function getItem (key) {
return key in ms ? ms[key] : null;
}
function setItem (key, value) {
ms[key] = value;
}
// 等同于
getItem: getItem,
setItem: setItem
};
属性的赋值器(setter)和取值器(getter),事实上也是采⽤这种写法const cart = {
_wheels: 4,
get wheels () {
return this._wheels;
},
set wheels (value) {
if (value < this._wheels) {
throw new Error('数值太⼩了!');
}
this._wheels = value;
}
}
2.属性名表达式
⽅法⼀,是直接⽤标识符作为属性名
⽅法⼆,是⽤表达式作为属性名,这时要将表达式放在⽅括号之内。// ⽅法⼀
obj.foo = true;
// ⽅法⼆
obj['a' + 'bc'] = 123;
表达式还可以⽤做⽅法名
let obj = {
['h' + 'ello']() {
return'hi';
}
};
obj.hello() // hi
注意,属性名表达式与简洁表⽰法,不能同时使⽤,会报错。
// 报错
const foo = 'bar';
const bar = 'abc';
const baz = { [foo] };
/
/ 正确
const foo = 'bar';
const baz = { [foo]: 'abc'};
注意,属性名表达式如果是⼀个对象,默认情况下会⾃动将对象转为字符串[object Object],这⼀点要特别⼩⼼。
const keyA = {a: 1};
const keyB = {b: 2};
const myObject = {
[keyA]: 'valueA',
[keyB]: 'valueB'
};
myObject // Object {[object Object]: "valueB"}
上⾯代码中,[keyA]和[keyB]得到的都是[object Object],所以[keyB]会把[keyA]覆盖掉,⽽myObject最后只有⼀个[object Object]属性。
3.⽅法的 name 属性
如果对象的⽅法使⽤了取值函数(getter)和存值函数(setter),则name属性不是在该⽅法上⾯,⽽是该⽅法的属性的描述对象
的get和set属性上⾯,返回值是⽅法名前加上get和set。
4.Object.is() 它⽤来⽐较两个值是否严格相等,与严格⽐较运算符(===)的⾏为基本⼀致
ES5 ⽐较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会⾃动转换数据类型,后者的NaN不等于⾃⾝,以及+0等于-0。JavaScript 缺乏⼀种运算,在所有环境中,只要两个值是⼀样的,它们就应该相等。
Object.is('foo', 'foo')
// true
Object.is({}, {})
// false
不同之处只有两个:⼀是+0不等于-0,⼆是NaN等于⾃⾝。
+0 === -0//true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
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
});
5.Object.assign( target, source, source1 ) ⽅法⽤于对象的合并,将源对象(source)的所有可枚举属性,复制到⽬标对象(target)。拷贝的属性是有限制的,只拷贝源对象的⾃⾝属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)
参数
target ⽬标对象
source 源对象
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
注意,如果⽬标对象与源对象有同名属性,或多个源对象有同名属性,则后⾯的属性会覆盖前⾯的属性。
let obj = {a: 1};
Object.assign(obj, undefined) === obj // true
es6字符串转数组Object.assign(obj, null) === obj /
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论