Javascript高級程序設計筆記

第一章 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 返回函數本身,多用于遞歸。

閉包

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容