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

資訊專欄INFORMATION COLUMN

ECMAScript6(8):對象的擴(kuò)展

pingan8787 / 469人閱讀

基本擴(kuò)展

允許使用已有對象賦值定義對象字面量,并且只寫變量名即可

var name = "Bob";
var getName = function(){console.log(this.name);};

var person = {name, getName};
//相當(dāng)于
//var person = {
//name: "Bob",
//getName: function(){console.log(this.name);}
//}
person.getName();   //"Bob"

可以像定義存取器那樣定義方法

var o = {
  _age: 10,
  _score: 60,
  age(num){
    if(num > 0) {
      this._age = num;
      return this;
    }
    return this._age;
  },
  get score(){
    return this._score;
  }
};

console.log(o.age());    //10
o.age(15);
console.log(o.age());    //15
console.log(o.score);    //60
o.score = 100;           //TypeError

注意,以下代碼是等同的:

var obj = {
  class () {}       //并不會因?yàn)?class 是關(guān)鍵字而解析錯誤
};
//等價于
var obj = {
  "class": function() {}
};

如果一個方法是 Generator 函數(shù),需要在前面加 *:

var obj = {
  time: 1,
  *gen(){
    yield "hello " + time;
    time++;
  }
}

屬性名表達(dá)式

js 本來可以這樣 obj["k"+"ey"] 訪問一個對象屬性,現(xiàn)在也可以這樣定義屬性了:

var key1 = "name";
var key2 = "age";

var o = {
  [key1]: "Bob",
  [key2]: 18,
  ["first" + key1]: "Ellen"
};
o.name;    //"Bob"
o.age;     //18
o.firstname;   //"Ellen"

注意:該方法不能和上一小節(jié)使用已有標(biāo)識符定義對象字面量的方法混合使用,否則會報(bào)錯;

//錯誤用法
var foo = "bar";
var bar = "abc";
var baz = {[foo]};  //報(bào)錯

方法的 name 屬性

函數(shù)有 name 屬性,方法也就有 name 屬性。一般方法 name 返回函數(shù)名(不包括對象名),對于存取器方法,沒有 name 屬性:

var o = {
  _age: 10,
  _score: 60,
  _name: "Bob",
  _firstname: "Ellen",
  set age(num){
    if(num > 0) {
      this._age = num;
      return this;
    }
  },
  get age(){
    return this._age;
  },
  get score(){
    return this._score;
  },
  name(n){
    if(!n) return this._name + " " + this._firstname;
    this._name = n;
    return this;
  },
  set firstname(n){
    if(n) this._firstname = n;
    return this;
  }
};
console.log(o.name.name);      //"name"
console.log(o.age.name);       //undefined
console.log(o.score.name);     //undefined
console.log(o.firstname);      //undefined,所以 set 函數(shù)更不會有 name 屬性

如果對象的方法是個 symbol,name 屬性為空字符串 ""

var sym1 = new Symbol("description of sym1");
var sym2 = new Symbol();
var o = {
  [sym1](){},
  [sym2](){},
};
o[sym1].name;    //""
o[sym2].name;    //""

靜態(tài)方法

Object.is(a,b): 比較a,b兩個值是否嚴(yán)格相等,相當(dāng)于 ===, 但有一點(diǎn)不一樣:

-0 === +0;     //true
NaN === NaN;   //false

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

Object.assign(target, source1,source2,...): 將每個 source 對象自身的可枚舉屬性復(fù)制到 target 對象上,不包括原型鏈上的屬性和不可枚舉屬性。只有有一個參數(shù)不是對象,就會拋出 TypeError 錯誤。遇到同名屬性,排在后面的會覆蓋前面的:

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

對于屬性名是 symbol 的可枚舉屬性也會被復(fù)制:

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

對于同名屬性存在嵌套對象,外層會被直接替換:

Object.assign({a:{b:"c",d:"e"}}, {a:{b:"hello"}});     //{a:{b:"hello"}}

可以用 Object.assign處理數(shù)組,但會視其為對象:

Object.assign([1,2,3], [4,5]);     //[4, 5, 3]

技巧:為對象添加屬性方法

Object.assign(String.prototype, {
  newProperty: "value",
  newFunction: function(){}
})

技巧:克隆對象

Object.assign({},origin);

技巧:為對象添加屬性方法

Object.assign(target, ...source);

技巧:為對象添加屬性方法

const DEFAULT_OPTION = {   //默認(rèn)值
  a: 1,
  b: 2
};
function processContent(newOption){
  return Object.assign({}, DEFAULT_OPTION, newOption);
}
//設(shè)置屬性應(yīng)該是基本類型,否則會因?yàn)樯羁截惓鰡栴}
對象屬性的可枚舉性與遍歷

以下6個操作會忽略不可枚舉的屬性

for...in循環(huán)

Object.keys()

