Es6對(duì)象新方法

Object.freeze()
該方法可以凍結(jié)一個(gè)對(duì)象,凍結(jié)對(duì)象指的是不能向這個(gè)對(duì)象,添加屬性、刪除屬性、修改屬性、以及不能修改該對(duì)象已有屬性的可枚舉型、可寫性、可配置性,該方法返回被凍結(jié)的對(duì)象。
演示:
var json = {
  name:'秦司令'
};
var obj = Object.freeze(json);
obj.age = 20;        // 不生效
obj.name = 'abc';   //不生效
delete obj.name    // 不生效
console.log(obj.name);  //秦司令 
console.log(obj.age)  // undefined

上面代碼給大家展示了一下操作 就是防止對(duì)象的屬性被修改 , 對(duì)象屬性的可枚舉性、可寫性、可配置性、下面我們會(huì)說到。


Object.is()
Es5比較兩個(gè)值是否相等,只有兩個(gè)運(yùn)算符 ,一個(gè)等于運(yùn)算符( == ) , 一個(gè)嚴(yán)格等于運(yùn)算符( === ) 。它們都有缺點(diǎn),前者會(huì)自動(dòng)轉(zhuǎn)換類型 , 后者的NaN不等于自身,以及+0 等于 -0。javascript缺乏一種運(yùn)算,在所有環(huán)境中,你們的值是一樣的就應(yīng)該相等。
Es6提出同值相等算法,用來解決這個(gè)問題。
Object.is就是部署這個(gè)算法的新方法。它用來比較倆個(gè)值是否嚴(yán)格相等,與嚴(yán)格運(yùn)算符(===) 的行為基本一致。
演示:
Object.is('foo','foo') // true
Object.is({},{}) // false

上面代碼中兩個(gè)空對(duì)象不相等,因?yàn)樗鼈兊囊玫刂凡煌?br> 不同之處只有兩個(gè): 一是 +0 不等于 -0 , 二是 NaN 等于自身

// Es5寫法
+0  === -0 // true
NaN === NaN  //false

//Es6提出的新算法方法
Object.is(+0,-0) //false
Object.is(NaN,NaN) // true

上面代碼Object.is Es6新提出的算法 讓 NaN 等于自身


Object.assign()
該方法用于對(duì)象合并,將源對(duì)象(source)的所有可枚舉屬性,復(fù)制到target目標(biāo)對(duì)象里。
演示:
var json = {a:1};
var source = {b:2};
Object.assign(json,source)  // {a:1,b:2}

Object.assign方法的第一個(gè)參數(shù)是目標(biāo)對(duì)象,其它的都是源對(duì)象,該方法返回值返回第一個(gè)參數(shù)。

注意,如果目標(biāo)對(duì)象和源對(duì)象的屬性有重復(fù)的話,那么源對(duì)象的屬性覆蓋目標(biāo)對(duì)象的屬性。

var json = {a:1,b:1}
var source = {b:2,c:3}
Object.assign(json,source) // {a:1,b:2,c:3}

如果只有一個(gè)參數(shù),Object.assign會(huì)直接返回該參數(shù)

Object.assign({name:'秦司令'}) // {name:'秦司令'}

如果該參數(shù)不是對(duì)象,而先會(huì)轉(zhuǎn)換成對(duì)象。

Object.assign(2) // Number({}) 

由于undefined和null無法轉(zhuǎn)換成對(duì)象,所以如果它們作為參數(shù),就會(huì)報(bào)錯(cuò)。

Object.assign(undefined) //報(bào)錯(cuò)
Object.assign(null)  //報(bào)錯(cuò)

當(dāng)然,如果undefined和null不在首參數(shù)就不會(huì)報(bào)錯(cuò),因?yàn)樗鼈儾辉谑讌?shù),處理方法就不同,如果無法轉(zhuǎn)換成對(duì)象就會(huì)跳過。

Object.assign({},123,{name:'秦司令'}) // {name:'秦司令'}

其它類型的值 數(shù)字,布爾,字符串,不在首參數(shù)內(nèi)也不會(huì)報(bào)錯(cuò) 。但是,除了字符串會(huì)以數(shù)組的形式,拷貝到目標(biāo)對(duì)象里,其它值都不行,只有字符串可以。

