### 模式
* 設計模式
* 編碼模式
* 反模式
### 面向對象
首先,`javascript`一切皆對象。
對象的兩種類型:
* 原生的(Native)
>[info] 獨立與宿主環境的`ECMAScript`實現提供的對象
* 主機的(Host)
>[info] 在主機環境中(如:瀏覽器)定義的對象
### 原型(prototype)
當我們創建一個函數時,`javascript`默認給它創建了一個對象屬性`prototype`。
這個`prototype`的屬性值是一個對象,默認只有一個`constructor`的屬性,指向所創建的函數本身。
```js
let Apple = function(){
}
let app = new Apple();
console.log(app.__proto__.constructor == Apple);//true
```
每個對象都有一個隱藏的屬性——`“__proto__”`,這個屬性引用了創建這個對象的函數的`prototype`。
### 函數聲明和函數表達式
* 表達式
```js
//又名匿名函數
var add = function(a,b){
return a+b;
}
add.name;// ""
//命名函數表達式,是函數表達式的一種
var add = function add(a,b){
}
add.name; // "add"
```
* 函數聲明
```js
function foo(){
//函數主體
}
foo.name; // "foo"
```
### apply與call
#### apply
帶有兩個參數,第一個參數是指定將要綁定到該函數內部`this`的一個對象;
第二個參數是一個數組或多個變量參數,這些參數將變成可用于該函數內部的類似數組的`arguments`對象。
如果第一個參數為`null`,那么`this`將指向全局對象。
```js
Function.apply(obj,args)
```
>[info] `apply`方法能劫持另外一個對象的方法,繼承另外一個對象的屬性.
eg:
```js
//定義一個函數
function App(name){
this.name = name;
this.created();
}
//擴展原型
App.prototype={
created:function(){
console.log(`${this.name} has been created!`);
},
destroy:function(reason){
let re = reason || "no reason";
this.destroy_time = new Date().getTime();
console.log(`${this.name} has been destroyed at ${this.destroy_time} for ${re}!`);
}
}
let app = new App('app');
console.log(app.destroy());//app has been destroyed at 1514355097846 for no reason!
let test = {
name:'test'
}
app.destroy.apply(test,["it is test simple"]);//test has been destroyed at 1514355097847 for it is test simple!
```
**簡單概括就是**:
>[danger] 將`app.destroy`的方法,應用到`test`對象上,使得`test`也具有`destroy`的功能。
>換句話說,就是為了改變函數體內部 `this` 的指向
#### call
`call`的用法和功能與`apply`完全一樣,只是接收參數不一樣。
```js
Function.call(obj,[param1[,param2[,…[,paramN]]]])
```
沒有參數數量的限制,參數已參數列表的形式傳遞過來。
#### 應用
* 繼承
```js
function Parent(){
this.name = "parent";
this.age = 18;
this.infomation = "this is a girl";
}
let child = {};
Parent.apply(child);
console.log(child.name)// "parent"
```
* 獲取數組中的最大值
```js
let array = [1,2,3,3,10,0];
let maxVal = Math.max.apply(null,array);
console.log(maxVal);//10
```
#### 還有個bind
```js
obj.bind(thisObj, arg1, arg2, ...);
```
把obj綁定到thisObj,這時候thisObj具備了obj的屬性和方法。與call和apply不同的是,bind綁定后不會立即執行。
```js
function add(j, k){
return j+k;
}
function sub(j, k){
return j-k;
}
add.bind(sub, 5, 3); //不再返回8
add.bind(sub, 5, 3)(); //8
```
### Curry化(柯里化)
>[info] 柯里化(Currying),又稱部分求值(Partial Evaluation),是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,并且返回接受余下的參數而且返回結果的新函數的技術。
一個通用柯里化函數:
```js
let currying = function(fn){
let stored_args = [].slice.call(arguments,1);
console.log(stored_args);//截取第一個參數
return function(){
let args = stored_args.concat([].slice.call(arguments));
return fn.apply(null,args);
}
}
function add(x,y){
return x+y;
}
let result = currying(add,5)(2);
console.log(result);//7
```
>[warning] `arguments`這個對象還有一個名叫 callee 的屬性,該屬性是一個指針,指向擁有這個 arguments 對象的函數。
>
- 前端
- C1-Javascript
- H5圖片分塊和斷點續傳
- JavascriptPatterns[Stoyanstefanov]
- macotask和microtask
- 前端代碼生成器
- 跨域
- 頁面回到頂部滾動按鈕實現
- C2-CSS
- 瀏覽器的一些單位
- 盒模型
- 移動端判斷橫豎屏
- C3-框架
- ReactNative
- 開發環境搭建(安卓篇)
- Vue
- vue+pdfjs使用
- vue+typescript使用實踐
- vue+webpack3.x集成typescript
- Vue源碼3
- vue源碼分析1
- vue源碼分析2
- vue筆記
- C4-工具
- git
- Gitlab-CICD
- mock規則
- vscode-settings
- webpack自定義命令,切換代理地址
- 正則表達式
- 深入淺出webpack
- C5-Node
- express
- express源碼閱讀
- nightmare使用指南
- 爬蟲1.0
- C6-微信
- 微信
- C7-Canvas
- 基礎API
- 前端隨筆筆記
- 后端
- C1-Java
- shiro
- C2-Linux
- ffmpeg
- ITerm
- Linux
- MongoDB安裝
- MySql安裝
- Ngnix反向代理
- 常見錯誤
- 備忘
- mac
- 備忘-Work
- 備忘Link
- 服務器資源
- 教程
- Hexo個人博客搭建筆錄
- 文檔
- CSS編碼規范
- 前端編碼規范
- 隨筆
- 整理
- 正則
- 鏈接收藏
- 面試
- CodeWars題庫
- CodeWars題庫(二)
- Java社招面試題
- Java面試
- Web面試
- 前端筆試題
- 筆試題