類和例項是大多數物件導向程式設計語言的基本概念,不過在js中不區分類和例項的概念,而是通過原型(prototype)來實現物件導向程式設計。原型是指當我們想要建立xiaoming這個具體的學生時,我們並沒有乙個student型別可用。那怎麼辦?
js沒有類的概念,所有物件都是例項,所謂繼承關係就是把乙個物件的原型指向另乙個物件而已,如果你把xiaoming的原型指向其他物件:var student =
};var xiaoming = ;
// 把xiaoming的原型指向了物件student
xiaoming.__proto__ = student;
xiaoming.name; // '小明'
xiaoming.run(); // 小明 is running...
請注意,在js中不要直接用obj.proto去改變乙個物件的原型,並且低版本的ie也無法使用proto。object.create()方法可以傳入乙個原型物件,並建立乙個基於該原型的新物件,但是新物件什麼屬性都沒有,因此我們可以編寫乙個函式來建立xiaoming:var bird =
};xiaoming.__proto__ = bird;
xiaoming.fly(); // 小明 is flying...
例項物件// 原型物件:
var student =
};function createstudent(name)
var xiaoming = createstudent('小明');
xiaoming.run(); // 小明 is running...
xiaoming.__proto__ === student; // true
js可以用建構函式的方法來建立物件,它的用法是先定義乙個建構函式:
這裡請注意,如果不寫new,這就是乙個普通函式並返回undefined。但是如果寫了new,它就變成了乙個建構函式,它繫結的this指向新建立的物件並預設返回this,也就是說不需要在最後return this。用new建立的物件還從原型上獲得了乙個constructor屬性,它指向函式student本身:function student(name)
}// 在js中用關鍵字new呼叫函式返回物件:
var xiaoming = new student('小明');
xiaoming.name; // '小明'
xiaoming.hello(); // hello, 小明!
student.prototype指向的物件就是xiaoming、xiaohong的原型物件,這個原型物件有個屬性constructor指向student函式本身,但是xiaoming、xiaohong這些物件沒有prototype屬性,不過可以用proto這個非標準用法來檢視,現在我們就認為xiaoming、xiaohong這些物件「繼承」自student。xiaoming.constructor === student.prototype.constructor; // true
student.prototype.constructor === student; // true
object.getprototypeof(xiaoming) === student.prototype; // true
xiaoming instanceof student; // true
xiaoming和xiaohong呼叫的hello是乙個函式,但它們是兩個不同的函式,雖然函式名稱和**都是相同的。要讓建立的物件共享乙個hello函式,根據物件的屬性查詢原則只要把函式移動到物件原型上就可以了,也就是student.prototype:xiaoming.name; // '小明'
xiaohong.name; // '小紅'
xiaoming.hello; // function: student.hello()
xiaohong.hello; // function: student.hello()
xiaoming.hello === xiaohong.hello; // false
如果建立物件時忘記寫new,在strict模式下,this.name = name將報錯,因為this繫結為undefined,在非strict模式下,this.name = name不報錯,因為this繫結為window,於是無意間建立了全域性變數name並返回undefined,這個結果更糟糕。為了區分普通函式和建構函式,按照規定建構函式首字母應當大寫,而普通函式首字母小寫:function student(name)
student.prototype.hello = function () ;
如果建立的物件有很多屬性,我們只需要傳遞需要的某些屬性,剩下的屬性可以用預設值。function student(props)
student.prototype.hello = function () ;
function createstudent(props) )
}var xiaoming = createstudent();
xiaoming.grade; // 1
原型繼承
在傳統的基於類和例項的語言中,繼承的本質是型別的拓展,由於js採用了原型繼承,所以不存在類。我們想要在js中實現繼承可以借助於中間函式,用inherits()函式進行封裝還可以隱藏中間函式的定義,並簡化**:
js的原型繼承實現方式如下:function inherits(child, parent) ;
f.prototype = parent.prototype;
child.prototype = new f();
child.prototype.constructor = child;
}function student(props)
student.prototype.hello = function ()
function primarystudent(props)
// 實現原型繼承鏈:
inherits(primarystudent, student);
// 繫結其他方法到primarystudent原型:
primarystudent.prototype.getgrade = function () ;
定義新的建構函式,並在內部用call()呼叫希望「繼承」的建構函式,並繫結this;
借助中間函式實現原型鏈繼承,最好通過封裝的inherits函式完成;
繼續在新的建構函式的原型上定義新方法;
類繼承我們知道js的物件模型是基於原型實現的,特點是簡單,但是實現繼承需要大量**。es6引入了新的關鍵字class來定義類:
用class直接通過extends來實現繼承:class student
hello()
}var xiaoming = new student('小明');
xiaoming.hello();
注意,因為不是所有的主流瀏覽器都支援es6的class,現在使用還不太方便,不過可以用babel這個工具把class**轉換為傳統的prototype**。class primarystudent extends student
mygrade()
}
Javascript 學習筆記
如果在生成的html裡面有事件需要傳遞帶特殊字元的引數,處理如下 singletext 輸入 1.singletext value.escapehtml 為 將html編碼 2.singletext value.escapehtml inspect 為 3.在 jsdebugtext innerht...
javascript學習筆記
視窗操作 1改變視窗的位置 window.location 2視窗的歷史操作 previous 3建立新的視窗 window.open url 視窗名稱 視窗特徵字元 細節 不能換行寫 視窗特徵 width,height,yes,no munubar,status,scrollbars,resiza...
javaScript學習筆記
2018 12 26 標題 var num1 10 var num2 0 var result num1 num2 console.log result infinity 表示超出了js的數值範圍 類似高數里的整數除以無窮小的數,得到無窮大的結果。var num1 a var num2 3 或其它n...