Object.assign({},'str') // {0:'s',1:'t',2:'r'} 
Object.assign({},123) // {}
Object.assign({},true) // {}

上面代碼中,數(shù)值,布爾值,字符串 結(jié)果只有字符串被拷貝進(jìn)去,這是因?yàn)橹挥凶址邪b類對(duì)象,會(huì)產(chǎn)生可枚舉屬性。

請(qǐng)看下個(gè)列子

Object(true)  //{ [[PrimitiveValue]]:true }
Object(123)  // { [[PrimitiveValue]]:123 }
Object('str') // {0:'s',1:'t',2:'r',length:3, [[PrimitiveValue]]:'str' }

上面代碼看對(duì)象的返回值 [[PrimitiveValue]] 這個(gè)是原始屬性 assign 是無法拿到的,只有字符串有可枚舉屬性,所以上面只能拷貝字符串。

Object.assign拷貝屬性也是有限制的,只拷貝源對(duì)象的自身屬性(不包含繼承屬性),也不拷貝不可枚舉屬性(enumerable:false)。

Object.assign({name:'秦司令'},
  Object.defineProperty({},'age',{
    enumerable:false,
    value:20  
  })
)

上面代碼中,Object.assign要拷貝這個(gè)對(duì)象屬性,但是沒有被拷貝進(jìn)去,因?yàn)檫@個(gè)屬性里面設(shè)置了不可枚舉屬性,enumerable:false。

屬性名為Symbol值的也會(huì)被拷貝進(jìn)去

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

注意點(diǎn)

淺拷貝
Object.assign方法實(shí)行的是淺拷貝,而不是深拷貝。也就是說,如果源對(duì)象某個(gè)屬性發(fā)生改變,那么Object.assign的目標(biāo)對(duì)象也跟著改變。
var json = {a:{b:1}}
var obj = Object.assign({},json)
json.a.b = 2
obj.a.b // 2

上面代碼發(fā)生引用的原因是,json.a的屬性值是一個(gè)對(duì)象,Object.assign拷貝到的是這個(gè)對(duì)象的引用,這個(gè)對(duì)象的任何變化,都會(huì)映射到目標(biāo)對(duì)象上

數(shù)組的處理
Object.assign用來處理數(shù)組,會(huì)把數(shù)組視為對(duì)象處理。
Object.assign([1,2,3],[4,5,6]) // [4,5,6]

上面代碼中,Object.assign把數(shù)組視為屬性名為 0 1 2的對(duì)象,因此源數(shù)組的0號(hào)屬性 4 覆蓋了 目標(biāo)屬性的 1 值 , 以此類推 最后全部覆蓋。

取值函數(shù)的處理
Object.assign只能進(jìn)行值的復(fù)制,如果是要復(fù)制一個(gè)取值函數(shù),那么將求值后再復(fù)制
const source = {
  get foo(){
    return 1
  }
}
const target = {};
Object.assign(target,source)  // {foo:1}

上面代碼中,source對(duì)象的foo屬性是一個(gè)取值函數(shù),Object.assign不會(huì)復(fù)制這個(gè)取值函數(shù),只會(huì)拿到值以后,將這個(gè)值復(fù)制過去


常見用途

Object.assign方法有很多好處。
一、為對(duì)象添加屬性
class Point{
  constructor(x,y){
    Object.assign(this,{x,y})
  }
}
new Point(1,2)

上面方法通過Object.assign方法,將x屬性和y屬性添加到Point類的對(duì)象實(shí)例。

二、給對(duì)象添加方法
function Fn(){}
Object.assign(Fn.Prototype,{
  add(){
  
  }
})
new Fn()

上面代碼使用Object.assign方法給對(duì)象添加方法,這樣寫法簡潔表達(dá)式

三、克隆對(duì)象
function clone(obj){
  return Object.assign({},obj)
}

上面代碼將原始對(duì)象拷貝到一個(gè)空對(duì)象,就得到了原始對(duì)象的克隆。

不過,采用這種方法克隆,只能克隆原始對(duì)象自身的值,不能克隆它繼承的值,如果想要克隆它的原型,請(qǐng)看下列代碼。

function clone(){
  var proto = Object.getPrototypeOf(obj)
  return Object.assign(Object.create(proto),obj)
}
// Object.create方法是操作__proto__ 
四、合并多個(gè)對(duì)象

