今天研究了一下js的原型,把自己的理解寫到這裡,如有不正確的地方,還望指出,在此先謝過啦~
原型是乙個物件。所有物件都有原型。任何乙個物件也都可以成為其他物件的原型。
每個原型都有乙個constructor
屬性指向其建構函式。
乙個物件的原型被物件內部的[[prototype]]
屬性所持有。
一句話就是,所有物件都有原型,其原型是該物件的內部屬性。那麼有哪些方法可以訪問到這個內部屬性呢?
var a = {};
object.getprototypeof(a);
a.__proto__;
a.constructor.prototype;
不知親剛剛有沒有注意到訪問[[prototype]]
的最後乙個方法a.constructor.prototype;
,直接使用了建構函式的prototype
屬性。
在這裡要多說兩句,js中函式也是物件,所以函式也有原型,其原型也和其他物件一樣,可以通過object.getprototypeof()
和__proto__
訪問。但是建立物件時,我們往往要使用建構函式 (constructor
) 的原型,為了用起來方便,就給建構函式新增了prototype
屬性,用於直接訪問其原型。由於所有的函式都可以成為建構函式,所以就造就了函式有那麼一點點特(you)殊(shi)—— 乙個函式可以通過其prototype
屬性直接訪問其原型,或者說乙個函式的prototype
屬性指向其原型物件。
如果僅僅只是因為乙個例項而使用原型是沒有多大意義的,這和直接新增屬性到這個例項是一樣的。原型真正魅力體現在多個例項共用乙個原型,原型物件的屬性一旦定義,就可以被多個引用它的例項所繼承,這種操作在效能和維護方面其意義是不言自明的。
這也是建構函式存在的原因,建構函式提供了一種方便的跨瀏覽器機制,這種機制允許在建立例項時為例項提供乙個通用的原型。
在使用原型前,先寫一下建構函式部分。
function calculator (decimaldigits, tax) ;
分步宣告
分開設定原型的每個屬性。
calculator.prototype.add = function (x, y) ;
calculator.prototype.subtract = function (x, y) ;
這樣,在new calculator物件以後,就可以呼叫add方法來計算結果了。
此時,calculator.prototype
的constructor
屬性指向 calculator。即:
calculator.prototype.constructor = calculator
更簡單的原型語法
通過給calculator的prototype屬性賦值物件字面量來設定calculator物件的原型。
calculator.prototype = ,
subtract: function (x, y)
};
上面的**中,將 calculator.prototype 賦值為乙個以物件字面量形式建立的新物件。最終結果相同,但是,此時 constructor 屬性不再指向 calculator,即calculator.prototype.constructor != calculator
。
每建立乙個函式,就會同時建立它的 prototype 物件,這個物件會自動獲得 constructor 屬性。而我們這裡使用的語法,本質上完全重寫了預設的 prototype 物件,因此 constructor 屬性也就變成了新物件的 constructor 屬性 —— 指向object建構函式。
如果 constructor 的值很重要,可以向下面一樣設定:
calculator.prototype = ,
subtract: function (x, y)
};
其他方式
使用function立即執行的表示式來為prototype賦值,格式如下:
calculator.prototype = function () ,
var subtract = function (x, y)
return
} ();
var friend = new person();
person.prototype.sayhi = function () ;
friend.sayhi(); // "hi" (沒有問題)
可以隨時為原型新增屬性和方法,並且修改能立即在所有物件例項中反映出來,但如果重寫了原型物件,那結果就不一樣了……
function person ()
var friend = new person();
person.prototype =
};friend.sayhi(); // error
在這個例子中,先建立了 friend 例項,然後又重寫其原型物件。在呼叫friend.sayhi()
時發生錯誤,因為friend 指向的原型中不包含以該名字命名的屬性。
重寫原型物件切斷了現有原型與任何之前已經存在的物件例項之間的聯絡,這些例項仍然引用的是最初的原型。
這部分與原型沒什麼大關係,只是看到了覺有幫助,就插到這裡了,莫要見怪 :)
當然,也不是所有的都是物件,值型別就不是物件。
舉個不太容易理解的例子,函式作為物件時,其屬性還是函式的例子。
var fn = function () ;
fn.a = 10;
fn.b = function () ;
fn.c = ;
上段**中,函式就作為物件被賦值了a、b、c三個屬性,第二個屬性值就是函式,這個有用嗎?
可以看看jquery原始碼。
在jquery原始碼中,「jquery」或者「$」,這個變數其實是乙個函式,不信可以用 typeof 驗證一下。
console.log(typeof $); // function
console.log($.trim(" abc "));
驗明正身!的確是個函式。而經常使用的 $.trim() 也是個函式。
很明顯,這就是在 $ 或者 jquery 函式上加了乙個 trim 屬性,屬性值是函式,作用是擷取前後空格。要習慣的把js中的一切看作物件,只要是物件,就是屬性的集合,屬性是鍵值對的形式。
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...