理論
對於靜態的類來說,JavaScript 對象直接量就已經夠用了,但使用繼承和實例來創建經典的類往往更有幫助。
JavaScript 是基於原型的編程語言,並沒有包含內置類的實現。
但通過JavaScript 可以輕易地模擬出經典的類。
JavaScript 中有構造函數和 new 運算符。構造函數用來給實例對象初始化屬性和值。任何JavaScript 函數都可以用做構造函數,構造函數必須使用 new 運算符作為前綴來創建新的實例。
new 運算符改變了函數的執行上下文,同時改變了return 語句的行為。
當使用 new 關鍵字來調用構造函數時,執行上下文從全局對象(window)變成一個空的上下文{}
,這個上下文代表了新生成的實例。因此,this 關鍵字指向當前創建的實例。如果構造函數沒有返回值,那么這個新生成的實例就作為默認的返回值。如果指定了返回值,這個新實例就白白浪費了。
var Person = function(name) {
this.name = name;
};
// 實例化一個Person
var alice = new Person('zhang');
if .. 這樣
Person('ben dan'); //=> undefined
上面這個例子說明了 new 與不 new 的區別。這個函數只會返回undefined,並且執行上下文是window(全局)對象,無意間創建了一個全局變量name。
實戰
/**
* Class build my Own class
* Created by cyk on 14-8-19.
*/
var Class = function() {
"use strict";
// in current line, 'this' is : Class {} 對象實例
// in the finally, as we have a return value ,so the Class {} is unused.
// 這樣的做法每次都會產生一個'新的' klass 字面量方法
var klass = function() {
// this 均是上下文中新生成的實例
this.init.apply(this, arguments);
};
klass.prototype.init = function() {};
// 定義 prototype 的別名
klass.fn = klass.prototype;
// 定義類的別名
klass.fn.parent = klass;
// 給類添加屬性
klass.extend = function ( obj ) {
// 可選的回調方法 extended
var extended = obj.extended;
for( var i in obj ) {
klass[i] = obj[i];
}
if (extended) extended(klass);
};
// 給實例添加屬性
klass.include = function ( obj ) {
// 可選的回調方法
var included = obj.included;
for( var i in obj ){
klass.fn[i] = obj[i];
}
if (included) included(klass);
};
/*
* 這里的實現支持extended 和included 回調。
* 將屬性傳入對象后就會觸發這兩回調函數
*/
return klass;
};
var ORMModule = {
save: function () {
"use strict";
// 共享的函數
}
};
var Person = new Class();
// 雖然和上一行代碼一樣,但是獲得的值卻是新 new 出來的,
// 所有 Asset 和 Person 指向的都是 Class 的不同變量,只是變量內容相似罷了
var Asset = new Class();
// 所以 Person 和 Asset 現在指向的並非同一個變量
Person.include(ORMModule);
Asset.include(ORMModule);
Person.include({
find: function() {
console.log(this);
}
});
// person is : Class instance,
// klass {init: function, parent: function, save: function, find: function}
var person = new Person();
var asset = new Asset();
person.find(); // klass
asset.find(); // undefined is not a function
先到這里,下集不見不看。