將多個(gè)對(duì)象合并到某個(gè)對(duì)象

const mer = (target,...source) => Object.assign(target,...source)
//上面的寫法 相當(dāng)于下面
function Demo(target,...source){
  return Object.assign(target,...source)
}

Object.getOwnPropertyDescriptors()
Es5的Object.getOwnPropertyDescriptor()方法會(huì)返回某個(gè)對(duì)象屬性的描述對(duì)象(descriptor) , Es2017引入了Object.getOwnPropertyDescriptors()方法,返回指定對(duì)象所有自身屬性(非繼承屬性)的描述對(duì)象。
const obj = {
  foo:123,
  get bar(){
    return 'aaa'
  }
}
Object.getOwnPropertyDescriptors(obj)
//{ foo:
//    { value: 123,
//      writable: true,
//      enumerable: true,
//      configurable: true },
//   bar:
//    { get: [Function: get bar],
//      set: undefined,
//      enumerable: true,
//      configurable: true } }

上面代碼中,Object.getOwnPropertyDescriptors()方法返回一個(gè)對(duì)象,所有原對(duì)象的屬性名都是該對(duì)象的屬性名,對(duì)應(yīng)的屬性值就是該對(duì)象的描述對(duì)象。

該方法的引入,主要是為了解決Object.assign不能正??截?set屬性 和 get 屬性的取值函數(shù)。

const source = {
    set foo(value){
      console.log(value)
    }
}
var obj = Object.assign({},source);
Object.getOwnPropertyDescriptor(obj,'foo')
// { value: undefined,
//   writable: true,
//   enumerable: true,
//   configurable: true }

上面代碼中,source對(duì)象的foo屬性的值是一個(gè)賦值函數(shù),Object.assign方法將這個(gè)屬性拷貝給target1對(duì)象,結(jié)果該屬性的值變成了undefined,這是因?yàn)镺bject.assign方法總是拷貝一個(gè)屬性的值,而不會(huì)拷貝它背后的賦值方法或取值方法。

這時(shí),Object.getOwnPropertyDescriptors()方法配合Object.defineProperties方法,就可以實(shí)現(xiàn)正確拷貝。

const source = {
  set foo(value){
    console.log(value)
  }
}
var target = {}
Object.defineProperties(target,Object.getOwnPropertyDescriptors(source)) 
Object.getOwnPropertyDescriptor(target,'foo')

上面的代碼,將屬性描述對(duì)象添加到目標(biāo)對(duì)象里面。

下面講解一下Object.defineProperties該方法

var json = {
  get foo(){
    return 123
  }
};
Object.defineProperties({},Object.getOwnPropertyDescriptors(json)) ;
//上面的寫法,等同于下面的寫法
Object.defineProperties({},{
  foo:{
     get(){
        return 123;
     },
     set(value){
        return value;
     }
  }
});

上面代碼, json是一個(gè)對(duì)象,里面是一個(gè)取值函數(shù) ,然后下面通過對(duì)象的屬性描述方法給它添加到Object.defineProperties該方法里面。

另外,Object.getOwnPropertyDescriptors()方法的另一個(gè)用處,是配合Object.create() 方法,將對(duì)象屬性克隆到一個(gè)新對(duì)象,這是淺拷貝。

var obj = {
  name:'秦司令'
};
Object.create(Object.getPrototypeOf(obj),Object.getOwnPropertyDescriptors(obj));

__ proto __ 屬性(前后各兩個(gè)下劃線),用來讀取或設(shè)置當(dāng)前對(duì)象的prototype對(duì)象。目前,所有瀏覽器(包括IE11) 都部署了這個(gè)屬性。
演示:
//Es5的寫法
function demo(){}
var obj  =  {
    method:function(){}
}
obj.__ proto __ = demo
new demo() 

// Es6的寫法

var obj  = Object.create(demo)

上面代碼中,Es6的寫法Object.create該方法直接是設(shè)置__ proto __ 屬性的

該屬性沒有寫入Es6的正文,而是寫入了附錄,原因是__ proto __前后的雙下劃線,說明它本質(zhì)上是一個(gè)內(nèi)部屬性,而不是一個(gè)正式對(duì)外的API,只是由于瀏覽器廣泛支持,才被加入Es6。標(biāo)準(zhǔn)明確規(guī)定,只有瀏覽器必須部署這個(gè)屬性,其它運(yùn)行環(huán)境不一定要部署。

