成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ES6--對象的擴展

animabear / 2947人閱讀

摘要:若數(shù)值字符串和布爾值做為待合并數(shù)據(jù),合并至目標(biāo)目標(biāo)對象時,只有字符串會以數(shù)組形式,拷貝到目標(biāo)對象。上面代碼中,布爾值數(shù)值字符串分別轉(zhuǎn)成對應(yīng)的包裝對象,可以看到它們的原始值都在包裝對象的內(nèi)部屬性上面,這個屬性是不會被拷貝的。

延續(xù)之前的關(guān)于ES6的學(xué)習(xí)內(nèi)容整理,該篇主要是整理ES6中關(guān)于對象的擴展,希望對大家有幫助。之前已經(jīng)整理了ES6--字符串?dāng)U展和ES6--函數(shù)擴展,大家有興趣可以移步了解。

屬性簡寫

允許直接寫入變量/函數(shù),作為對象的屬性/方法。

let str = "Clearlove"
let obj = {str}
obj // { str: "Clearlove" }

// 等同于
let str = "Clearlove"
let obj = { str: str }

作為方法時的簡寫:

let obj = {
  method() {
    return "Hello~"
  }
}

// 等同于
let obj = {
  method: function() {
    return "Hello~"
  }
}

屬性和方法的簡寫一般作為函數(shù)函數(shù)的返回值對象屬性的賦值器和構(gòu)造器, 以及CommonJS 模塊輸出一組變量,就非常合適使用簡潔寫法。

let Obj = {};

function getItem (key) {
  return key in Obj ? Obj[key] : null;
}

function setItem (key, value) {
  Obj[key] = value;
}

function clear () {
  Obj = {};
}

module.exports = { getItem, setItem, clear }

// 等同于
module.exports = {
  getItem: getItem,
  setItem: setItem,
  clear: clear
}
屬性表達(dá)式

javascript中定義對象屬性,最常見的方式如下:

let obj = {}
obj.iseditable = true

ES6中允許用表達(dá)式作為對象的屬性,將表達(dá)式放在一對中括號中,如下:

let key1 = "key1"
let obj = {
  [key1]: "123",
  ["key" + "2"]: "abc"
}

表達(dá)式還可以定義方法名:

let obj = {
  ["say" + "hello"]() {
    return "hello"
  }
}

obj.sayhello() // hello
Object.is()

用于比較兩個值是否嚴(yán)格相等,與嚴(yán)格比較運算符===基本一致

Object.is("Clearlove", "Clearlove") // true
Object.is({}, {}) // false

與嚴(yán)格比較運算符===的差異主要有兩點:1. +0不等于-0, 2. 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
});
Object.assign()

Object.assign方法用于對象合并,將待合并對象的所有可枚舉屬性,復(fù)制到目標(biāo)對象中。

let target = { name: "Clearlvoe" }

let age = { age: 18 }
let sex = { sex: "男" }

Object.assign(target, age, sex)
target // {name: "Clearlvoe", age: 18, sex: "男"}

如果目標(biāo)對象與待合并對象有同名屬性,或多個待合并對象有同名屬性,則后面的屬性會覆蓋前面的屬性。

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

let target = { name: "Clearlvoe" }
Object.assign(target) //  { name: "Clearlvoe" }
Object.assign(target) === target // true

如果該參數(shù)不是對象,則會先轉(zhuǎn)成對象,然后返回。但undefinednull無法轉(zhuǎn)化為對象,所有以它們?yōu)閰?shù)時,會報錯。

typeof Object.assign(2) // "object"

Object.assign(undefined) // Uncaught TypeError: Cannot convert undefined or null to object
Object.assign(null) // Uncaught TypeError: Cannot convert undefined or null to object

但如果undefinednull是作為帶合并數(shù)據(jù),則不會報錯,因為無法轉(zhuǎn)化為對象,所有跳過。

let target = { name: "Clearlvoe" }
Object.assign(target, undefined) === obj // true
Object.assign(target, null) === obj // true

若數(shù)值、字符串和布爾值做為待合并數(shù)據(jù),合并至目標(biāo)目標(biāo)對象時,只有字符串會以數(shù)組形式,拷貝到目標(biāo)對象。而數(shù)值和布爾值則會被忽略。

let str = "abc";
let boolean = true;
var num = 10;

