今天在看一本書(shū),只有小小的一百多頁(yè)枫振,半天快看完半本了,名字叫《學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)預(yù)算法》.看下來(lái)的感受就是萤彩,短小精悍粪滤,適合復(fù)習(xí)一下大學(xué)學(xué)的數(shù)據(jù)結(jié)構(gòu)。
在讀到使用js實(shí)現(xiàn)棧的結(jié)構(gòu)的時(shí)候乒疏,看到它的寫(xiě)法是之前的構(gòu)造函數(shù)繼承的寫(xiě)法额衙,突發(fā)奇想,想用es6的語(yǔ)法改寫(xiě)一下試試怕吴,這是書(shū)上的寫(xiě)法:
function Stack() {
var items = []
this.push = function(element) {
items.push(element)
}
this.pop = function() {
return items.pop()
}
this.peek = function() {
return items[items.length - 1]
}
this.isEmpty = function() {
return items.length === 0
}
this.size = function() {
return items.length
}
this.clear = function() {
items = []
}
this.print = function() {
console.log(items.toString());
}
}
算不上是類(lèi)的寫(xiě)法窍侧,只是在函數(shù)里定義了幾個(gè)方法,去修改items的值而已转绷,新寫(xiě)的寫(xiě)法如下:
class Strack {
constructor() {
this.item = []
}
// 棧的壓入
push(value) {
this.item.push(value)
}
// 棧的彈出
pop() {
this.item.pop()
}
// 返回棧頂元素
peek() {
let lengthTemp = this.item.length
return this.item[lengthTemp - 1]
}
// 判空
isEmpty() {
return this.item.length === 0
}
// remove all
clear() {
this.item = []
}
// sum all items
size() {
return this.item.length
}
}
export default Strack
使用:
const newStrack = new Strack()
newStrack.push(1)
newStrack.push(2)
newStrack.push(3)
newStrack.pop()
console.log(newStrack, newStrack);
console.log('newStrack is empty? : ', newStrack.isEmpty());
很簡(jiǎn)單伟件,但是沒(méi)有弄清楚,這樣寫(xiě)和以前的寫(xiě)法有什么的本質(zhì)的區(qū)別议经,這一點(diǎn)需要去研究一下斧账。
基于類(lèi)的面向?qū)ο蠛突谠偷拿嫦驅(qū)ο?/h3>
基于類(lèi)的面向?qū)ο?br>
在基于類(lèi)的面向?qū)ο笳Z(yǔ)言中(比如Java和C++)谴返, 是構(gòu)建在類(lèi)(class)和實(shí)例(instance)上的。其中類(lèi)定義了所有用于具有某一特征對(duì)象的屬性咧织。類(lèi)是抽象的事物嗓袱, 而不是其所描述的全部對(duì)象中的任何特定的個(gè)體。另一方面习绢, 一個(gè)實(shí)例是一個(gè)類(lèi)的實(shí)例化渠抹,是其中的一個(gè)成員。
基于原型的面向?qū)ο?br>
在基于原型的語(yǔ)言中(如JavaScript)并不存在這種區(qū)別:它只有對(duì)象闪萄!不論是構(gòu)造函數(shù)(constructor)梧却,實(shí)例(instance),原型(prototype)本身都是對(duì)象败去》藕剑基于原型的語(yǔ)言具有所謂的原型對(duì)象的概念,新對(duì)象可以從中獲得原始的屬性圆裕。
基于類(lèi)的面向?qū)ο?br> 在基于類(lèi)的面向?qū)ο笳Z(yǔ)言中(比如Java和C++)谴返, 是構(gòu)建在類(lèi)(class)和實(shí)例(instance)上的。其中類(lèi)定義了所有用于具有某一特征對(duì)象的屬性咧织。類(lèi)是抽象的事物嗓袱, 而不是其所描述的全部對(duì)象中的任何特定的個(gè)體。另一方面习绢, 一個(gè)實(shí)例是一個(gè)類(lèi)的實(shí)例化渠抹,是其中的一個(gè)成員。
基于原型的面向?qū)ο?br> 在基于原型的語(yǔ)言中(如JavaScript)并不存在這種區(qū)別:它只有對(duì)象闪萄!不論是構(gòu)造函數(shù)(constructor)梧却,實(shí)例(instance),原型(prototype)本身都是對(duì)象败去》藕剑基于原型的語(yǔ)言具有所謂的原型對(duì)象的概念,新對(duì)象可以從中獲得原始的屬性圆裕。
所以广鳍,在JavaScript中有一個(gè)很有意思的proto屬性(ES6以下是非標(biāo)準(zhǔn)屬性)用于訪問(wèn)其原型對(duì)象, 你會(huì)發(fā)現(xiàn)葫辐,上面提到的構(gòu)造函數(shù)搜锰,實(shí)例,原型本身都有proto指向原型對(duì)象耿战。其最后順著原型鏈都會(huì)指向Object這個(gè)構(gòu)造函數(shù)蛋叼,然而Object的原型對(duì)象的原型是null,不信剂陡, 你可以嘗試一下Object.prototype.proto === null為true狈涮。然而typeof null === 'object'為true。到這里鸭栖, 我相信你應(yīng)該就能明白為什么JavaScript這類(lèi)基于原型的語(yǔ)言中沒(méi)有類(lèi)和實(shí)例的區(qū)別歌馍, 而是萬(wàn)物皆對(duì)象!
封裝
js實(shí)現(xiàn)封裝的辦法和java其實(shí)差不多
function Person(name) {
this.name = name
var smallName = 'xiaoming'
}
Person. prototype.sayHi = function() {
console.log('hello')
}
上面代碼晕鹊,定義了一個(gè)私有變量smallName和一個(gè)方法sayHi松却,我們并不能通過(guò)實(shí)例化Person去訪問(wèn)smallName,還有我們也不知道sayH是怎么實(shí)現(xiàn)的溅话,這樣就實(shí)現(xiàn)了封裝晓锻。
繼承和多態(tài)
在es6以前,我最常使用的繼承方式是使用protutype
function Person(name) {
this.name = name
this.career = function() {
console.log('I am a Person' + name)
}
}
Person.prototype.sayHi = function () {
console.log('my name is ' + this.name);
}
function Teacher(career) {
this.career = function() {
console.log('I am a ' + career + ', my name is ' + this.name)
}
}
Teacher.prototype = new Person('Ma')
Teacher.prototype.constructor = Teacher
var personOne = new Person('Zhang')
personOne.career()
var teaMa = new Teacher('math')
console.log(teaMa);
teaMa.career()
Person是一個(gè)父類(lèi)飞几,子類(lèi)Teacher想要繼承父類(lèi)砚哆,就在它的prototype指向變?yōu)橐粋€(gè)新的父類(lèi)實(shí)例,同時(shí)將prototype的constructor屬性指向自己,如果constructor屬性不指回自己的話屑墨,將會(huì)導(dǎo)致
console.log(teaMa.constructor === Person) // true
這是一個(gè)重大錯(cuò)誤躁锁,明明是Teacher實(shí)例化出來(lái)的纷铣,結(jié)果顯示父類(lèi)實(shí)例化的......
新實(shí)例化的Teacher有父類(lèi)的name屬性,這就實(shí)現(xiàn)了繼承战转,同時(shí)Person和Teacher類(lèi)都有career方法搜立,他們通過(guò)函數(shù)覆蓋實(shí)現(xiàn)了多態(tài)。