Object.getPrototypeOf()
該方法與Object.setPrototypeOf方法配套,用于讀取一個(gè)對(duì)象的原型對(duì)象。
演示:
var obj = {}
Object.getPrototypeOf(obj) 

下面是一個(gè)列子。

function Fn(){}
var f = new Fn()
Object.getPrototypeOf(f) === Fn.prototype  //true
Object.setPrototypeOf(f,Object.prototype)
Object.getPrototypeOf(f) === Fn.prototype //false

如果參數(shù)不是對(duì)象,會(huì)自動(dòng)轉(zhuǎn)換為對(duì)象

Object.getPrototypeOf(1)
// 轉(zhuǎn)換過程 Object.getPrototypeOf(Number(1))
// Number{ [[PrimitiveValue]]: 0 }
Object.getPrototypeOf('foo')
//轉(zhuǎn)換過程 Object.getPrototypeOf(String('foo'))
// String{length:0,[[PrimitiveValue]]: ' ' }

Object.getPrototypeOf(1) == Number.prototype  // true
Object.getPrototypeOf('foo') == String.prototype // true

如果參數(shù)是undefined和null,它們無法轉(zhuǎn)換為對(duì)象,會(huì)直接報(bào)錯(cuò)

Object.getPrototypeOf(null)   //報(bào)錯(cuò)
// typeError: Cannot convert null or undefined to Object
Object.getPrototypeOf(undefined)  //報(bào)錯(cuò)
// typeError: Cannot convert null or undefined to Object

如果一個(gè)對(duì)象本身部署了__ proto __屬性,該屬性的值就是對(duì)象的值。

Object.getPrototypeOf({__proto__:null}) // null 

Object.setPrototypeOf()
Object.setPrototypeOf方法的作用與__ proto __ 相同, 用來設(shè)置一個(gè)對(duì)象的prototype對(duì)象,返回參數(shù)對(duì)象本身。它是Es6正式推薦設(shè)置原型的對(duì)象的方法。
演示:
//格式
Object.setPrototypeOf(object,prototype)
//用法
const obj = Object.setPrototypeOf({},null) //設(shè)置這對(duì)象沒有原型

//該方法等同于下面的函數(shù)
function setPrototypeOf(obj,proto1){
  obj.__proto__ = proto1
  return obj
}

下面是一個(gè)例子

let proto = {}
let obj = {name:'秦司令'}
Object.setPrototypeOf(obj,proto)

proto.x = 10;
proto.y = 20;

obj.name // 秦司令
obj.x // 10
obj.y // 20

上面代碼將proto對(duì)象設(shè)為obj的原型,所以從obj對(duì)象可以讀取proto對(duì)象的原型屬性。

如果第一個(gè)參數(shù)不是對(duì)象,會(huì)自動(dòng)轉(zhuǎn)換為對(duì)象,但是由于返回的還是第一個(gè)參數(shù),這個(gè)操作不會(huì)產(chǎn)生任何效果。

Object.setPrototypeOf(1,{})  === 1
Object.setPrototyoeOf('name' , {}) == 'name'
Object.setPrototypeOf(true,{}) == true

由于undefined和null無法轉(zhuǎn)換為對(duì)象,所以第一個(gè)參數(shù)是undefined或null的話,會(huì)直接報(bào)錯(cuò)。

Object.setPrototypeOf(undefined,{}) //報(bào)錯(cuò)
Object.setPrototypeOf(null,{}) //報(bào)錯(cuò)
Object.keys()
Es5引入了Object.keys方法,返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不包含繼承的) 所有可遍歷(enumerable)的屬性鍵名。
var obj = {name:'秦司令',age:20};
Object.keys(obj)  //["name","age"]

Es2017引入了跟Object.keys配套的Object.values和Object.entries,作為遍歷一個(gè)對(duì)象的補(bǔ)充手段,供for....of循環(huán)使用

var obj = {a:1,b:2,c:3};
for(let key of Object.keys(obj)){
  console.log(key)  // a b c
}
for(let values of Object.values(obj)){
  console.log(values) // 1 2 3
}
for(let [k,v] of Object.entries(obj)){
  console.log([k,v]) // [name,'秦司令',age:20]  
}
Object.values()
Object.values方法返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值。
var obj = {name:'秦司令',age:20};
Object.values(obj) // ["秦司令",20]

