ES6 之 對象擴展 前半部

屬性的簡介表示法

var foo = 'bar';
var baz = {foo};
console.log(baz);       //{ foo: 'bar' }


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


var o = {
    method() {
        return 'Hello';
    }
};
//等同於
var o = {
    method: function () {
        return 'Hello';
    }
};
console.log(o.method());        //Hello

function getPoint() {
    var x = 1;
    var y = 10;
    return {x,y};
}

console.log(getPoint());    //{ x: 1, y: 10 }


# CommJS模塊輸出變量就非常適合使用簡介寫法
var ms = {};

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

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

function clear() {
    ms = {}
}


module.exports = {getItem,setItem, clear};
//等同於
module.exports = {
    getItem:getItem(),
    setItem: setItem(),
    clear: clear()
}
ps: 以上屬性的賦值器和取值器都採用了屬性簡寫的方法

屬性名表達式

JS語言定義對象的屬性有兩種方法。
1、用標識符定義屬性(ES5)
2、用表達式作爲屬性名(ES6)

// ES5 標識符作屬性名 
var obj = {
    foo:true,
    abc: 123
}

// ES6 表達式作爲屬性名

let propKey = 'foo';
let obj = {
    [propKey]: true,
    ['a'+'bc']:123
}

let lastWord = 'last word';
var a = {
    'first word':'hello',
    [lastWord]:'world'
}

console.log(a['first word']);
console.log(a[lastWord]);
console.log(a['last word']);

注意:屬性名表達式和簡介表示法不能同時使用

var foo = 'bar';
var bar = 'abc';
var baz = {[foo]};  //  絕壁報錯

var foo = 'bar';
var baz = {[foo]: 'abc'};  // 正確寫法

方法的name屬性

var person = {
    sayName(){
        console.log(this.name);
    },
    get firstName(){
        return 'Loyal';
    }
}

console.log(person.sayName.name);       //親測:sayName

console.log(person.firstName.name);     //親測:undefined  書本答案爲: get firstName

注意: 有兩種特殊情況,1、bind方法創造的函數,name返回“bound”+原函數名字;2、Function構造函數創造的函數,name屬性返回“anonymous”

console.log((new Function()).name);     //anonymous
var doSomething = function () {
        // ....
}
console.log(doSomething.bind().name);   //bound doSomething

Object.is() 用來比較兩個值是否嚴格相等,它與嚴格比較運算符的欣慰基本一致


console.log(Object.is('foo', 'foo'));       //true
console.log(Object.is({}, {}));             //false

# 略有不同
console.log(+0 === -0);                     //true
console.log(NaN === NaN);                   //false

console.log(Object.is(+0, -0));             //false
console.log(Object.is(NaN, NaN));           //true

ps: ES5中可以使用以下代碼來實現Object.is功能
Object.defineProperty(Object, 'is', {
    value: function(x,y){
       if(x === y) {
           return x !== 0 || 1/x === 1/y;
       }
        return x !== x && y !== y;
    },
    configurable: true,
    enumerable: false,
    writable: true
})

Object.assign() 用來將源對象的所有可枚舉屬性複製到目標對象,需要至少兩個對象作爲參數,第一個參數爲目標對象,後面的參數爲源對象,只要有一個不是對象,就會拋出TypeError錯誤

var target = {a: 11};
var source1 = {b:2};
var source2 = {c:3};
console.log(Object.assign(target, source1, source2));   //{ a: 11, b: 2, c: 3 }

# 注意,目標對象和源對象有同名屬性,或多個源對象有同名屬性,則後面屬性會覆蓋前面的屬性
var target = {a: 11, b:3};
var source1 = {b:2};
var source2 = {c:3};
console.log(Object.assign(target, source1, source2));   //{ a: 11, b: 2, c: 3 }


# 嵌套的對象,Object.assign的處理方法是替換而不是添加
var target = {a:{b:{c:5,d:6}} };
var source1 = {a:{b:'hello'}};
console.log(Object.assign(target, source1));   //{ a: { b: 'hello' } }

# 處理數組,但會將其視爲對象,進行替換
console.log(Object.assign([1, 2, 3], [4, 5]));  //[ 4, 5, 3 ]
  • 爲對象添加屬性

Class Point{
 constructor(x,y){
     Object.assign(this, {x,y})
 }
}
  • 爲對象添加方法
Object.assign(SomeClass.prototype, {
  someMethod(arg1,arf2){

  },
  anotherMethod(){

  }
})
//等同於

SomeClass.prototype.someMethod = function (arg1,arf2){
  //...
}
SomeClass.prototype.anotherMethod = function () {
  //...
}
  • 克隆對象

function clone(origin){
    return Object.assign({}, origin);
}

以上將院士對象複製到一個控對象,就得到了運勢對象的克隆
只能克隆原始對象自身的值,不能克隆他繼承的值想要保持繼承鏈,可以試用以下代碼

function clone(origin) {
    let originProto = Object.getPrototypeOf(origin);
    return Object.assign(Object.create(originProto), origin);
}
  • 合併多個對象
const merge = (target,...source) => Object.assign(target,...source);
const merge = (...source) => Object.assign({}, ...source);
  • 爲屬性指定默認值
const DEFAUlTS = {
    logLEvel: 0,
    ouputFormat: 'html'
}
function processContent(options) {
    let options = Object.assign({}, DEFAUlTS, options);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章