0
点赞
收藏
分享

微信扫一扫

ES6 对象新增方法

 

 

先回顾下ES5中常用对象方法:

Object的静态方法,所为静态方法是指部署在Object对象自身的方法。

Object . keys

参数是对象,返回一个数组;该数组的成员是该对象自身的(而不是继承的)所有属性名。(可枚举的属性)

eg:

var obj = {name:"lxc",age:25}
Object.keys(obj)//["name","age"]

Object.values

参数是对象,返回一个数组;该数组的成员是该对象自身的(而不是继承的)所有属性值。(可枚举的属性)

var obj = {name:"lxc",age:25}
Object.keys(obj)//["name","age"]

 

Object.getOwnPropertyNames

——也用来遍历对象的属性,接受一个对象作为参数,返回一个数组,包含了该对象自身的所有的属性名。

eg:

var obj = {name:"lxc",age:25}
Object.getOwnPropertyNames(obj)//["name","age"]

两者区别在于,getOwnPropertyNames方法可返回不可枚举的属性名:

eg:数组的length方法是不可枚举的,所以出现在getOwnPropertyNames中

var arr = ["lv","xc"];
Object.keys(arr);//["0","1"]
Object.getOwnPropertyNames(arr);//["0","1","length"]

由于js中没有提供计算对象属性个数的方法,所以可以用这两个方法来代替:

var obj = {name:"lxc",age:25}
Object.getOwnPropertyNames(obj).length;//2
Object.keys(obj).length;//2

Object的实例方法,它是定义在对象的原型上边的,所有的Object实例方法都继承了这些方法。

Object实例对象的方法主要有以下六个:

Object.prototype.valueOf()

——返回当前对象对应的值,默认情况返回对象本身;它的主要用途是,js自动类型转换会默认调用这个方法:

eg:

var obj = new Object();
obj + 1//"[object Object]1"

上边代码将对象obj与数字1相加,这时js就会默认调用valueOf()方法,求出obj的值,再与1相加。。。

我们也可以自定义valueOf方法,来覆盖Object.prototype.valueOf:

var obj = new Object();
obj.valueOf = function(){
return 1;
}
obj +1 //2

Object.prototype.toString()

——返回一个对象的字符串形式,默认情况下返回该类型字符串。(简单说就是把对象转字符串)

var obj1 = new Object();
var obj2 = {name:"lxc"};
var arr = [1,2];
var str = "123";
var num = 1;
var date = new Date();
obj1.toString()//"[object Object]"
obj2.toString()//"[object Object]"
arr.toString()//"1,2"
str.toString()//"123"
num.toString()//"1"
date.toString()//"Sun Jun 23 2019 19:57:28 GMT+0800 (中国标准时间)"

上边代码中,数组、字符串、Date对象调用toString()方法,并不会返回[object,Object],因为它们都自定义了toString方法,覆盖了原始的方法。

在开发中toString()的实际应用——判断数据类型:

Object.prototype.toString()方法返回对象的该类型的字符串,因此可以用来判断一个值的类型。

eg:

var obj = {};
obj.toString()//"[object Object]"

上边代码调用空对象的toString方法,结果返回一个字符串,第二个Object表示该值的构造函数,这是一个十分有用的判断数据类型的方法。

由于实例对象可能会自定义toString()方法,覆盖掉Object.prototype.toString()方法,所以,为了得到类型字符串,最好直接使用Object.prototype.toString()方法,通过函数call方法,可以在任意值上调用这个方法,帮助我么判断数据的类型。

Object.prototype.toString.call(value)

上边代码的意思是对value这个值调用Object.prototype.toString()方法;

不同的数据类型的Object.prototype.toString()方法返回的值如下:

数值:返回[ object Number ]

字符串:返回[ object String ]

布尔值:返回[ object Boolean]

undefined:返回[ object Undefined]

null:返回[ object Null ]

数组:返回[ object Array]

arguments:返回[ object Arguments]

函数:返回[ object Function]

Error:返回[ object Error]

Date:返回[ object Date]

RegExp:返回[ object RegExp]

其他对象:返回[ object Object ]

也就是说,通过Object.prototype.toString()方法会看出一个值到底是什么类型:

Object.prototype.toString.call(1)//"[object Number]"
Object.prototype.toString.call([])//"[object Array]"
Object.prototype.toString.call("")//"[object String]"
Object.prototype.toString.call({})//"[object Object]"
Object.prototype.toString.call(true)//"[object Boolean]"
Object.prototype.toString.call(undefined)//"[object Undefined]"
Object.prototype.toString.call(null)//"[object Null]"
Object.prototype.toString.call(Math)//"[object Math]"

利用这个特性,可以写出一个比typeof运算符更准确的类型判断函数:(可对比 jQuery中$.type()方法)

var paramType = function(param){
var _type = Object.prototype.toString.call(param);
return _type.match(/\[object (.*?)\]/)[1].toLowerCase();
};
paramType([])//"array"
paramType(1)//"number"
paramType(null)//"null"
paramType({})//"object"

