深切明白ES6笔记(四)扩大的对象功用

主要知识点有对象种别、属性速记法、要领简写、需盘算属性名、Object.is()要领、Object.assign()要领、可许可反复的属性、自有属性的罗列递次、Object.setPrototypeOf()要领、super援用、要领定义

《深切明白ES6笔记(四)扩大的对象功用》

《深切明白ES6》笔记 目次

对象种别

  • 一般对象:具有 JS 对象一切默许的内部行动。
  • 奇特对象:其内部行动在某些方面有别于默许行动。
  • 规范对象:在 ES6 中被定义的对象,比方 Array 、 Date ,等等。规范对象可所以一般的,也可所以奇特的。
  • 内置对象:在剧本最先运转时由 JS 运转环境供应的对象。一切的规范对象都是内置对象。

对象字面量语法的扩大

属性初始化器的速记法

属性初始化器的速记法可以用来消弭属性名和当地变量的反复状况,可以运用作用域内的变量值赋值给同名属性:

ES5 及更早版本中:

function createPerson(name, age) {
    return {
        name: name,
        age: age
    };
}

ES6简写:

function createPerson(name, age) {
    return {
        name,
        age
    };
}

要领简写

在对象字面量的写法中,为一个对象增加一个要领,须要指定对象的属性以及详细的函数声明。ES6供应了一种要领简写语法,经由过程省略function关键字,可以让为对象增加要领的语法越发简约。
ES5中的写法:

var person = {
    name: "Nicholas",
    sayName: function() {
        console.log(this.name);
    }
};

ES6简写语法:

var person = {
    name: "Nicholas",
    sayName() {
        console.log(this.name);
    }
};

需盘算属性名

需盘算属性名划定规矩许可对象字面量中属性名是变量、字符串字面量或许由变量盘算而得的,详细写法是经由过程方括号[]包括属性名。

var lastName = "last name";
var person = {
    "first name": "Nicholas",
    [lastName]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person[lastName]); // "Zakas"

var suffix = " name";
var person = {
    ["first" + suffix]: "Nicholas",
    ["last" + suffix]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); // "Zakas"

const id = 5
const obj = {
  [`my-${id}`]: id
}
console.log(obj['my-5']) // 5

新的要领:Object.is()和Object.assign()

Object.is() 要领

JS中比较两个值是不是雷同的时刻会运用严厉即是运算符===,然则,运用严厉运算符式,+0和-0会以为这两者是相称的,而NaN===NaN是不相称的,运用Object.is()要领来推断这两者状况与运用严厉相称符会有所差别,其他状况和运用严厉相称运算符基础一致;

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

Object.assign() 要领

混入( Mixin )是在 JS 中组合对象时最盛行的形式。在一次混入中,一个对象会从另一个对象中吸收属性与要领。
下面是一个mixin要领的完成,这个要领完成的是浅拷贝。将b对象的属性拷贝到了a对象,合并成一个新的对象。

//mixin不只有这一种完成要领。
function mixin(receiver, supplier) {
  Object.keys(supplier).forEach((key) => {
    receiver[key] = supplier[key]
  })
  return receiver
}

let a = {name: 'sb'};
let b = {
  c: {
    d: 5
    }
  }
console.log(mixin(a, b)) // {"name":"sb","c":{"d":5}}

写如许一个mixin要领是不是是很烦,而且每一个项目都得引入这个要领,如今,ES6给我们供应了一个现成的要领Object.assign()来做mixin的事变。

假定要完成上面的mixin要领,你只须要给Object.assign()传入参数即可。

console.log(Object.assign(a, b))// {"name":"sb","c":{"d":5}}

反复的对象字面量属性

ES5 严厉形式为反复的对象字面量属性引入了一个搜检,若找到反复的属性名,就会抛出毛病。

"use strict";
var person = {
    name: "Nicholas",
    name: "Greg" // 在 ES5 严厉形式中是语法毛病
};

ES6 移除了反复属性的搜检,严厉形式与非严厉形式都不再搜检反复的属性。当存在反复属性时,排在背面的属性的值会成为该属性的现实值:

"use strict";
var person = {
    name: "Nicholas",
    name: "Greg" // 在 ES6 严厉形式中不会失足
};
console.log(person.name); // "Greg"

自有属性的罗列递次

ES5 并没有定义对象属性的罗列递次,而是把该题目留给了 JS 引擎厂商。而 ES6 则严厉定义了对象自有属性在被罗列时返回的递次。这对 Object.getOwnPropertyNames() 与Reflect.ownKeys)怎样返回属性造成了影响,还一样影响了Object.assign() 处置惩罚属性的递次。
自有属性罗列时基础递次以下:

  1. 一切的数字范例键,按升序分列。
  2. 一切的字符串范例键,按被增加到对象的递次分列。
  3. 一切的标记范例(详见第六章)键,也按增加递次分列。
const state = {
  id: 1,
  5: 5,
  name: "eryue",
  3: 3
}

Object.getOwnPropertyNames(state) 
//["3","5","id","name"] 罗列key

Object.assign(state, null)
//{"3":3,"5":5,"id":1,"name":"eryue"} 

for-in 轮回的罗列递次仍未被明确规定,由于并不是一切的 JS 引擎都采纳雷同的体式格局。而 Object.keys() 和 JSON.stringify() 也运用了与 for-in 一样的罗列递次。

更壮大的原型

一般来说,对象的原型会在经由过程组织器或 Object.create() 要领建立该对象时被指定。
ES5 增加了 Object.getPrototypeOf() 要领来从恣意指定对象中获取其原型;
缺乏在初始化以后变动对象原型的规范要领。

修正对象的原型

ES6 经由过程增加 Object.setPrototypeOf() 要领而改变了这类假定,此要领许可你修正恣意指定对象的原型。它接收两个参数:须要被修正原型的对象,以及将会成为前者原型的对象

let person = {
    getGreeting() {
        return "Hello";
    }
};
let dog = {
    getGreeting() {
        return "Woof";
    }
};
// 原型为 person
let friend = Object.create(person);
console.log(friend.getGreeting()); // "Hello"
console.log(Object.getPrototypeOf(friend) === person); // true
// 将原型设置为 dog
Object.setPrototypeOf(friend, dog);
console.log(friend.getGreeting()); // "Woof"
console.log(Object.getPrototypeOf(friend) === dog); // true

运用 super 援用的简朴原型接见

可以运用super援用,来接见原型中的要领:

const proto = {
  foo: 'hello'
};

const obj = {
  foo: 'world',
  find() {
    return super.foo;
  }
};

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

注重,super关键字示意原型对象时,只能用在对象的简写要领当中,用在其他地方都邑报错。

// 报错
const obj = {
  foo: super.foo
}

// 报错
const obj = {
  foo: () => super.foo
}

// 报错
const obj = {
  foo: function () {
    return super.foo
  }
}

javaScript 引擎内部,super.foo等同于Object.getPrototypeOf(this).foo(属性)或Object.getPrototypeOf(this).foo.call(this)(要领)。

const proto = {
  x: 'hello',
  foo() {
    console.log(this.x);
  },
};

const obj = {
  x: 'world',
  foo() {
    super.foo();
  }
}

Object.setPrototypeOf(obj, proto);

obj.foo() // "world"

上面代码中,super.foo指向原型对象proto的foo要领,然则绑定的this却照样当前对象obj,因而输出的就是world。

正式的“要领”定义

ES6 则正式做出了定义:要领是一个具有 [[HomeObject]] 内部属性的函数,此内部属性指向该要领所属的对象。

let person = {
// 要领
    getGreeting() {
        return "Hello";
    }
};
// 并不是要领
function shareGreeting() {
    return "Hi!";
}

大多数状况下,这类差别并不主要,但是运用 super 援用时就完整差别了。

let person = {
    getGreeting() {
        return "Hello";
    }
};
// 原型为 person
let friend = {
    getGreeting() {
        return super.getGreeting() + ", hi!";
    }
};
Object.setPrototypeOf(friend, person);
console.log(friend.getGreeting()); // "Hello, hi!"
    原文作者:sevencui
    原文地址: https://segmentfault.com/a/1190000016092396
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