CocosCreator 源碼-./polyfill/object詳解

// for IE11

/*?

Object.assign() 靜態(tài)方法將一個或者多個源對象中所有可枚舉的自有屬性復(fù)制到目標(biāo)對象,并返回修改后的目標(biāo)對象。

const target = { a: 1, b: 2 };

const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

console.log(target);

// Expected output: Object { a: 1, b: 4, c: 5 }

console.log(returnedTarget === target);

// Expected output: true

target

需要應(yīng)用源對象屬性的目標(biāo)對象,修改后將作為返回值。

sources

一個或多個包含要應(yīng)用的屬性的源對象。

*/

if (!Object.assign) {

? ? Object.assign = function (target, source) {

? ? ? ? /* 調(diào)用引擎方法,cc-js cc.js =js 這部分在flatform部分詳細(xì)講解 */

? ? ? ? return cc.js.mixin(target, source);

? ? }

}

// for Baidu browser

// Implementation reference to:?

// http://2ality.com/2016/02/object-getownpropertydescriptors.html

// http://docs.w3cub.com/javascript/global_objects/reflect/ownkeys/

/*?

?在ES2017的版本中,Object對象新增了一個方法——Object.getOwnPropertyDescriptors。這個方法主要的作用是返回屬性的描述對象(descriptor)。


?const obj = {

? ?prop1 : 100,

? ?prop2 : "字符串屬性",

? ?get bar(){return "bar返回字符串"}

}

Object.getOwnPropertyDescriptors(obj);

{prop1: {…}, prop2: {…}, bar: {…}}bar: {get: ?, set: undefined, enumerable: true,?

? ? configurable: true}configurable: trueenumerable:?

? ? trueget: ? bar()arguments: (...)caller: (...)length: 0

? ? name: "get bar"__proto__: ? ()apply: ? apply()arguments: (...)

? ? bind: ? bind()call: ? call()caller: (...)constructor: ? Function()

? ? length: 0name: ""toString: ? toString()Symbol(Symbol.ha…………

在瀏覽器里運行代碼,會得到上面的結(jié)果。數(shù)據(jù)很多,但能看出都是關(guān)于各個屬性的特性的描述文字。

? ? ?Object.getOwnPropertyDescriptors 方法返回一個對象,所有原來的對象的屬性名都是該對象的屬性名,對應(yīng)的屬性值就是該屬性的描述對象。

? ? ? 現(xiàn)在我們知道了,我們用Object.getOwnPropertyDescriptors能夠查看對象屬性的特性,

? ? ? 讓我們開發(fā)的時候?qū)@個對象心里有底。但是這個接口還有什么實際作用呢?

? ? ? 作用:克隆對象。

? ? ? 之前我們談過,用Object.assign()能克隆對象,其原理是把一個現(xiàn)有的對象和一個空對象合并之后,

? ? ? 空對象就有了現(xiàn)有對象的屬性。這樣空對象好像就變成了源對象的克隆體一樣。


? ? ? 這種方法在通常情況下是沒問題的,但是有一個前提是Object.assign()接口無法正確拷貝set屬性和get屬性的對象。

? ? ? 因為assign做合并的時候,只能拷貝一個屬性值,不會把它背后的賦值方法或者取值方法一同拷貝過來。所以在這種情況下,

? ? ? 我們就可以用Object.getOwnPropertyDescriptors方法,配合Object.defineProperties方法,實現(xiàn)克隆對象的功能。

? ? ? ? 這種方法的原理是將源對象的所有屬性描述對象,提取出來,根據(jù)這個描述對象,重新定義一個空對象的屬性。代碼如下:?

? ? ? ? const source = {

? ? ? ? set foo(value) {

? ? ? ? ? ? console.log(value);

? ? ? ? }

? ? ? ? };


? ? ? ? const target2 = {};

? ? ? ? Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source));

? ? ? ? Object.getOwnPropertyDescriptor(target2, 'foo')

? ? ? ? // { get: undefined,

? ? ? ? //? ?set: [Function: set foo],

? ? ? ? //? ?enumerable: true,

? ? ? ? //? ?configurable: true }

? ? ? ? ? ? ?我們還有另一種方法,讓getOwnPropertyDescriptors方法配合Object.create方法,來克隆對象

? ? ? ? ? ? ? ? var source = {

? ? ? ? ? ? ? ? ? ? prop1 : "prop1",

? ? ? ? ? ? ? ? ? ? prop2 : 100;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? // source 是源對象,我們獲取source的原型對象和source的屬性描述對象,根據(jù)二者生成的新對象就是source的克隆

? ? ? ? var clone = Object.create(Object.getPrototypeOf(source),Object.getOwnPropertyDescriptors(source));

*/

if (!Object.getOwnPropertyDescriptors) {

? ? Object.getOwnPropertyDescriptors = function (obj) {

? ? ? ? /* 聲明一個對象,用于存儲屬性描述對象 */

? ? ? ? let descriptors = {};

? ? ? ? /* getOwnPropertyNames-

? ? ? ? 該方法返回對象自身屬性的名稱。對象自身的屬性是直接定義的屬性 在該對象上,并且不是從該對象的原型繼承的。對象的屬性包括字段(對象)和函數(shù)。 */

? ? ? ? let ownKeys = Object.getOwnPropertyNames(obj);

? ? ? ? /* getOwnPropertySymbols

? ? ? ? 該方法返回直接在對象 o 上找到的所有符號屬性的數(shù)組。 */

? ? ? ? if (Object.getOwnPropertySymbols) { // for IE 11

? ? ? ? ? ? ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(obj));

? ? ? ? }

? ? ? ? for (let i = 0; i < ownKeys.length; ++i) {

? ? ? ? ? ? let key = ownKeys[i];

? ? ? ? ? ? /* 存儲屬性描述對象 */

? ? ? ? ? ? descriptors[key] = Object.getOwnPropertyDescriptor(obj, key);

? ? ? ? }

? ? ? ? return descriptors;

? ? }

}

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

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

  • 1.屬性的簡潔表示法 允許直接寫入變量和函數(shù) 上面代碼表明,ES6 允許在對象之中,直接寫變量。這時,屬性名為變量...
    雨飛飛雨閱讀 1,283評論 0 3
  • let 和 const 循環(huán)語句中,每次循環(huán)都會創(chuàng)建一個新的代碼塊作用域 var a = [];for (let ...
    _于曼麗_閱讀 312評論 0 0
  • ECMAScript - 學(xué)習(xí)筆記 ?? ??nvm node.js 包管理工具 nvm github[https:/...
    Super三腳貓閱讀 907評論 0 1
  • 屬性的簡潔表示法 ES6允許直接寫入變量和函數(shù),作為對象的屬性和方法。這樣的書寫更加簡潔。 上面代碼表明,ES6允...
    呼呼哥閱讀 3,024評論 0 2
  • 一、屬性的簡介表示法 ES6允許直接寫入變量和函數(shù)作為對象的屬性和方法。允許在對象中只寫屬性名,不寫屬性值。這時,...
    了凡和纖風(fēng)閱讀 376評論 0 0

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