Object.prototype.toLocaleString()

——方法与toSting的返回结果相同,也是返回一个值的字符串形式。唯一不同的是toLocaleString()返回的是本地字符串形式:

eg:

var date = new Date();
console.log(date.toLocaleString())//2019/6/23 下午9:04:18
console.log(date.toString())//Sun Jun 23 2019 21:04:18 GMT+0800 (中国标准时间)

Object.prototype.hasOwnProperty()

——方法接受一个字符串作为参数,返回一个布尔值,表示该实例对象自身是否有改属性。(我们知道for  in是遍历对象所有可枚举的属性,原型上的或继承的属性也能遍历出来,如果只想要对象自身属性,可利用hasOwnProperty()判断下是否是自身属性。。。)

eg:

var obj = {
name:"lxc"
}

Object.prototype.age = "20";

for(key in obj){
//属性key是否是obj对象自身属性,是返回true,否返回false
if(obj.hasOwnProperty(key)){
console.log(key)//name
}
}

下边我们来看下ES6中对象的扩展功能:

1、对象属性的简写:

// ES5
function a(id){
return {
id:id
}
}
//ES6
const a = id=>{
return {
id
}
}
console.log(a(1))

2、对象方法的简写:

// ES5
var obj = {
name:function(){
alert("lxc");
}
}
//ES6
let boj = {
name(){
alert("lxc");
}
}

3、属性名可计算:

属性名可以传入变量或者常量,而不只是一个固定的字符串。

let a = 1;
let b = {
[`name${a}`]:"lvxingchen"
}
console.log(b)//{name1:"lvxingchen"}
console.log(b[`name${a}`])//"lvxingchen"

对象新增方法:

1、Object.is : 比较两个值是否相等,解决了js中 == 或者===带来的异常情况;

异常情况:

console.log(NaN == NaN)//false
console.log(5 == "5")//true

新增的Object.is解决了此问题:

console.log(Object.is(NaN,NaN))//true
console.log(Object.is(5,"5"))//false

2、Object.assign( param1 , param2  , ··· ··· ) : 实现拷贝一个对象给另外一个对象,返回一个新对象。(此方法是浅拷贝,将param2对象中可枚举的属性和方法拷贝到param1中,且会改变对象param1)

let a = {
name:"lx",
age:20
};
let b = {
say:"haha",
age:21
};
Object.assign(a,b);
console.log(a)//{name:"lx",age:21,say:"haha"}

 

3、ES6严格模式下,对象中出现key相同的情况,后边的key会覆盖掉前面相同的key。

ES6中对象的属性:

1、属性可简写

function f(x,y){
return {x,y};
}
// 等同于
function f(x,y){
return {
x:x,
y:y
}
}
console.log(f(1,2))//{x:1,y:2}

2、方法也可以简写:

const foo = {
say(){
console.log("hehe");
}
}
// 等同于
const foo = {
say:function(){
console.log("hehe");
}
}

模块的输出:

function a (){}
function b (){}
function c (){}
module.exports = { a, b, c };
// 等同于
module.exports = {
a:a,
b:b,
c:c
}

3、属性表达式:

const obj = {
['a' + 'b']: '123'
}
console.log(obj) // {ab: "123"}
let obj = {
["h" + "ello"](){
console.log("哈哈")
}
}

4、属性的可枚举性和遍历:

     可枚举性

   对象的每一个属性有一个描述对象(Descriptor),用来控制改属性的行为。

Object.getOwnPropertyDesciptor方法可以获取该属性的描述对象。

let obj = {
name:"lxc"
}
console.log( Object.getOwnPropertyDescriptor(obj,"name") );
// {
// value: "lxc",
// writable: true,
// enumerable: true,
// configurable: true
// }

描述对象的enumerable为false的属性,成为“可枚举性”,如果该属性为false,就表示某些操作会忽略当前属性。

    目前,有四个操作会忽略enumerable为false的属性。

    —— for ··· in循环:之遍历对象自身的和继承的可枚举的属性。

    —— Object.keys() : 返回对象自身的所有可枚举的属性键名。

    —— JSON.stringify() : 值串行化对象自身的可枚举的属性。

    —— Object.assign() : 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。 

上边四个方法,只有for  in 会返回继承的属性,其他三个方法都会忽略继承的属性,对处理对象自身属性。

另外,ES6规定,所有的Class的原型的方法是不可枚举的。。。

class Test{
constructor(){
this.name = "lxc"
}
say(){
alert("haha")
}
}
new Test()
console.log( Object.getOwnPropertyDescriptor(Test.prototype,"say").enumerable ) // false

总的来说,操作中引入继承的属性,会让问题复杂化,大多数时候,我们只关心对象自身的属性。所以,尽量不用for ··· in循环,二用Object.keys代替。。。


举报

相关推荐

0 条评论