返回?cái)?shù)組的成員順序

var obj = {100:'a',2:'b',18:'c'}
Object.values(obj) // [b,c,d] 

上面代碼中,屬性名為數(shù)值的屬性,是按照數(shù)值大小,從小到大遍歷的,因此返回的順序是b,c,d

Object.values只返回自身可遍歷屬性

var json = Object.create({},{p:{value:123}})
Object.values(json)  //[]

上面代碼中,Object.create方法的第二個(gè)參數(shù)添加的對(duì)象屬性(屬性p),如果不顯式聲明,默認(rèn)是不可遍歷的,因?yàn)閜的屬性描述對(duì)象的enumerable默認(rèn)是false,Object.values不會(huì)返回這個(gè)屬性,只要把enumerable改成true,Object.values就返回這個(gè)屬性p值

var obj = Object.create({},{p:{
    value:2,
    enumerable:true 
}})
Object.values(obj)  //[2]

Object.values會(huì)過濾屬性名為Symbol值的屬性

Object.values({[Symbol()]:123,name:'秦司令'})
// ['秦司令']

如果Object.values方法的參數(shù)是一個(gè)字符串,會(huì)返回各個(gè)字符組成的一個(gè)數(shù)組。

Object.values('fooa')
// ['f','0','0','a']

上面代碼中,字符串會(huì)先轉(zhuǎn)換成一個(gè)類似數(shù)組的對(duì)象,字符串的每個(gè)字符,就是該對(duì)象的一個(gè)屬性,因此,Object.values返回每個(gè)屬性的鍵值,就是各個(gè)字符組成的一個(gè)數(shù)組

如果參數(shù)不是對(duì)象,Object.values會(huì)先將其轉(zhuǎn)換為對(duì)象。由于數(shù)值和布爾值的包裝類對(duì)象,都不會(huì)為實(shí)例添加非繼承的屬性,所以,Object.valus會(huì)返回空數(shù)組

Object.values(43) //[]
Object.values(true) // []
Object.entries()
Object.entries()方法返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值對(duì)數(shù)組。
var obj = {foo:'bar',baz:43}
Object.entries(obj)
// [["foo","bar"],["baz",43]]

如果原對(duì)象的屬性名是一個(gè)Symbol值,該屬性會(huì)被忽略

Object.entries({[Symbol()]:123,foo:'abc'}) 
//[["foo","abc"]]

Object.entries的基本用途是遍歷對(duì)象的屬性

let obj = {one:1,tow:2}
for(let [k,v] of Object.entries(obj)){
  console.log(`${JSON.stringify(k)}:${JSON.stringify(v)}`)
}
// "one":1  
// "tow":2

Object.entries另一用處是將對(duì)象轉(zhuǎn)換成Map結(jié)構(gòu)

var obj = {foo:'bar',name:'秦司令'}
var map = new Map(Object.entries(obj))
// Map{foo:'bar',name:'秦司令'}

如有問題,望大神指點(diǎn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.屬性的簡潔表示法 允許直接寫入變量和函數(shù) 上面代碼表明,ES6 允許在對(duì)象之中,直接寫變量。這時(shí),屬性名為變量...
    雨飛飛雨閱讀 1,256評(píng)論 0 3
  • 屬性的簡潔表示法 ES6允許直接寫入變量和函數(shù),作為對(duì)象的屬性和方法。 上面代碼表明,ES6允許在對(duì)象之中,直接寫...
    oWSQo閱讀 568評(píng)論 0 0
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,626評(píng)論 1 32
  • 屬性的簡潔表示法 ES6允許直接寫入變量和函數(shù),作為對(duì)象的屬性和方法。這樣的書寫更加簡潔。 上面代碼表明,ES6允...
    呼呼哥閱讀 3,008評(píng)論 0 2
  • 文 | 花時(shí)間 來源 | 慢成長 果果三歲以后,我對(duì)她的數(shù)學(xué)啟蒙越來越上心。我始終覺得,數(shù)學(xué)啟蒙是一種素質(zhì)教育。我...
    漫界閱讀 1,094評(píng)論 1 6

友情鏈接更多精彩內(nèi)容