JSON.stringify()

Object.assign()

Reflect.enumerate()

擴(kuò)展運(yùn)算符 ...

以下4個方法不忽略不可枚舉屬性

Object.getOwnPropertyNames()

Object.getOwnPropertySymbols()

Reflect.ownKeys()

以上9個方法中,只有2個會操作包含繼承到的屬性

for...in循環(huán)

Reflect.enumerate()

以上9個方法中,只有1個方法可以獲得 Symbol 屬性

Object.getOwnPropertySymbols()

除此之外需要強(qiáng)調(diào)的是 ES6 中,所有 class 的原型方法都是不可枚舉的:

Object.getOwnPropertyDescriptor(class{foo(){}}.prototype, foo).enumerable;  //false

ES6 起,有了7中遍歷屬性的方法:

for...in: 循環(huán)遍歷對象自身和繼承到的可枚舉屬性,不包括 Symbol 屬性

Object.keys(obj): 返回包含自身可枚舉屬性的屬性名數(shù)組,不包含 Symbol 屬性

Object.getOwnPropertyNames(obj): 同上,但包括不可枚舉屬性

Object.getOwnPropertySymbols(obj): 返回自身所有 Symbol 屬性名的數(shù)組,包括不可枚舉屬性

Reflect.ownKey(obj): 返回自身所有屬性名數(shù)組,包括不可枚舉屬性和 Symbol 屬性名

Reflect.enumerate(): 返回一個 Iterator, 用來遍歷對象自身及繼承到的可枚舉屬性,不包括 Symbol 屬性;和 for...in 一樣

for...of: 只能遍歷具有 Iterator 接口的對象,具體作用范圍由 iterator 決定,遍歷沒有 iterator 的對象會報(bào)錯

以上方法除了 for...of 以外,遍歷順序?yàn)椋?/p>

首先遍歷所有屬性名為數(shù)字的屬性,按數(shù)字大小排序;

其次遍歷所有屬性名為字符串的屬性,按屬性生成時間排序;

最后遍歷所有屬性名為 Symbol 的屬性,按屬性生成時間排序;

對象的__proto__屬性

這是個很老很老的屬性,在大家想期待下,ES6終于把它寫進(jìn)去了,嗯?...是寫進(jìn)附錄了。這個屬性用來讀寫當(dāng)前的對象的原型對象obj.constructor.prototype

從本質(zhì)上來講,__proto__ 是定義在Object.prototype 上的一個存取器函數(shù):

function isObject(a){
  return Object(a) === a;
}
Object.defineProperty(Object.prototype, "__proto__", {
  get(){
    let _thisObj = Object(this);
    return Object.getPrototypeOf(_thisObj);
  },
  set(proto){
    if(this == null) throw new TypeError();
    if(!isObject(this) || !isObject(proto)) return undefined;
    let status = Object.setPrototypeOf(this, proto);
    if(! status) throw new TypeError();
  }
});

但是,還是不建議使用這個東西,畢竟看它這名字就是個內(nèi)部屬性,因?yàn)樗辛瞬患?,但不保證所以終端都能用,所以ES6推薦用下面這兩個屬性:

Object.setPrototypeOf(obj, newProto);   //寫
Object.getPrototypeOf(obj);   //讀

簡單舉一個例子:

function Rectangle(){}
var rec = new Rectangle();
Object.getPrototypeOf(rec) === Rectangle.prototype;    //true
Object.setPrototypeOf(rec, Object.prototype);
Object.getPrototypeOf(rec) === Rectangle.prototype;    //false

當(dāng)然如果你把一個對象的原型設(shè)置成了 null, 也是可以的,只是,它不具備任何你聽說過的方法了:

var o = Object.setPrototypeOf({}, null);
//等價于 var o = {"__proto__": null};
Object.getPrototypeOf(o);                //null
o.toString();                    //TypeError: o.toString is not a function
對象的擴(kuò)展運(yùn)算符

這是 ES7 的一個提案, babel可以使用器部分功能使用。

rest參數(shù)

用法和數(shù)組中很類似,這里不再過多贅述,直接看幾個例子吧:

var {x,y,...z}  = {x: 1, y: 2, a: 3, d: 4}; //x=1, y=2, z={a: 3, d: 4}

值得強(qiáng)調(diào)的是, 對象的rest參數(shù)形式執(zhí)行的是淺拷貝,賦值得到的是原對象的引用:

let obj = {a: {b: 1}};
let {...x} = obj;
obj.a.b = 2;
console.log(x.a.b);    //2

此外 rest 不會復(fù)制不可枚舉屬性和繼承自原型的屬性:

var p = {a: 0};
var o = {b: 2};
var o = Object.defineProperty(o, "foo", {
  value: 2,
  configurable: true,
  enumerable: false,
  writable: true
});
Object.setPrototypeOf(o, p);
var u = { ...p };
console.log(u);    //{b:2}

