第一章 Javascript簡介
Javascript實現
- 核心(ECMAScript)
- 文檔對象模型(DOM)
- 瀏覽器對象模型(BOM)
ECMA-262
- 語法
- 類型
- 語句
- 關鍵字
- 保留字
- 操作符
- 對象
文檔對象模型
針對XML但經過擴展用于HTML的應用程序變成接口API。把整個頁面映射為一個多層節點結構。提供訪問和操作網頁的方法和接口。
- DOM1映射文檔結構
- DOM2
- DOM視圖(Vidws)
- DOM事件(Events)
- DOM樣式(Style)
- DOM遍歷和范圍(Traversal and Range)
- DOM3加載文檔的方法、驗證文檔的方法
瀏覽器對象模型
提供與瀏覽器交互的方法和接口。
第二章 在HTML中使用JavaScript
引入外部javascript, 標簽之間不能再添加額外的內容。否則不執行。
<script type="text/javascript" src="abc.js"></script>
defer屬性,腳本延遲到整個頁面解析完再執行。每個標簽按順序執行。
async屬性,不能保證按先后順序執行。
charset屬性,字符集。
script內嵌文件中出現的內容要\轉義。
外部文件的優點:
- 可維護
- 可緩存
- 適應未來
noscript元素
當瀏覽器不支持JavaScript的時候,顯示noscript元素中的內容。“需要啟用JavaScript”
所有script元素都會按照他們做頁面中出現的先后順序依次被解析。在不使用defer和async的情況下,只有在解析完前面script元素中的代碼之后,才會開始解析后面script中的代碼。一般放在文檔的后面 。
使用defer屬性可以 讓腳本在文檔完全呈現之后再執行,延遲腳本總是按照指定他們的順序執行。
使用async屬性可以表示當前腳本不必等待其他腳本,也不必阻塞文檔呈現。
第三章 基本概念
語法
- 區分大小寫
- 標識符:第一個字符必須是字母、下劃線、美元符號,其他字符可以是字母、下劃線、美元符號、數字。可以包含ASCII和Unicode字符,駝峰大小寫格式。
- 注釋 // 單行注釋 /****多行注釋****/
- 嚴格模式:不確定的行為得到處理,不安全的行為拋出錯誤,"use strict" 可以在頂部添加代碼,也可以在指定函數下添加。
- 語句:結尾分號不是必須,但推薦使用。控制語句多行使用代碼塊,建議始終使用。
關鍵字和保留字
不一一列舉了。
變量
松散型變量可以保存任何數據
var message; //undefined
var message="hi";
如果在函數中var定義一個變量,退出函數后會銷毀。如果函數中不用var直接使用,全局變量退出后還能使用。
可以用逗號創建多個變量var message=1 , go="haha", age=29;
數據類型
基本數據類型 undefined,Null,Bollean,Number,String
復雜數據類型 Object
typeof操作符
- undefined 未定義
- boolean 布爾值
- string 字符串
- number 數值
- object 對象或者null
- function 函數
instanceof檢測對象
person instanceof Array
undefined類型
聲明變量但是沒有初始化。沒有必要顯式的聲明。
var message;
alert(message); //undefined
alert(age); //產生錯誤
但是他們typeof都能輸出undefined。
Null類型
空對象類型 typeof 返回object
未來使用空變量,初始化為null。
null == undefined //ture
Boolean 類型
在使用if的時候用于默認條件判斷。 使用Boolean()進行轉換
|數據類型|轉換為true的值|轉換為false的值|
|-|-|
|Boolean|true|false|
|String|非空字符串|空字符串|
|Number|非零數字包括無窮大|0和NaN|
|Object|任何對象|null|
|Undefined|不使用|undefined|
Number類型
八進制第一位是0,如果字面值中數值超出范圍。那么前導0忽略。八進制在嚴格模式無效。
十進制前兩位是0x。在進行算數計算時,所有的十六進制和八進制被轉換為十進制。
isFinite(123) 判斷是否無限大
沒有小數部分的浮點數,會轉換為整數。
1.2e7
1.2e-7
浮點數表示法
最大能表示的數值 Number.MAX_VALUE
最小能表示的數值 Number.MIN_VALUE
0除以0返回NaN,NaN和任何數值都不相等,包括本身。使用isNaN(123)--false,isNaN(NaN)當然返回true,不能轉換為數值的,也會返回true。isNaN("10")就是false,isNaN(true) 可以被轉換成數值1,也是false。isNaN("blue")不能轉換成數值,是false。
Number()數值轉換規則
- 布爾值,轉換為0和1
- 數字,簡單傳入返回
- null,返回0
- undefined,返回NaN
- 字符串,遵循以下規則。
- 如果只含數字,轉換為十進制數字,前導0忽略
- 如果含浮點格式,轉換為浮點數值
- 如果包含有效的十六進制字符,轉換成十進制數字
- 如果字符串是空的,轉換為0
- 除上述之外,轉換為NaN
- 如果是對象,調用valueOf()方法,依照前面的規則返回的數值進行返回。如果結果是NaN,則調用對象的toString()方法,再依照前面進行返回。
parseInt()函數
找到第一個非空字符進行轉換,如果第一個字符不是數字,返回NaN。因此,轉換空字符串會返回NaN。而Number會返回0.第二個參數可以是基數。"22.5"返回22,小數點不是有效的數字字符。
parseFloat 函數
從第一個字符開始解析每個字符。一直解析到字符串末尾。或者解析遇見一個無效的浮點數字字符為止。第二個小數點無效。
String類型
字符字面量
\n \t \r
每個字面量長度是1
字符串不可變,要改變字符串,只能銷毀原來的。
toString()方法
返回字符字面量,能傳遞基數,但是null和undefined沒有這個方法。如果想把null和undefined轉換成字符串,使用String()轉型函數、
Object類型
var o = new Object()
每個實例都有下列屬性和方法
- constructor 創建當前對象的函數
- hasOwnProperty 檢查給定的屬性在當前對象實例中是否存在
- isPrototypeOf 檢查傳入對象是否是傳入對象的原型
- propertyIsEnumerable 檢查給定對象能否使用for in語句
- toLocaleString() 返回對象字符串表示,與執行環境對應
- toString() 返回對象字符串表示
- valueOf() 返回對象字符串,數值,布爾值表示
操作符
一元操作符
遞增和遞減操作符,前置和后置。
- 包含有效數字字符的字符串,轉換為數字后操作。
- 不包含有效數字的字符串,變量設置為NaN
- 布爾值轉換為0和1再操作。
- 浮點數,執行加減1
- 對于對象,先調用valueOf方法,運用轉換規則。如果結果是NaN,則調用toString()方法。
一元加減操作符。如果是非數值,用Number()轉換,如果是對象,先調用valueof和toString方法,然后再轉換。
位操作符
負數是二進制的補碼,補碼是反碼+1.
按位非NOT 負值減1
按位與AND &
按位或OR |
按位異或 XOR ^ 相同為0 不同為1
左移 << 用0填充
右移 >> 用0填充
布爾操作符
邏輯非!
對象返回false,
空字符串返回true,
非空字符串返回false,
操作數0返回true,
非零返回false,
null返回true,
NaN返回true,
undefined返回true。
兩個邏輯非,可以轉換為布爾值。和Boolean() 相同
邏輯與&&
- 第一個操作數是對象,返回第二個操作數
- 第二個操作數是對象,只有在第一個求值結果是true情況下才返回該對象。
- 兩個操作數都是對象,返回第二個操作數。
- 有一個操作數是null、NaN、undefined,則返回他
- 短路操作
邏輯或||
- 如果第一個操作數是對象,返回第一個操作數
- 如果第一個操作數的求值結果為false,則返回第二個操作數。
- 如果兩個操作數都是對象,則返回第一個操作數
- 如果兩個都是null、NaN、undefined。
- 短路操作
乘性操作符
乘法*
- 如果操作符都是數值,按照常規乘法計算,超出范圍變成無窮大。
- 有一個操作數是NaN,結果是NaN
- Infinity與0相乘,結果是NaN
- infinity與非0相乘,結果是infinity或者-infinity
- 兩個Infinity相乘,返回Infinity
- 有一個操作數不是數值,調用Number()轉換后,在執行上面的操作。
除法/
- 超過范圍,結果是infinity或者-infinity
- 有一個操作符是NaN,返回NaN
- infinity除以infinity,返回NaN
- 0除以0,返回NaN
- 非零有限數被0除,結果是infinit或-Infinity
- 有一個操作數不是數值,后臺調用Number()轉換后,再用上面的規則。
求模%
- 數值返回正常值。
- 被除數無限大除數有限大,返回NaN
- 被除數有限大除數是0,返回NaN
- Infinity被Infinity除,結果是NaN
- 被除數有限大,除數無窮大,結果是被除數。
- 被除數是0,結果是0.
- 有一個操作數不是數值,調用Number(),再應用上述規則。
加性操作符
加法
- 有一個操作符是NaN,結果就是NaN
- 兩個正無窮相加或者兩個負無窮相加,結果就是正無窮和負無窮。
- 正無窮和負無窮相加,結果是NaN
- 字符串相加,就拼接
- 一個是字符串,則將另一個轉換為字符串,再拼接。
- 如果操作數是對象、數值、布爾值,調用他們的toString()取得相應字符串的數值,對于undefined和null,分別調用string()取得字符串undefined和null
減法
- 兩個操作符都是數值,執行常規計算。
- 有一個是NaN,結果都是NaN
- Infinity-Infinity=NaN
- -Infinity- -infinity = NaN
- infinity--infinity=infinity
- -infinity-infinity=-infinity
- 0-0=0
- 0--0=-0
- -0--0=+0
- 如果一個操作數是字符串、布爾值、null、undefined,后臺調用number()將轉換為數值,再根據前面的規則執行減法計算。如果轉換的結果是NaN,那么整個結果是NaN
- 如果有一個操作符是對象,調用valueOf取得對象的數值,如果得到的是NaN,則結果是NaN,如果沒有valueOf方法,則調用toString()方法并得到字符串轉換為數值。
關系操作符
- 兩個操作符都是數值,執行數值比較。
- 都是字符串,比較編碼數值
- 如果一個操作數是數值,則將另一個操作數轉換為一個數值進行比較。
- 如果一個操作數是對象,則調用這個對象的valueOf方法,用結果進行比較。如果沒有,就調用toString方法。
- 如果一個操作數是布爾值,則現將其轉換為數值,進行比較。
- 任何操作符和NaN比較,都是false。
相等操作符
相等和不相等 先轉換再比較
- 有一個操作數是布爾值,轉為數值再比較。
- 一個是字符串,另一個是數值,比較相等這錢先將字符串轉換為數值。
- 一個是對象另一個不是,調用valueOf方法,用得到的基本類型和前面的比較。
- null和undefined相等。不能將null和undefined轉換為其他任何數值。
- 有一個操作數是NaN,相等操作符返回false,不相等返回true。NaN不等于NaN。
NaN<3 false
NaN>=3 false - 兩個操作數是對象,比較是否是同一個對象。
全等和不全等 僅比較不轉換
條件操作符
variable = bollean_expression ? true_value : false_value;
賦值操作符
= += -= *= /= %= <<= >>= >>>=
逗號操作符
var num1=1,num2=2,num3=3;
var num=(2,4,5,6,7) //返回最后一個
語句
if語句
if(a>b){
alert("aaa");
}else if(i<0){
alert("aaa");
}else{
alert("aaa");
}
if (condition) statement1 else statement2
do-while語句
do{
statement
}while(expression);
while語句
while(expression) statement
for語句
for (initialization; expression; post-loop-expression) statement
for (;;;) statement 無限循環
for-in 語句
枚舉對象屬性,確認對象是不是或者undefined
for (property in expression) statement
label語句
label:statement
break和continue語句
可以返回標簽
with語句
with(expression) statement
with(location){
var qs = qs
var hostname = hostname
}
var qs = location.qs
var hostname = location.qs
switch語句 每句要break
switch(i){
case 25:
alert("25");
break;
case 35:
alert("35");
break;
default:
alert("other");
}
如果不寫break,就會合并2個的情況。
函數
function functionName(arg0,arg1,...,argN){
statements
}
return語句停止并立即退出,之后的語句不會執行。
ECMAScript函數不介意傳遞進來多少個參數,也不建議是什么數據類型。
arguments[0]可以獲取第一個參數,并且時時保持同步。arguments.length確定傳遞進來多少參數。可以重寫argument對應的值。如果沒有賦值,那就是undefined。
沒有重載
后面的函數覆蓋前面的
第四章 變量、作用域和內存問題
基本類型和引用類型
動態屬性
var person = new Object();
person.name = "abc";
alert(person.name); //"abc"
var name ="abc";
name.age =24;
alert(name.age); //undefied
不能給基本類型的數值添加屬性。
復制變量值
基本類型的數值復制,兩個變量相互獨立。
引用類型對象復制,復制的為指針。
傳遞參數
所有函數的參數傳遞是按照數值傳遞。
function setName(obj){
obj.name = "Nicholas";
obj = new Object();
obj.name = "Greg";
}
var person = new Object();
setName(person);
alert(person.name) //"Nicholas"
內部的obj被賦予了其他的指針。
檢測類型
基本類型使用 typeof
引用類型 result = variable instanceof constructor
執行環境及作用域
在web瀏覽器中,全局執行環境是windows對象。
代碼在環境中執行,會創建變量對象的作用域鏈。
內部環境可以通過作用域鏈訪問外部環境,但是外部環境不能訪問內部環境中的變量和函數。
延長作用域鏈
try-catch語句的catch塊
with語句
這兩個語句都會在作用域鏈前端添加一個變量對象。對于with語句來說,會將指定的對象添加到作用域鏈中。對catch語句來說,會創建一個新的變量對象,其中包含的是被拋出的錯誤對象的生命。
沒有塊級作用域
在括號內的if或者for的變量是全局變量,不是局部變量。
在函數內,var是局部,不添加var是全局
查詢標識符,由內部到外部。找到這個變量。
垃圾收集
以后再說標記清除、引用計數、性能問題、管理內存
第五章引用類型
Object 類型
創建對象
var person = new Object()
//對象字面量表示法
var person = {
name:"aaa";
age:29
}
var person = {
"name":"aaa";
"age":29
}
//對象最后不能加逗號
var a = {} //與new Object()相同
訪問屬性
person['name'] //可以用空格非數字,變量,關鍵字
person.name
Array 類型
var colors = new Array()
var colors = new Array(20) //預先知道長度
var colors = new Array("a","b","c")
var colors = Array(3) //3項
var colors = Array("aa")
var colors = Array(3) // 省略new 操作
var names = ['a','b'] //字面量法,
var names = [1,2,] //不要這樣
var names = [,,,] //也不要這樣
colors[0] //顯示第0項,也可以修改,或者對新的項新增。
colors.length //顯示長度
colors[colors.length] = "a" //添加新項
value instanceof Array 檢測數組,一個環境
Array.isArray(value) 確定到底是不是數組,不管哪個環境
轉換方法
array.valueof() 返回數組,對每一項toString
toLocaleString()
toString() 返回數組每個值的字符串形式拼接而成的一個以逗號分隔的字符串
array.join("|")
棧方法
后進先出LIFO(last in first out)
array.push(1,2,3) 返回修改后數組長度
array.pop() 返回移除的數組
隊列方法
先進先出FIFO(first-in-first-out)
array.push(1,2,3)
array.shift()
前進后出
array.pop()
array.unshift
重新排列方法
array.reverse() 反序
array.sort(function compare(value1,value2){return value2-value1})
function compare(value1,value2){
if(value1 < value2){
return -1;
} else if (value1 > alue2){
return 1;
} else {
return 0
}
}
操作方法
array.concat([a,b,c])組合成新數組,沒有參數的時候,只是返回副本。
array.slice(1,3) 按照python那種方式提取數組,不會影響原始數組
array.splice(1,0,[1,2]) 刪除、插入、替換數組
位置方法
indexOf(4,4) 可以查找某個東西的位置,帶參數從那個位置開始找。
lastIndexOf()
迭代方法
- every() 每項運行都運行函數,每一項都返回true,則返回true
- filter() 返回true的組成新數組
- forEach() 每一項運行給定函數,沒有返回值
- map() 返回每次調用函數的結果
- some() 任何一項返回true,就返回true
function(item,index,array){
return(item>2);
}
歸并方法
reduce() reduceRight()
var values = [1,2,3,4,5]
var sum = values.reduce(function(prev,cur,index,array){
return prev+cur
})
DATE類型
var now = new Date() 創建日期當前對象,可傳入1970.1.1的毫秒數
var someDate = new Date(Date.parse("May 25, 2005")) 按照日期格式轉換
var someDate = new Date(Date.UTC(2005,4,5,17,55,55)) 按照0的基數
var start = Date.now() 取得當前時間
valueOf返回毫秒表示,方便比較
toString和toLocalString 返回字符串
RexExp類型
暫缺
Function類型
function sum(num1, num2){
return num1 + num2
}
var sum = function(num1,num2){
return num1 + num2;
};
末尾分號
沒有重載
函數聲明與函數表達式
率先讀取聲明,讀取到規定地方才讀取表達式
function sum(sum1, sum2){} //這是聲明,函數聲明提升
var sum = function (){} //這是表達式
作為值的函數
把一個函數作為另一個函數的結果返回.return function(){}
函數內部屬性
arguments 傳入對象的所有參數
this 執行環境,在不同的環境表示
arguments.callee 是函數自己 比如階乘可以用
caller 保存著調用當前函數的函數引用。
function outer(){
inner()
}
function inner(){
inner.caller; //outer();
}
arguments.callee.caller 更松散的耦合
函數的屬性和方法
length 函數希望接收的命名參數的個數
prototype 屬性,不可枚舉,for-in無法發現
apply() 可以擴充作用域,在特定作用域中調用函數
call() 與apply作用相同,區別是接受參數的方式不同,傳遞的參數必須枚舉出來
function sum(num1,num2){
return num1+num2
}
function callSum1(num1,num2){
return sum.apply(this,arguments);
}
function callSum2(num1,num2){
return sum.apply(this,[num1,num2]);
}
function callSum3(num1,num2){
return sum.call(this,num1,num2);
}
擴充作用域
window.color = "red"
var o = {color:blue}
function saycolor(){alert(this.color)}
saycolor.call(0)
bind() 綁定作用域
window.color = "red"
var o ={color:"blue"}
function sayColor(){
alert(this.color)
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue
基本包裝類型
var s1 = "some text"
var s2 = s1.substring(2);
實際上完成的是以下操作
var s1 = new String("some text");
var s2 = s1.substring(2)
s1 = null
Boolean類型
因為所有對象會轉換成true,所以用處不大。
valueOf() 返回基本類型true和false
toString() 返回字符串true
typeof基本類型會返回boolean,引用類型返回object,理解引用關系非常重要。
永遠不要使用Boolean 對象
Number類型
var numberObject = new Number(10)
valueOf()返回基本類型的數值
toLocalString和toString返回字符串形式
num.toFix(2) 返回指定小數位,四舍五入
typeof基本類型返回number
typeof引用類型返回object
String類型
valueOf toString toLocalString 返回字符串
使用toString用于將數值格式化為字符串方法
字符方法
stringValue.charAt(1) //訪問指定位置
stringValue.charCodeAt(1) //訪問指定位置的編碼
stringValue[1] //訪問指定位置
操作方法
stringValue.concat("world") //字符串連接
slice substr substring //子字符串
indexOf lastIndexOf //位置方法
trim() //刪除空格
toLowerCase toUpperCase //大小寫轉換
match() //接收正則表達式或者RegExp對象
search() //接收正則表達式或者REgExp對象 返回第一個匹配是索引
replace() //替換 可以用正則表達式
localeCompare() //方法
單體內置對象
Golbal對象
URL編碼方法
encodeURI() //整個URL編碼,不會對本身屬于URL字符編碼冒號斜杠
encodeURLComponent() //對一段編碼,對任何非標準字符編碼。
decodeURL()
decodeURLComponent() 解壓
eval方法
解析語句
Golbal對象屬性
各種類型,構造函數,錯誤,日期,regexp等
windows對象
訪問Global對象,Web瀏覽器都是將這個全局對象作為windows對象實現。
Math對象
底數,自然數,最大值,最小值,四舍五入,隨機數
第六章 面向對象的程序設計
var person = new Object();
person.name = "abc";
person.sayName = function(){
alert()
}
var person = {
name:"abc",
age:29.
sayName:function(){
alert(this.name);
}
}
屬性類型
數據屬性
[[Configurable]] 能否刪除重新定義
[[Enumerable]] 能否通過for-in 循環返回屬性
[[writable]]
[[Value]] 這個屬性的數值
Object.defineProperty(aaa,"name",{
writable:false,
value:"aaaa"
})
訪問器屬性
[[Configurable]] 能否刪除重新定義
[[Enumerable]] 能否通過for-in 循環返回屬性
[[get]]讀取屬性調用的函數
[[set]]寫入屬性調用的函數
aaa._age=87;
Object.defineProperty(aaa,"age",{
get:function(){
return this._age;
},
set:function(newValue){
this._age=newValue;
}
})
aaa.age=88
alert(aaa.age)
定義多個屬性
var book={};
Object.defineproperties(book,{
_year:{
value:2004
},
edition:{
value:1;
}
}
)
讀取屬性的特性
Object.getOwnPropertyDescriptor(book,"year")
如果是訪問屬性,那么是configurable,enumerable,get,set
如果是數據屬性,那這個對象屬性有configurable\enumerable\writable和value
var descriptor = Object.getOwnPropertyDescriptor(book,"_year");
descriptor.value
創建對象
工廠模式
function createObject(name,age,job){
var person = new Object;
person.name = name;
person.age = age;
person.job = job;
person.sayName = function(){
alert(this.name)
}
return person;
}
無法解決對象識別問題
構造函數模式
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName = function(){
alert(this.name);
}
}
var person1= new Person("johnny",18,"workker")
沒有顯式創建對象,直接將屬性和方法賦給this對象,沒有return語句。構造函數要大寫。
person1.constructor == Person //true
person1 instanceof Person //true
每次執行方法,都要重建一次。兩個創造出來的sayname不相同。把函數移到外面,但是沒有封裝了。
原型模式
function Person(){}
Person.prototype.name = "Johnny"
Person.prototype.age = 20
Person.prototype.job = "Software Engineer"
Person.prototype.sayName = function(){
alert (this.name);
}
var person1 = new Person()
person1.sayName();
var person2 = new Person()
person2.sayName();
alert(person1.sayName == person2.sayName); //true
Person.prototype.isPrototypeOf(person1) //true
Object.getPrototypeOF(person1).name //"Johnny"
無法通過對象實例重寫原型中的值,重寫之后會給實例添加屬性,卻不能改寫原型。使用delete刪除屬性,從而回復對原型的訪問。使用person1.hasOwnProperty('name') 是否存在于實例中。
原型與in操作符
如果對象能通過原型或者實例訪問到屬性,in返回true。
確定是原型中的屬性。
function hasPrototypeProperty(object,name){
return !object.hasOwnProperty(name) && (name in object);
}
使用for-in循環,返回的是所有能夠通過對象訪問的、可枚舉屬性,既包括存在于實例中的屬性,也包括存在于對象中的屬性。
原型簡寫
function Person(){}
Person.prototype = {
constrotor : Person,
name:"abc",
sayName : function(){
alert(this.name);
}
}
Object.defineProperty(Person.prototype,"constructor",{
enumerable:false,
value:Person
}
);
取得對象上可枚舉實例的屬性
var keys = Object.keys(Person.prototype);
alert(keys); //"name,age,job,sayName"
取得所有實例的屬性,無論是否可枚舉
Object.getOwnPropertyNames(Person.prototype);
要不然constructor無法確定對象類型。但是變成可枚舉的enumerable。
更簡單的原型語法
function Person(){}
Person.prototype = {
constructor:Person,
name:"Nicho",
age:18,
sayName:function(){
alert(this.name);
}
};
這樣從這里創建的新對象的constructor就不再指向Person了。所以要重寫constructor.但是會導致constructor 的Enumerable特性被設置成true。
Object.defineProperty(Person.prototype,"constructor",{
enumerable:false,
value:Person
})
原型的動態性
重寫一個原型屬性可以,但是重寫整個原型會導致指向他的實例失去屬性。
原型對象問題
沒有傳遞參數,共享本性。
原型對象的問題
所有的實例在默認情況下都使用相同的屬性。
組合使用構造函數模式和原型模式。
function Person(name, age, job){
this.name = name;
this.age=18
}
Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name);
}
}
使用最廣泛、認同度最高
動態原型模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
if (typeof this.sayName != "function"){
Person.prototype.sayName = function(){
alert(this.name);
}
}
}
不能使用對象字面量重寫原型,會切斷聯系。
寄生構造模式
先不看了
穩妥構造模式
先不看了
繼承
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property
}
function SubType(){
this.subproperty = false
}
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
return this.subproperty;
}
var instance = new SubType();
alert(instance.getSuperValue())
//確定原型和實例的關系
instance instanceof Object
instance instanceof SuperType
instance instanceof SubType
Object.prototype.isPrototypeOf(instance)
SuperType.prototype.isPrototypeOf(instance)
SubType.prototype.isPrototypeOf(instance)
謹慎定義方法,覆蓋方法,給原型添加方法一定要放在替換語句之后。
重寫subtype會阻斷與super之間的聯系。
不能通過字面量添加新方法,這樣會重寫原型。
SubType.prototype = {
getSubValue:function(){
return this.subproperty;
},
someOtherMethod: function(){
return false;
}
}
問題1 ,引用類型的原型,原型會變成另一個類型的實例,實例對原型的修改,提現在了其他的實例上。在創建子類型的時候,不能向超類型的構造函數傳遞參數。
借用構造函數???
function SuperType(name){
this.color = [1,2,3,"name"]
}
function SubType(){
SubType.call(this,"haha");
}
var instance1 = new SubType();
instance1.push("black")
var instance2 = new SubType();
instance2.color //沒有變化
可以傳遞參數.缺點都在構造函數中定義,無法重復使用,超類型中定義的方法,在子類型中不可見。
組合繼承????
function SuperType(name){
this.name = name;
this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function(){
alert (this.name);
}
function SubType(name,age){
SuperType.call(this,name);
this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age);
}
var instance1 = new SubType("Nicholas",29);
instance1.color.push("black");
alert(instance1,colors); //四個顏色
instance1.sayName(); //nigulasi
instance1.sayAge(); //29
var instance1 = new SubType("aaa",28);
instance1.color.push("black");
alert(instance1,colors); //三個顏色
instance1.sayName(); //aaa
instance1.sayAge(); //28
既避免了原型鏈和借用構造函數的缺陷,又融合了有點,是最常用的繼承模式。
原型式繼承
寄生式繼承
寄生組合式繼承
第七章 函數表達式
函數聲明,函數聲明提升。
函數表達式,類似于賦值語句。
遞歸
arguments.callee 返回函數本身,多用于遞歸。