let obj = Object.assign({}, str, boolean, num);
console.log(obj); // { "0": "a", "1": "b", "2": "c" }

字符串能被拷貝,是因為字符串的包裝對象,會產(chǎn)生可枚舉屬性。

Object(true) // {[[PrimitiveValue]]: true}
Object(10)  //  {[[PrimitiveValue]]: 10}
Object("abc") // {0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"}

上面代碼中,布爾值、數(shù)值、字符串分別轉(zhuǎn)成對應(yīng)的包裝對象,可以看到它們的原始值都在包裝對象的內(nèi)部屬性[[PrimitiveValue]]上面,這個屬性是不會被Object.assign拷貝的。只有字符串的包裝對象,會產(chǎn)生可枚舉的實義屬性,那些屬性則會被拷貝。

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

Object.assign({name: "Clearlove"},
  Object.defineProperty({}, "invisible", {
    enumerable: false,
    value: "hello"
  })
)
// {name: "Clearlove"}

上面代碼中,Object.assign要拷貝的對象只有一個不可枚舉屬性invisible,這個屬性并沒有被拷貝進(jìn)去。

注意點

Object.assign()是淺拷貝,如果源對象的某個屬性值是對象,那么目標(biāo)對象拷貝到的是這個 對象的引用。

let source = {person: { name: "Clearlove"}}
let target = Object.assign({}, source)

source.person.name = "Meiko"
target.person.name  // "Meiko"  

對于這種嵌套的對象,一旦遇到同名屬性,Object.assign()的處理方法是替換,而不是添加。

let source = {person: { name: "Clearlove" }}
let target = {person: { name: "Meiko", age: 18 }}
Object.assign(target, source) // {person: { name: "Clearlove" }} 
常見用途 為對象添加屬性
class LOL {
  constructor(name, age) {
    Object.assign(this, {name, age})
  } 
}

上面方法通過Object.assign方法,將name屬性和age屬性添加到LOL類的對象實例。

為對象添加方法
Object.assign(SomeClass.prototype, {
  addClass(classname) {
    ....
  },
  removeClass(class) {
    ....
  }
})
克隆對象
function clone(origin) {
  return Object.assign({}, origin);
}

上面代碼將原始對象拷貝到一個空對象,就得到了原始對象的克隆。

不過,采用這種方法克隆,只能克隆原始對象自身的值,不能克隆它繼承的值。如果想要保持繼承鏈,可以采用下面的代碼。

function clone(origin) {
  let originProto = Object.getPrototypeOf(origin)
  return Object.assign(Object.create(originProto), origin) 
}
合并多個對象

將對個對象合并到目標(biāo)對象中

const merge = (target, ...sources) => Object.assign(target, ...sources)

如果希望合并后返回一個新對象,可以改寫上面函數(shù),對一個空對象合并

const merge = (...sources) => Object.assign({}, ...sources)
為屬性制定默認(rèn)值
const DEAFULT = {
  number: 0,
  template: "html"
}

funcition processContent(options) {
  options = Object.assigin({}, DEAFULT, options)
  console.log(options)
}

注意,由于存在淺拷貝的問題,DEFAULT對象和options對象的所有屬性的值,最好都是簡單類型,不要指向另一個對象。否則,DEFAULT對象的該屬性很可能不起作用。

屬性的可枚舉性和遍歷 可枚舉性

對象的每個屬性都有一個描述對象(Descriptor),用來控制該屬性的行為。

let person = { name: "Clearlove" }
Object.getOwnPropertyDescriptor(person, "name")

//  {
//    value: Clearlove,
//    writable: true,
//    enumerable: true,
//    configurable: true
//  }

描述對象的enumerable屬性,稱為”可枚舉性“,如果該屬性為false,就表示某些操作會忽略當(dāng)前屬性。
目前有四個操作會忽略enumerablefalse的屬性:

for..in循環(huán): 只遍歷自身和繼承的可枚舉的屬性

Object.keys(): 返回對象所有可枚舉的屬性的鍵名

JSON.stringify: 只字符串化可枚舉的屬性

Object.assign(): 忽略enumerablefalse的屬性,只拷貝可枚舉的屬性

