JS建構函式,原型鏈,原型物件總結
建構函式
建構函式第一個字母大寫
使用this指向當前物件的 公有屬性
var Car = function(wheels, seats, engines) {
this.wheels = wheels;
this.seats = seats;
this.engines = engines;
};
var myCar = new Car(6,3,1)
複製程式碼
也可以建立私有屬性和私有方法,它們兩個在物件外部是不可訪問的
用var 關鍵詞去建立變數,代替this建立私有屬性;比如,我們想記錄我們的car行駛的 speed
,但是我們希望外面的程式碼對 speed
的修改只能是加速或減速(而不是變成字串、直接賦值成某個速度等其他操作),那麼如何達到這類操作的目的呢?
var Car = function() {
// this is a private variable
var speed = 10;
// these are public methods
this.accelerate = function(change){
speed =+ change
}
this.decelerate = function() {
speed -= 5;
}
this.getSpeed = function(){
return speed
}
}
複製程式碼
instanceof
判斷某個物件是否為某個建構函式的例項
console.log(myCar instanceof Car)
複製程式碼
靜態成員和例項成員
靜態成員: 寫成物件字面量的形式,直接使用物件來呼叫。
// 一般用於 工具 的寫法,工具中使用靜態成員,即工具中的方法如 max(),PI 只有一個
var MyMath = {
PI:3.1415,
max:function(){},
min:function(){}
}
MyMath.PI
MyMath.max()
複製程式碼
例項成員:建構函式中的成員: p.sayHi()
function Person(name,age) {
this.name = name,
this.age = age,
this.sayHi = function(){}
}
//當有很多例項的時候,使用建構函式來建立
var p = new Person('zs',18)
複製程式碼
建構函式原型
每一個建構函式都有一個屬性 : 原型/原型物件 prototype
function Person(name,age) {
this.name = name,
this.age = age,
}
console.dir(Person.prototype)
//那麼就可以為Person的原型物件增加方法,這樣用Person建構函式建立出來的例項都可以訪問新增加的方法
Person.prototype.sayHi = function() {
console.log("hi")
}
var p1 = new Person('ls',12)
var p2 = new Person('tom',13)
p1.sayHi()
p2.sayHi()
這樣做的優點: 節省記憶體
p1.sayHi 和 p2.sayHi 是相等的,指向同一個記憶體空間
如果在Person()內部定義 sayHi 方法的話,新建立的p1,p2會各自在記憶體建立空間
複製程式碼
物件本身有 __proto__ 屬性,當呼叫物件的屬性或方法時,先去找物件本身的屬性/方法;找不到的話 再去調原型中的屬性/方法
物件的__proto__ 屬性 等於 建構函式的prototype,物件可以訪問原型物件所有成員
p1.__proto__ === Person.prototype
> true
constructor 記錄了建立該物件的建構函式
p1.constructor === Person
> true
複製程式碼
注意:constructor 屬性
function Person(){
}
var p1 = new Person()
console.log(p1.constructor === Person.prototype.constructor)
>true
原因:
當獲取 person.constructor 時,其實 person 中並沒有 constructor 屬性,當不能讀取到constructor 屬性時,會沿著原型鏈從 person 的原型也就是 Person.prototype 中讀取,正好原型中有該屬性,所以:
person.constructor === Person.prototype.constructor
複製程式碼
原型鏈
同理如圖:
查詢物件是否具有某個方法或屬性時,會由底向上查詢:當底層物件沒有時,會在其原型物件上找,其原型物件沒用時,會再其原型物件的原型物件上找;
使用原型物件注意點
- 當我們改變建構函式的prototype的時候,需要重新設定constructor屬性
//在Person.prototype.sayHi = function(){} 基礎上進一步改進
Person.prototype = {
constructor:Person, //注意點
sayHi:function(){
console.log("hi")
}
}
var p1 = new Person('zs',18)
p1.sayHi()
複製程式碼
- 先設定原型屬性,再建立物件,才能訪問原型物件的成員
原型物件的應用
擴充內建物件的功能,比如給array方法 增加一個求偶數的和的功能
var arr = [1,2,4,5]
Array.prototype.getSum = function(){
var sum = 0;
for (var i = 0;i < this.length; i++){
if(this[i] %2 === 0) {
sum += this[i]
}
}
return sum
}
複製程式碼
//但是能不能用下面這種方法呢?
Array.prototype = {
getSum = function(){}
}
//答案是不能!因為Array,String 都屬於內建物件,如果用以上方法,會覆蓋掉他們本身的那些方法
複製程式碼