# js面向對象的編程基礎
> 今天面試的時候和HR談了很久,其中問道了面向對象的編程的基礎。自己回答的不算太好吧,雖然回答了絕大部分。今天就做個簡單的總結吧
### 簡單的繼承
`
~~~
// parentClass
function superclass () {
this.superValue = 'this is parentClass';
}
~~~
// 添加原型共有方法
superclass.prototype.getsuperVaule = function () {
return this.superValue;
}
// childrenClass
function subclass () {
this.subclass = 'this is childclass';
}
//添加子類原型共有方法
subclass.prototype = new superClass();
//為子類添加構造方法
subclass.prototype.getVaule = function () {
return this.subValue;
}
`
## 測試使用
~~~
var instance = new subClass();
console.log(instance.getValue)
console.log(instance.getsuperValue)
~~~
## 解析
其實本質也就是通過將父類的實例賦給子類。之所以將父類實例化,是因為,類要通過prototype才可以訪問prototype上面的方法。而對象(也就是類的實例化)可以直接訪問(內部是通過__proto__)prototype的方法。子類也是同理了。當我們使用new運算符的時候。對象也就可以訪問到prototype上面的方法了。
## 缺點
1. prototype上面的方法是所以子類公用的。如果是引用類型的變量,那么所有的子類都只有公用一個變量。也就是一個子類改變了引用類型的值,其他子類的引用類型的值也會改變。
2. 無法向父類傳遞參數,初始化父類。畢竟我們是通過父類的實例化賦值給子類的原型。所以在子類實例化的時候。父類早就定下來了。
## 構造函數的繼承(經典繼承)
~~~
function superclass (item) {
this.subjects = ['html','css','js'];
this.subjects.push(item)
}
//添加原型共有方法
superclass.prototype.each = function () {
this.subjects.forEach( (item,index) => {
console.log(item)
}
}
// 聲明子類
function subclass (item) {
superclass.call(this,item)
}
~~~
## 測試
~~~
var instance = new subclass('king')
console.log(instance.subjects)
var instance2 = new subclass('luckyman')
console.log(instance2.subjects)
instance2.each(); //會報錯
~~~
## 解析
核心就是通過call或者apply來改變this的指向。將父類的this改變為子類的this。也因為這樣子。父類的this上的方法或者屬性就會定義到子類當中。但是在父類的原型里的this還是指向父類的。(this指向函數賴以執行的環境,可以認為prototype的執行環境永遠都是本身類)。也因此原型上的方法都是無法被繼承的。
## 缺點
1. 無法公用變量或者屬性。原型上的方法也無法被繼承
## 組合繼承
~~~
function supclass(item) {
//值類型共有變量
this.name = name
//引用類型共有屬性
this.books = ['html','css','js']
item && this.books.push(item)
}
//原型方法
superclass.prototype.each() {
this.books.forEach( (item,index) => {
console.log(item);
}
}
//聲明子類
function subclass(item,time) {
supclass.call(this,item);
this.time = time
}
//子類原型
subclass.prototype = new supclass();
//子類原型方法
subclass.prototype.getTime = function () {
console.log(this.time)
}
~~~
## 測試
~~~
var instance1 = new subclass('js book',2017');
instance1.each();
instance1.getTime();
var instance2 = new subclass('高級教程', '2014');
instance2.each();
instance2.getTime();
~~~
## 解析
組合模式本質就是原型繼承和構造函數繼承兩種方式的組合,繼承兩種方式的優點
## 缺點
開銷比較大,在子類的原型上,new了一次父類,在構造函數里又執行了new運算符
所以父類執行了兩次初始化
## 原型式繼承
~~~
function inheritobject (0) {
//聲明過度對象
function F() {}
F.prototype = o;
//返回過度對象的實例,該實例的原型繼承了父類
return new F();
}
~~~
### 解析
這種因為構造函數基本沒有任何的開銷,也可以將F過度類緩存起來。這也是Object.create()方法的實現原理。
### 缺點
1. 引用類型會被所有子類公用
## 寄生繼承
~~~
function createObj (obj) {
// 通過原型繼承方式創建新對象
var o = new inheriteobject(obj);
// 擴展新對象
o.getName = function () {
console.log(name)
}
// 返回對象
return o;
}
~~~
### 測試
~~~
var books = {
name : 'kingEND',
age: 23
}
var subbooks = new createObj (books);
subooks.getName();
~~~
## 最后的繼承者 -- 寄生組合式繼承
~~~
function inheritPrototype (subclass, superclass) {
// 復制一份父類的原型副本保存在變量中
var p = inheritobject(supclass.prototype);
//修正因為重寫子類原型導致子類的constructor 屬性被修改
// 因為p是父類的prototype,所以constructor會指向父類的構造函數
// 而子類的prototype里的constructor應該是指向子類的構造函數
p.constructor = subclass;
// 設置子類的原型
subclass.prototype = p;
}
- 前端
- pc端
- 京東無延時菜單效果
- datapicker組件的編寫
- cursor禁止默認樣式
- 移動端
- web在真機調試
- 有關vue的上拉加載
- 下拉刷新
- vue獲取dom節點
- worker技術
- h5頁面喚醒手機撥號,發短信功能
- 彈出層喚醒擠壓css背景圖片
- 23模式
- 基礎模式
- SMD同步模塊
- canvas
- 點的均勻分布
- 線條繪畫
- canvas常見的全局屬性
- 判斷點在某個區間內
- 保證動畫效果的流暢性
- arc函數學習
- cookies
- 本地服務搭建
- Mint UI框架的學習
- 第一天
- Swiper組件的解析
- loadmore組件
- 二維碼的生成
- 前端優化
- 瀏覽器緩存
- indexdb本地數據庫的使用
- 淺談前端優化
- css漸變屬性
- 前端常用組件學習
- picker組件
- vue
- 模塊下的state訪問
- vue的進階
- npm包的發布
- 淘寶移動端適配問題
- vue的生命周期的理解
- vue的路由學習
- vue自帶的動畫效果
- vue 項目里,img標簽報錯,添加默認圖片
- axios 實現loading加載提示
- qs庫
- vue的v-for指令無法使用在tr、td中
- vue打包之后,npm run dev 空白
- vue 單頁面百度統計
- unix時間轉化
- UI組件的實現
- picker
- upload組件
- js動畫效果
- canvas甜甜圈的編寫
- 瀑布流實現
- 適配問題
- 圖片加載
- js基礎知識
- js數組合并
- 響應布局總結
- 組件開發
- grid組件
- 專題頁面常用布局頁面
- scroll滾動問題
- 項目整理經驗收集
- 畫圖工具應用實現記錄
- 參考線實現
- JCode
- 多條件篩選不用ajax的原因分析
- node
- koa路由下的分塊
- 連接數據庫mysql
- 初步搭建數據庫模型
- java
- spring框架的學習
- maven 搭建web項目
- 建站
- 關聯github
- 雜文
- 后端常用成熟系統
- node實戰練習
- 編寫郵箱通知
- 微信小程序
- 模板之坑
- 模板坑之數據傳入
- 小程序組件化之一
- 有關this的綁定
- 小程序組件化之二
- 小程序分包加載
- tab切換,頁面狀態不更新
- 小程序請求組件(草稿)
- php學習之路
- 文件上傳
- 有關數據庫時間類型的插入
- Ubuntu下的php開啟擴展模塊
- windows系統下的hosts文件位置
- 騰訊云的cos
- thinkPHP
- 模塊設計
- 模型的使用
- ajax的請求異常總結
- apache服務器
- 虛擬主機的建立
- ssh的使用
- ftp服務器配置
- Lamp的搭建
- ftp從零開始配置
- https的配置
- git hooks實現簡單的自動部署
- ubuntu系統登錄遠程ubuntu服務器
- ubuntu
- 新建用戶需要使用sudo
- sftp的文件上傳問題
- 配置apache部分問題總結
- git服務器的搭建
- githook的學習
- ubuntu 虛擬主機搭建
- ubunut的服務器的防火墻的關閉
- 寶塔部署laravel
- 關于寶塔phpmyadmin無法訪問的問題
- 解決碼云每次提交輸入密碼的問題
- mysql
- phpmyadmin的安裝
- 遠程登陸數據庫
- git的使用
- 拉去分支的代碼
- git remote指令
- 學習臨時筆記
- ios兼容性問題
- 蘋果獲取屏幕寬度問題
- toDataURL無法導出圖片
- 蘋果觸屏滾動,下拉刷新問題
- jquery動畫
- jquery的animate無法使用transform
- jquery隊列queue
- css重學之路
- 規范一
- css3的matrix屬性
- 淘寶適配方案
- Yii框架學習
- gd庫的支持安裝
- larval框架學習
- 中間件
- 指令
- 自定義指令生成token
- 微信登錄后端篇
- 寶塔apache配置ssl
- SVN
- PS
- 快捷鍵
- Redis
- Redis在Unbtun下的配置
- 微信公眾號開發
- 測試號配置