這四個操作之中,前三個是 ES5 就有的,最后一個Object.assign()是 ES6 新增的。其中,只有for...in會返回繼承的屬性,其他三個方法都會忽略繼承的屬性,只處理對象自身的屬性。實際上,引入“可枚舉”(enumerable)這個概念的最初目的,就是讓某些屬性可以規(guī)避掉for...in操作,不然所有內(nèi)部屬性和方法都會被遍歷到。

比如,對象原型的toString方法,以及數(shù)組的length屬性,就通過“可枚舉性”,從而避免被for...in遍歷到。

Object.getOwnPropertyDescriptor(Object.prototype, "toString").enumerable
// false

Object.getOwnPropertyDescriptor([], "length").enumerable
// false

上面代碼中,toStringlength屬性的enumerable都是false,因此for...in不會遍歷到這兩個繼承自原型的屬性。

另外,ES6 規(guī)定,所有 Class 的原型的方法都是不可枚舉的。

Object.getOwnPropertyDescriptor(class {foo() {}}.prototype, "foo").enumerable
// false
未完待續(xù)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91812.html

相關(guān)文章

  • ES6入門之對象擴展

    摘要:循環(huán)遍歷對象自身的和繼承的可枚舉屬性不含屬性。返回一個數(shù)組,包含對象自身的所有屬性的鍵名。目前,只有對象方法的簡寫法可以讓引擎確認(rèn),定義的是對象的方法。showImg(https://user-gold-cdn.xitu.io/2019/5/21/16ada8456223b0e1); 1. 屬性的簡潔表示法 在ES6中 允許直接寫入變量和函數(shù),作為對象的屬性和方法,使得代碼的書寫更為簡潔。...

    RiverLi 評論0 收藏0
  • ES6入門之對象擴展

    摘要:屬性的簡潔表示法在中允許直接寫入變量和函數(shù),作為對象的屬性和方法,使得代碼的書寫更為簡潔。循環(huán)遍歷對象自身的和繼承的可枚舉屬性不含屬性。返回一個數(shù)組,包含對象自身的所有屬性的鍵名。 showImg(https://segmentfault.com/img/remote/1460000019259004?w=1282&h=1920); 1. 屬性的簡潔表示法 在ES6中 允許直接寫入變量...

    AWang 評論0 收藏0
  • ES6標(biāo)準(zhǔn)入門》讀書筆記

    摘要:標(biāo)準(zhǔn)入門讀書筆記和命令新增命令,用于聲明變量,是塊級作用域。用于頭部補全,用于尾部補全。函數(shù)調(diào)用的時候會在內(nèi)存形成一個調(diào)用記錄,又稱為調(diào)用幀,保存調(diào)用位置和內(nèi)部變量等信息。等到執(zhí)行結(jié)束再返回給,的調(diào)用幀才消失。 《ES6標(biāo)準(zhǔn)入門》讀書筆記 @(StuRep) showImg(https://segmentfault.com/img/remote/1460000006766369?w=3...

    HollisChuang 評論0 收藏0
  • es6學(xué)習(xí)筆記--字符串擴展、數(shù)組擴展、對象擴展

    摘要:字符串的擴展字符串的遍歷器接口字符串可以被循環(huán)遍歷。即能識別編號大于查詢字符串是否包含某個字符返回布爾值,表示是否找到了參數(shù)字符串。返回布爾值,表示參數(shù)字符串是否在原字符串的頭部。 字符串的擴展 1.字符串的遍歷器接口 字符串可以被for...of循環(huán)遍歷。 與es5的比較for循環(huán)雖可以遍歷字符串,但不能識別大于oxFFFF的編碼; 2.位置 --> 字符/碼點 根據(jù)指定位置返回對應(yīng)...

    不知名網(wǎng)友 評論0 收藏0
  • ES6rest參數(shù)和擴展運算符

    摘要:參數(shù)的形式為變量名擴展運算符是三個點。傳遞給函數(shù)的一組參數(shù)值,被整合成了數(shù)組。擴展運算符的應(yīng)用普通的函數(shù)調(diào)用上面代碼中,和這兩行,都是函數(shù)的調(diào)用,它們的都使用了擴展運算符。這時,擴展運算符可以將其轉(zhuǎn)為真正的數(shù)組,原因就在于對象實現(xiàn)了。 rest參數(shù)和擴展運算符都是ES6新增的特性。rest參數(shù)的形式為:...變量名;擴展運算符是三個點(...)。 rest參數(shù) rest參數(shù)用于獲取函數(shù)...

    ccj659 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<