對象的傳統(tǒng)表示法
let person = {
????"name":"張三",
????"say":function(){
? ??????alert("你好嗎?");
????}
}
ES6中的簡潔寫法
var name = "Zhangsan";
var age = 12;//傳統(tǒng)的屬性寫法
var person = {
? ? ? ?"name":name,
? ? ? ?"age":age
};? ?console.log(person);
//結(jié)果:{name: "Zhangsan", age: 12}//ES6的屬性寫法
? ?var person = {name,age};
? ?console.log(person);
? ?//結(jié)果:{name: "Zhangsan", age: 12}
????對象的屬性可以這樣簡寫,那么對象的方法表示:
//傳統(tǒng)的表示法
var person = {
say:function(){
alert('這是傳統(tǒng)的表示法');
????}
};//ES6的表示法
var person = {
????say(){
? ??????alert('這是ES6的表示法');
? ? }
};
屬性名可以是表達(dá)式?
????用字面量定義一個對象的時候,可以用變量或者表達(dá)式作為對象的屬性名或者方法名。
var f = "first";
var n = "Name";
var s = "say";
var h = "Hello";
var person = {
????[f+n ] : "Zhang",
????[s+h ](){
????????return "你好嗎?";
????}
};? ?console.log(person.firstName);
? ?//結(jié)果:Zhang? ?console.log(person.sayHello());
? ?//結(jié)果:你好嗎?
es6中的屬性名可以有空格:
let foods = {};
foods.dessert = '蛋糕';
foods['hot drink'] = '可樂' //console.log(foods)
創(chuàng)建新對象Object.create()
? ??Object.create()?方法會使用指定的原型對象及其屬性去創(chuàng)建一個新的對象。
let breakfast = {
? ? getDrink() {
? ? ? ? return'咖啡';
? ? }
};
let dinner = {
? ? getDrink() {
? ? ? ? return'牛奶';
? ? }
};
let sunday = Object.create(breakfast);
console.log(sunday.getDrink())
Object.is( )函數(shù)
????方括號中還可以用變量的形式引入:ES5 比較兩個值是否相等,只有兩個運(yùn)算符:相等運(yùn)算符(==)和嚴(yán)格相等運(yùn)算符(===)。它們都有缺點(diǎn),前者會自動轉(zhuǎn)換數(shù)據(jù)類型,后者的NaN不等于自身,以及+0等于-0。 JavaScript 缺乏一種運(yùn)算,在所有環(huán)境中,只要兩個值是一樣的,它們就應(yīng)該相等。
????ES6 提出 “Same-value equality” (同值相等)算法,用來解決這個問題。Object.is就是部署這個算法的新方法。它用來比較兩個值是否嚴(yán)格相等,與嚴(yán)格比較運(yùn)算符( === )的行為基本一致,Object.is()括號中放的是對比的兩個值。
+0 === -0//true
NaN === NaN// false
Object.is(+0, -0)// false
Object.is(NaN, NaN)// true
Object.assign()函數(shù)
????把一個對象的值復(fù)制到另一個對象里,Object.assign()方法用于將所有可枚舉的屬性的值從一個或多個源對象復(fù)制到目標(biāo)對象。它將返回目標(biāo)對象。
????Object.assign(target, ...sources)
參數(shù)
target
目標(biāo)對象。
sources
(多個)源對象。
返回值
目標(biāo)對象。
如果目標(biāo)對象中的屬性具有相同的鍵,則屬性將被源中的屬性覆蓋。后來的源的屬性將類似地覆蓋早先的屬性。
let breakfast = {drink: '咖啡'},
? ? foods = {drink: '蛋糕'};Object.assign(
? ? breakfast,
? ? foods
)console.log(breakfast) //{drink: "蛋糕"}
????Object.assign( )函數(shù)的參數(shù)還可以是多個(至少是兩個)。
//這個充當(dāng)目標(biāo)對象
? let target = {"a":1};? ?//這個充當(dāng)源對象
? ?let origin1 = {"b":2,"c":3};? ?//這個充當(dāng)源對象
? ?let origin2 = {"d":4,"e":5};? ?Object.assign(target,origin1,origin2);
? ?//打印target對象出來看一下
? ??console.log(target);? ?//結(jié)果 {a: 1, b: 2, c: 3, d: 4, e: 5}
Object.getPrototypeOf( )函數(shù)
? ? 函數(shù)作用:獲取一個對象的prototype屬性。這里的對象我們用一個自定義類實(shí)例出來的對象來演示。(這里涉及到了javascript的面向?qū)ο?,后面拓展?/p>
//自定義一個Person類(函數(shù))
function Person(){}
????//函數(shù)都有一個預(yù)屬性prototype對象
? ?Person.prototype = {
????//給prototype對象添加一個say方法
????????say(){
? ??????????console.log('hello');
????????}
????};? ?//實(shí)例化Person對象,賦值給變量allen
? ?let allen = new Person();
? ?//調(diào)用類的say方法
? ?allen.say();
? ?//結(jié)果:打印出hello? ?//獲取allen對象的prototype屬性
? ?Object.getPrototypeOf(allen);
? ?//結(jié)果:打印{say:function(){.....}}
Object.setPrototypeOf()函數(shù) (現(xiàn)在這個方法只是草案?推薦用__proto__)
????設(shè)置一個對象的prototype屬性。
? ??Object.setPrototypeOf()?方法設(shè)置一個指定的對象的原型 ( 即, 內(nèi)部[[Prototype]]屬性)到另一個對象或null。
let breakfast = {
? ? getDrink() {
? ? ? ? return '咖啡';
? ? }
};
let dinner = {
? ? getDrink() {
? ? ? ? return '牛奶';
? ? }
};
let sunday = Object.create(breakfast);
console.log(sunday.getDrink());
console.log(Object.getPrototypeOf(sunday) === breakfast); // 判斷原型是否相同
Object.setPrototypeOf(sunday, dinner);
console.log(sunday.getDrink())
__proto__
let breakfast = {
? ? getDrink() {
? ? ? ? return'咖啡';
? ? }
};
let dinner = {
? ? getDrink() {
? ? ? ? return'牛奶';
? ? }
};
let sunday = {
? ? __proto__: breakfast
}
console.log(sunday.getDrink());
console.log(Object.getPrototypeOf(sunday) === breakfast);
sunday.__proto__ = dinner;
console.log(sunday.getDrink());
console.log(Object.getPrototypeOf(sunday) === dinner);
super (得到方法返回的內(nèi)容)
? ??super?關(guān)鍵字用于調(diào)用一個對象的父對象上的函數(shù)。
let breakfast = {
? ? getDrink() {
? ? ? ? return'咖啡';
? ? }
};
let dinner = {
? ? getDrink() {
? ? ? ? return'牛奶';
? ? }
};
let sunday = {
? ? __proto__: breakfast,
? ? getDrink() {
? ? ? ? return'返回了 ' + super.getDrink();
? ? }
}
console.log(sunday.getDrink())
迭代器 Iterators (輪流交換)
? ??Iterator?函數(shù)返回一個對象,它實(shí)現(xiàn)了遺留的迭代協(xié)議,并且迭代了一個對象的可枚舉屬性。
function chef(foods) {
? ? let i = 0;
? ? return {
? ? ? ? next() {
? ? ? ? ? ? let done = (i >=foods.length);
? ? ? ? ? ? let value = !done ? foods[i++] : undefined;
? ? ? ? ? ? return {
? ? ? ? ? ? ? ? value: value,
? ? ? ? ? ? ? ? done: done
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
let yang =chef(['西紅柿', '雞蛋']);
console.log(yang.next());
console.log(yang.next());
console.log(yang.next());
迭代生成器 Generators?
function* chef(){?
?yield '西紅柿'; yield '雞蛋';?
} ?
let yang = chef();? ?
console.log(yang.next());
????還可以以數(shù)組的形式傳入
function* chef(foods){ for (let i = 0; i<foods.length; i++){
????yield foods[i];
?}
}??let yang = chef(['西紅柿', '雞蛋']);
?console.log(yang.next());
Classes?類
ECMAScript 2015 中引入的 JavaScript類主要是 JavaScript 現(xiàn)有的基于原型的繼承的語法糖。?類語法不是向JavaScript引入一個新的面向?qū)ο蟮睦^承模型。JavaScript類提供了一個更簡單和更清晰的語法來創(chuàng)建對象并處理繼承。
?類實(shí)際上是個“特殊的函數(shù)”,就像你能夠定義的函數(shù)表達(dá)式和函數(shù)聲明一樣,類語法有兩個組成部分:類表達(dá)式和類聲明。
定義一個類的一種方法是使用一個類聲明。要聲明一個類,你可以使用帶有class關(guān)鍵字的類名(這里是“Rectangle”)。
class Rectangle {
? constructor(height, width) {
? ? this.height = height;
? ? this.width = width;
? }
}
提升
函數(shù)聲明和類聲明之間的一個重要區(qū)別是函數(shù)聲明會聲明提升,類聲明不會。你首先需要聲明你的類,然后訪問它,否則像下面的代碼會拋出一個ReferenceError:
let p =new Rectangle();
?// ReferenceError
class Rectangle {}
聲明實(shí)例使用類
class Chef {
? ? constructor(food) {
? ? ? ? this.food = food;
? ? }
? ? cook() {
? ? ? ? console.log(this.food)
? ? }
}
let yang =newChef('番茄');
yang.cook();
類中的?get (得到東西的方法)與?set(設(shè)置東西的方法)
class Chef {
? ? constructor(food) {
? ? ? ? this.food = food;
? ? ? ? this.dish = [];
? ? }
? ? get menu() {
? ? ? ? return this.dish;
? ? }
? ? set menu(dish) {
? ? ? ? this.dish.push(dish);
? ? }
? ? cook() {
? ? ? ? console.log(this.food)
? ? }
}
let yang = new Chef();
console.log(yang.menu = '番茄');
console.log(yang.menu = '雞蛋');
console.log(yang.menu)
javascript的面向?qū)ο?/h3>
????Javascript本身不是一種面向?qū)ο蟮木幊陶Z言,在ES5中,它的語法中也沒有class(類的關(guān)鍵字),但是,開發(fā)者可以利用對象的原型prototype屬性來模擬面向?qū)ο筮M(jìn)行編程開發(fā)。
//構(gòu)造函數(shù)模擬創(chuàng)建一個Dog類
? ?function Dog(name){
????????this.name = name;
????}
? ?//把一些屬性和方法,定義在prototype對象上
? ?Dog.prototype = {
????"type":"動物",
????"say":function(){
? ??????alert(
????????????"名字叫"+this.name);
????????}
????};
? ?//實(shí)例化
? ?var dog = new Dog('旺財');
? ?//調(diào)用say方法
? ?dog.say();
? ?//結(jié)果:名字叫旺財
????上面的案例告訴我們,模擬面向?qū)ο缶幊逃袔讉€關(guān)鍵步驟:1、構(gòu)造函數(shù);2、給prototype對象添加屬性和方法;3、實(shí)例化;4、通過實(shí)例化后的對象調(diào)用類的方法或者屬性。