擴(kuò)展運(yùn)算符

復(fù)制參數(shù)對象所有可遍歷屬性到當(dāng)前對象中:

var o1 = {a: 1, b: 2};
var n = { ...o1 };    //n={a: 1, b: 2};
//相當(dāng)于
var n = Object.assign({}, o1);

可以用擴(kuò)展運(yùn)算符合并多個對象, 排后的屬性會覆蓋之前的屬性:

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

注意一點(diǎn):如果擴(kuò)展運(yùn)算符的參數(shù)對象有 get 方法,該方法會被執(zhí)行:

var a = {o:1,p:2,m:4};
var withoutError = {
  ...a,
  get x(){
    throw new Error();
  }
};           //不報(bào)錯
var withError = {
  ...a,
  ...{get x(){
    throw new Error();
  }}
};           //報(bào)錯

如果擴(kuò)展對象是 null 或 undefined,會被忽略,不報(bào)錯

var o = { ...null,  ...undefined};    //不報(bào)錯
console.log(o);    //{}

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

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

相關(guān)文章

  • ECMAScript6 新特性——“數(shù)值擴(kuò)展

    摘要:二進(jìn)制和八進(jìn)制表示法提供了二進(jìn)制和八進(jìn)制數(shù)值的新的寫法,分別用前綴或和或表示。用來檢查是否為有窮以及是否為這兩個新方法只對數(shù)值有效,非數(shù)值一律返回。引入了和這兩個常量,用來表示這個范圍的上下限。因?yàn)橛芯认拗?,超過的次方的值無法精確表示。 1 二進(jìn)制和八進(jìn)制表示法 ES6提供了二進(jìn)制和八進(jìn)制數(shù)值的新的寫法,分別用前綴0b(或0B)和0o(或0O)表示。 console.log(0b10...

    Dean 評論0 收藏0
  • ECMAScript6(3):數(shù)值類型擴(kuò)展

    摘要:數(shù)值類型擴(kuò)展類型新增了如下特性支持二進(jìn)制和八進(jìn)制二進(jìn)制用或開頭八進(jìn)制用或開頭新加方法判斷一個數(shù)字是否有限方法判斷一個變量是否。值得注意的是如果將非數(shù)值傳入這兩個函數(shù)一律返回。對于無法轉(zhuǎn)換為數(shù)值的參數(shù)返回符合函數(shù)。 數(shù)值類型擴(kuò)展 Number 類型新增了如下特性: 支持二進(jìn)制和八進(jìn)制 二進(jìn)制用 0b 或 0B 開頭, 八進(jìn)制用 0o 或 0O 開頭: Number(0b1101); ...

    Martin91 評論0 收藏0
  • ECMAScript6 新特性——“對象擴(kuò)展

    摘要:屬性的簡潔表示法允許直接寫入變量和函數(shù)作為對象的屬性和方法。,中有返回一個數(shù)組,成員是參數(shù)對象自身的不含繼承的所有可遍歷屬性的鍵名。對象的擴(kuò)展運(yùn)算符目前,有一個提案,將解構(gòu)賦值擴(kuò)展運(yùn)算符引入對象。 1 屬性的簡潔表示法 ES6允許直接寫入變量和函數(shù)作為對象的屬性和方法。 寫入屬性 var name = value; var obj = { name }; console.log...

    Clect 評論0 收藏0
  • ECMAScript6 新特性——“數(shù)組擴(kuò)展

    摘要:原來的也被修改了數(shù)組實(shí)例的喝方法,用于找出第一個符合條件的數(shù)組成員。它的參數(shù)是一個回調(diào)函數(shù),所有數(shù)組成員依次執(zhí)行該回調(diào)函數(shù),直到找出第一個返回值為的成員,然后返回該成員。數(shù)組實(shí)例的方法使用給定值,填充一個數(shù)組。 1 Array.from() Array.from方法用于將兩類對象轉(zhuǎn)為真正的數(shù)組:類似數(shù)組的對象(array-like object)和可遍歷(iterable)的對象(包括...

    Eminjannn 評論0 收藏0
  • ECMAScript6 新特性——“函數(shù)擴(kuò)展

    摘要:返回空字符串,返回將一個具名函數(shù)賦值給一個變量,則和的屬性都返回這個具名函數(shù)原本的名字。不可以使用對象,該對象在函數(shù)體內(nèi)不存在。等到運(yùn)行結(jié)束,將結(jié)果返回到,的調(diào)用幀才會消失。 1 函數(shù)參數(shù)的默認(rèn)值 ES6允許為函數(shù)的參數(shù)設(shè)置默認(rèn)值,即直接寫在參數(shù)定義的后面: function log(x = message.,y = duration infomation.) { consol...

    Jiavan 評論0 收藏0

發(fā)表評論

0條評論

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