# javascript快速入門12--函數式與面向對象
## 函數
函數是一組可以隨時隨地運行的語句。
函數是 ECMAScript 的核心。
創建函數
```
function fnOne() {//具有名稱的函數,函數名必須符合變量名命名規范
//可以沒有符何語句
}
var fnTwo = function () {//匿名函數
};
function () {//創建匿名函數而不立即創建其引用,那么之后就沒辦法調用此函數
}
(function fnThree() {
})();//創建函數并立即執行一次
(function () {})();//創建匿名函數并立即執行一次
```
匿名函數與命名函數的區別
```
fnOne();//不會出錯,使用function創建的具有名稱的函數在任何與之相同作用域的地方都能調用
fnTwo();//出錯
var fnTwo =function () {};//因為只有執行了這個賦值語句后,fnTwo才會被創建
function fnOne() {}
```
函數返回值
```
function fnTest() { return "value";//使用return來返回值
alert("Hello!!!");//執行了return之后,函數就會退出
}
```
函數參數
```
function fnTest(arg1,arg2,arg3) {
alert(arg1+"\n"+arg2+"\n"+arg3);
}
fnTest(1,2,3);
fnTest(1,2);//沒有傳值過去時,就會是undefined
```
arguments對象:在函數執行時函數內部就會有arguments對象,它包含了所有的參數,arguments的length屬性報告了傳入參數個數
```
function fnTest() { for (var i=0;i< arguments.length;i++) {
alert(arguments[i]);
}
}
fnTest(1,2,3);
fnTest(45);
```
使用arguments對象模擬函數重載
```
function fnTest() { var args = arguments; switch (arguments.length) { case 0 : return "沒有輸入!!!"; case 1 : return "一個參數:"+args[0]; case 2 : return "二個參數:"+args[0]+" 和 "+ args[1];
}
}
alert(fnTest());
alert(fnTest(1));
alert(fnTest(2));
```
arguments對象補充:arguments對象的callee屬性指向它所在的函數
```
function fnTest() {alert(arguments.callee);}
```
## 閉包
閉包,指的是詞法表示包括不被計算的變量的函數,也就是說,函數可以使用函數之外定義的變量。
在 ECMAScript 中使用全局變量是一個簡單的閉包實例。請思考下面這段代碼:
```
var msg = "我是全局變量!!!"; function say() {
alert(msg);
}
say();
```
在ECMAScript中,在函數聲明處向函數外部看到的聲明的所有變量,在函數內部都能訪問到它們的最終值!
```
var g = "全局變量!!!"; function fnA() { var a="A"; function fnB() { var b="B";
alert(a);//可以訪問到a
alert(c);//但不以訪問c
function fnC() { var c = "C";
alert(a+"\n"+b);//只要遵循從里向外看的原則,看到的變量都可以訪問到
}
}
} //更復雜的閉包
function fnTest(num1,num2) { var num3 = num1+num2; return function () {
alert("num1+num2結果為"+num3);
};
} var result = fnTest(23,56);
result();
```
閉包函數只能訪問變量的最終值!!!
```
function fnTest(arr) { for (var i=0;i < arr.length;i++) {
arr[i]=function () {
alert(i+" | "+arr[i]);
};
}
} var arr = [0,1,2,3,4,5];
fnTest(arr); for (var i=0;i < arr.length;i++) {
arr[i]();//始終輸出6還有一個undefined
//因為函數退出后,i值為6,所以訪問到的值只有6
}
```
不但在閉包中可以訪問閉包外的變量值,而且還可以設置它的值
```
function fnTest() { var a=123; return {
set:function (param) {a = param},
get:function () {return a}
};
} var obj = fnTest();
alert(obj.get());//123
obj.set(4);
alert(obj.get());//4
```
## 對象,構造函數
創建一個對象
```
var obj = new Object();
alert(obj);
alert(Object);//一個函數
Object();//可以直接執行
//構造函數也是一個普通的函數
function Demo() {
} var d = new Demo();//不會出錯,使用new運算符來創建對象實例
alert(d);//object
```
this關鍵字的用法
```
function Demo() { this.property = "屬性!!!";
}
d = new Demo();
alert(d.property);//屬性!!!
```
不使用new而直接執行構造函數時,this指向window
```
function Demo() { this.property = "屬性!!!";
} var d = Demo();
alert(d.property);//undefined
alert(window.property);//屬性!!!
```
可以給構造函數傳遞參數,然后可以將參數賦值給對象的屬性
```
function Person(name,age) { this.name = name; this.age = age;
} var p1 = new Person("CJ",18);
```
instanceof 運算符,用來判斷對象是否是某個類(雖然ECMAScript中并不存在類,但我們在這里依然使用這一術語)的實例
```
var str = new String("string");
alert(str instanceof String);//true
var arr = new Array();
alert(arr instanceof Array);//true
function Demo() {} var d = new Demo();
alert(d instanceof Demo);//true
```
## 面向對象術語
一種面向對象語言需要向開發者提供四種基本能力:
* 封裝——把相關的信息(無論數據或方法)存儲在對象中的能力。
* 聚集——把一個對象存儲在另一個對象內的能力。
* 繼承——由另一個類(或多個類)得來類的屬性和方法的能力。
* 多態——編寫能以多種方法運行的函數或方法的能力。
ECMAScript支持這些要求,因此可被看作面向對象的。
### 封裝與私有屬性:封裝并不要求私有!
```
function Person(name,age) { this.name = name;//將值存儲為對象的屬性即是封裝
this.age = age;
} var p1 = new Person("CJ",18);
```
ECMAScript目前版本并不支持私有屬性,但可以通過閉包來模擬
```
function Person(name,age) { this.getName = function () {return name}; this.setName = function (param) {name=param}; this.getAge = function () {return age}; this.setAge = function (param) {age=param};
} var p1 = new Person("CJ",18);
alert(p1.name);//undefined
alert(p1.getName());//CJ
p1.setName("XXX");
alert(p1.getName());//XXX
```
### 繼承:prototype屬性
ECMAScript中,繼承是通過構造函數的prototype屬性實現的
```
function Person(name,age) { this.name=name; this.age = name;
}
alert(Person.prototype);//object
Person.prototype.sort = "人"; var p1 = new Person("CJ",18);
alert(p1.sort);//所有的Person對象的實例繼承了sort這個屬性
```
所有對象都有一個方法isPrototypeOf(),用來判斷它是不是另一個對象的原型
```
function Person() {} var p1 = new Person();
alert(Person.prototype.isPrototypeOf(p1));//true
```
在ECMAScript中讓一個類繼承另一個類的方式比較特殊
```
function ClassA() { this.a = "A";
} function ClassB() { this.b = "B";
}
ClassB.prototype = new ClassA(); //讓ClassB繼承ClassA
var b = new ClassB();
alert(b.a);//"A",繼承了屬性a
alert(b instanceof ClassB);//true
alert(b instanceof ClassA);//true,因為繼承,b也是ClassA的后代
alert(ClassB.prototype.isPrototypeOf(b));//true
alert(ClassA.prototype.isPrototypeOf(b));//true,ClassA.prototype也是b的原型
```
然而這樣的繼承有個注意點——
```
function ClassA() { this.a = "A";
} function ClassB() { this.b = "B";
} var b = new ClassB();//先實例化ClassB
ClassB.prototype = new ClassA();//再去繼承ClassA,將prototype重置為另一個對象
alert(b instanceof ClassB);//false
alert(b instanceof ClassA);//false
alert(ClassB.prototype.isPrototypeOf(b));//false
alert(ClassA.prototype.isprototypeOf(b));//false
```
當構造函數需要參數時
```
function Person(name,age) { this.name = name; this.age = age;
} function Teacher(name,age,lesson) { this.tempMethod = Person;//對象冒充
this.tempMethod(name,age); //當執行Person時,由于是在Teacher某個實例上調用的,所以在Person函數中的this指向了Teacher的實例
delete this.tempMethod;//刪除臨時方法
this.lesson = lesson;
}
ClassB.prototype =new ClassA();//始終不應在繼承時放參數
var t1 = new Teacher("HUXP",18,"C#");
alert(t1.name+" | "+ this.age+ " | "+this.lesson);
```
事實上,對于對象冒充,ECMAScript提供了更簡潔的內置方法call,在每個函數上調用,第一個參數即為要冒充的對象,剩下的是函數需要的其它參數
```
function Demo(arg) { this.name = arg;
} var obj = new Object();
Demo.call(obj,"name");
alert(obj.name);//"name"
//使用call重寫上面繼承的例子
function Person(name,age) { this.name = name; this.age = age;
} function Teacher(name,age,lesson) {
Person.call(this,name,age);//對象冒充
this.lesson = lesson;
}
```
### 靜態屬性與Function類
在ECMAScript里有個有趣的地方是,函數本身也是對象(和數組也一樣),也可使用new來創建.Function構造函數至少要傳兩個字符串參數,可以是空字符串。除了最后一個字符串會被當做函數體語句去執行,其它參數都會作為函數參數變量名!
```
var fn = new Function();//一個空函數
//創建有內容的函數
fn = new Function("arg1","alert(arg1)");//最后一個參數為執行語句的字符串,前面參數全是函數要用到的參數
//上面的代碼等效于
fn = function (arg1) {alert(arg1)};//同樣,由于都是賦值語句,所以要注意出現次序
fn.property ="既然是對象,那么就要以添加屬性"
```
事實上,在構造函數上添加的屬性就被稱之為靜態屬性,它不會被實例所繼承
```
function ClassDemo() {
}
ClassDemo.property = new Array(); var d =new ClassDemo();
alert(d.property);//undefined
alert(ClassDemo.property);//object
```
Function類的實例還有其它一些方法和屬性(當然,使用function關鍵字聲明的函數也是一樣的)
```
function outer() {
inner(); function inner() {
alert(inner.caller); //函數的caller屬性指向調用自身的上下文函數,這里指向outer
}
} function applyTest() { var args = arguments; this.name = args[0]; this.age=args[1];
} var obj = new Object();
applyTest.apply(obj,["name",18]);
alert(obj.name);
alert(obj.age); //apply方法與call方法類似,也用于對象冒充,只是apply方法只有兩個參數
//第一個是要冒充的對象,第二個是所有參數組成的數組
```
- 介紹
- HTML/CSS 教程
- 第 1 章 HTML5 概述
- 第 2 章 基本格式
- 第 3 章 文本元素
- 第 4 章 超鏈接和路徑
- 第 5 章 分組元素
- 第 6 章 表格元素
- 第 7 章 文檔元素
- 第 8 章 嵌入元素
- 第 9 章 音頻和視頻
- 第 10 章 表單元素[上]
- 第 10 章 表單元素[中]
- 第 10 章 表單元素[下]
- 第 11 章 全局屬性和其他
- 第 12 章 CSS 入門
- 第 13 章 CSS 選擇器[上]
- 第 14 章 CSS 顏色與度量單位
- 第 15 章 CSS 文本樣式[上]
- 第 15 章 CSS 文本樣式[下]
- 第 16 章 CSS 盒模型[上]
- 第 16 章 CSS 盒模型[下]
- 第 17 章 CSS 邊框與背景[上]
- 第 17 章 CSS 邊框與背景[下]
- 第 18 章 CSS 表格與列表
- 第 19 章 CSS 其他樣式
- 第 20 章 CSS3 前綴和 rem
- 第 21 章 CSS3 文本效果
- 第 21 章 CSS3 文本效果
- 第 23 章 CSS3 邊框圖片效果
- 第 24 章 CSS3 變形效果[下]
- 第 25 章 CSS3 過渡效果
- 第 26 章 CSS3 動畫效果
- 第 27 章 CSS 傳統布局[上]
- 第 27 章 CSS 傳統布局[下]
- 第 28 章 CSS3 多列布局
- 第 29 章 CSS3 彈性伸縮布局[上]
- 第 29 章 CSS3 彈性伸縮布局[中]
- 第 29 章 CSS3 彈性伸縮布局[下]
- 第 30 章 使用 Emmet 插件
- Bootstrap 教程
- 第 1 章 Bootstrap 介紹
- 第 2 章 排版樣式
- 第 3 章 表格和按鈕
- 第 4 章 表單和圖片
- 第 5 章 柵格系統
- 第 6 章 輔組類和響應式工具
- 第 7 章 圖標菜單按鈕組件
- 第 8 章 輸入框和導航組件
- 第 9 章 路徑分頁標簽和徽章組件
- 第 10 章 巨幕頁頭縮略圖和警告框組件
- 第 11 章 進度條媒體對象和 Well 組件
- 第 12 章 列表組面板和嵌入組件
- 第 13 章 模態框插件
- 第 14 章 下拉菜單和滾動監聽插件
- 第 15 章 標簽頁和工具提示插件
- 第 16 章 彈出框和警告框插件
- 第 17 章 按鈕和折疊插件
- 第 18 章 輪播插件
- 第 19 章 附加導航插件
- 第 20 章 項目實戰--響應式導航[1]
- 第 20 章 項目實戰--響應式輪播圖[2]
- 第 20 章 項目實戰--首頁內容介紹[上][3]
- 第 20 章 項目實戰--首頁內容介紹[下][4]
- 第 20 章 項目實戰--資訊內容[5,6]
- 第 20 章 項目實戰--案例和關于[7]
- javaScript 教程
- javascript快速入門1--JavaScript前世今生,HelloWorld與開發環境
- javascript快速入門2--變量,小學生數學與簡單的交互
- javascript快速入門3--分支判斷與循環
- javascript快速入門4--函數與內置對象
- javascript快速入門5--數組與對象
- javascript快速入門6--Script標簽與訪問HTML頁面
- javascript快速入門7--ECMAScript語法基礎
- javascript快速入門8--值,類型與類型轉換
- javascript快速入門9--引用類型
- javascript快速入門10--運算符,語句
- javascript快速入門11--正則表達式
- javascript快速入門12--函數式與面向對象
- javascript快速入門13--BOM——瀏覽器對象模型(Browser Object Model)
- javascript快速入門14--DOM基礎
- javascript快速入門15--節點
- javascript快速入門15--表單
- javascript快速入門16--表格
- javascript快速入門17--事件
- javascript快速入門18--樣式
- javascript快速入門19--定位
- javascript快速入門20--Cookie
- javascript快速入門21--DOM總結
- javascript快速入門22--Ajax簡介
- javascript快速入門23--XHR—XMLHttpRequest對象
- javascript快速入門24--XML基礎
- javascript快速入門25--瀏覽器中的XML
- javascript快速入門26--XPath
- javascript快速入門27--XSLT基礎
- PHP 教程
- 第一章 如何加載運行已發布的PHP項目
- 第二章 PHP基礎
- 第三章 操作符與控制結構
- 第四章 數學運算
- 第五章 數組
- 第六章 目錄與文件
- 第七章 自定義函數
- 第八章 字符串處理
- 第九章 正則表達式
- 第十章 日期與時間
- 第十一章 表單與驗證
- 第十二章 會話控制
- 第十三章 上傳文件
- 第十四章 處理圖像
- 第十五章 MySQL 數據庫
- 第十六章 PHP 操作MySQL
- 第十七章 面向對象基礎
- 第十八章 面向對象的特性
- 第十九章 面向對象的工具