對象擴展

1.方法也可以簡寫


let age = 10 ;
const person = {
  name:'linjian',
  sex:'boy',
  hello(){
    console.log('hello lilei')
  }
}
// console.log(Array.from('x\uD83D\uDE80y').length); 
person.hello();

ES6 允許字面量定義對象時,用方法二(表達式)作為對象的屬性名,即把表達式放在方括號內

let propKey = 'foo';

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

Object.is()
ES5 比較兩個值是否相等,只有兩個運算符:相等運算符(==)和嚴格相等運算符(===)。它們都有缺點,前者會自動轉換數(shù)據(jù)類型,后者的NaN不等于自身,以及+0等于-0。JavaScript 缺乏一種運算,在所有環(huán)境中,只要兩個值是一樣的,它們就應該相等。

ES6 提出“Same-value equality”(同值相等)算法,用來解決這個問題。Object.is就是部署這個算法的新方法。它用來比較兩個值是否嚴格相等,與嚴格比較運算符(===)的行為基本一致。不同之處只有兩個:一是+0不等于-0,二是NaN等于自身。

Object.is('foo', 'foo')
// true
Object.is({}, {})
// false
+0 === -0 //true
NaN === NaN // false

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

Object.assign方法用于對象的合并,將源對象(source)的所有可枚舉屬性,復制到目標對象(target)。

let a ={a:1};
let b = {b:2},c={c:3};
console.log(Object.assign(a,b,c))
console:Object {
  a: 1,
  b: 2,
  c: 3
}
非對象轉為對象,由于undefined和null無法轉成對象,所以如果它們作為參數(shù),就會報錯
console.log(typeof Object.assign(2)) // 'Object'

Object.assign方法實行的是淺拷貝,而不是深拷貝。也就是說,如果源對象某個屬性的值是對象,那么目標對象拷貝得到的是這個對象的引用。

常見用途
(1)為對象添加屬性

class Point {
  constructor(x, y) {
    Object.assign(this, {x, y});
  }
}

(2)為對象添加方法

Object.assign(SomeClass.prototype, {
  someMethod(arg1, arg2) {
    ···
  },
  anotherMethod() {
    ···
  }
});

// 等同于下面的寫法
SomeClass.prototype.someMethod = function (arg1, arg2) {
  ···
};
SomeClass.prototype.anotherMethod = function () {
  ···
};

(3)克隆對象

function clone(origin) {
  return Object.assign({}, origin);
}
不過,采用這種方法克隆,只能克隆原始對象自身的值,不能克隆它繼承的值。如果想要保持繼承鏈,可以采用下面的代碼。
function clone(origin) {
  let originProto = Object.getPrototypeOf(origin);
  return Object.assign(Object.create(originProto), origin);
}

Object.getOwnPropertyDescriptors方法的另一個用處,是配合Object.create方法,將對象屬性克隆到一個新對象。這屬于淺拷貝。

const clone = Object.create(Object.getPrototypeOf(obj),
  Object.getOwnPropertyDescriptors(obj));

// 或者

const shallowClone = (obj) => Object.create(
  Object.getPrototypeOf(obj),
  Object.getOwnPropertyDescriptors(obj)
);

proto屬性(前后各兩個下劃線),用來讀取或設置當前對象的prototype對象。目前,所有瀏覽器(包括 IE11)都部署了這個屬性。標準明確規(guī)定,只有瀏覽器必須部署這個屬性,其他運行環(huán)境不一定需要部署,而且新的代碼最好認為這個屬性是不存在的。因此,無論從語義的角度,還是從兼容性的角度,都不要使用這個屬性,而是使用下面的Object.setPrototypeOf()(寫操作)、Object.getPrototypeOf()(讀操作)、Object.create()(生成操作)代替。

// es6 的寫法
const obj = {
  method: function() { ... }
};
obj.__proto__ = someOtherObj;

// es5 的寫法
var obj = Object.create(someOtherObj);
obj.method = function() { ... };

Object.setPrototypeOf方法的作用與proto相同,用來設置一個對象的prototype對象,返回參數(shù)對象本身。它是 ES6 正式推薦的設置原型對象的方法。

// 格式
Object.setPrototypeOf(object, prototype)

// 用法
const o = Object.setPrototypeOf({}, null);

Object.getPrototypeOf()
該方法與Object.setPrototypeOf方法配套,用于讀取一個對象的原型對象。
super 關鍵字
this關鍵字總是指向函數(shù)所在的當前對象,ES6 又新增了另一個類似的關鍵字super,指向當前對象的原型對象。

const proto = {
  foo: 'hello'
};

const obj = {
  find() {
    return super.foo;
  }
};

Object.setPrototypeOf(obj, proto);
obj.find() // "hello"

Null 傳導運算符
編程實務中,如果讀取對象內部的某個屬性,往往需要判斷一下該對象是否存在。比如,要讀取message.body.user.firstName,安全的寫法是寫成下面這樣。

const firstName = (message
  && message.body
  && message.body.user
  && message.body.user.firstName) || 'default';
可以簡寫為:
const firstName = message?.body?.user?.firstName || 'default';

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容