首頁  >  文章  >  web前端  >  淺談javascript的原型繼承_javascript技巧

淺談javascript的原型繼承_javascript技巧

WBOY
WBOY原創
2016-05-16 17:51:351104瀏覽

請看原始碼:

複製程式碼 程式碼如下:

function clone(o) { var F = function(){};
F.prototype = o;
return new F();
}

先看ext(4.1的1896行開始)的原型式繼承。

複製程式碼 程式碼如下:
var TemplateClass = function(){}; var ExtObject = Ext.Object = {
chain: function (object) {
TemplateClass.prototype = object;
var result = new TemplateClass();
TemplateClass.prototype = null; return result;
}
}


這裡清除了object的prototype。
再看一下jquery是怎麼玩的繼承。



複製程式碼 程式碼如下: var jQuery = function( 🎜>
var jQuery = function( 🎜>

var jQuery = function( ? >return new jQuery.fn.init( selector, context, rootjQuery );
};
-----------------------
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function( selector, context, rootjQuery ) {
----------------- ------
}
}
-------------------
jQuery.fn.init.prototype = jQuery.fn ;

jquery玩的就比較高,借助jQuery.fn.init來完成,但是思路一樣。
司徒正美的mass裡也有類似的繼承,在lang_fix.js裡面第17行:
複製程式碼



複製程式碼



複製程式碼


複製程式碼
複製程式碼複製程式碼

程式碼如下:


create: function(o){
if (arguments.length > 1) {
$.log(" Object.create implementation only accepts the first parameter.")
}
function F() {}
F.prototype = o;
return new F();
}


查看了一下es5的官方,找到了他的相容補丁:




複製代碼


代碼如下:


// ES5 15.2. 3.5
// http://es5.github.com/#x15.2.3.5
if (!Object.create) {
Object.create = function create(prototype, properties) {
var object;
if (prototype === null) {
object = { "__proto__": null }; } else { if (typeof prototype != "object") { throw new TypeError("typeof prototype[" (typeof prototype) "] != 'object'"); } var Type = function () {}; Type.prototype = prototype;
object = new Type(); // IE has no built-in implementation of `Object.getPrototypeOf` // neither `__proto__`, but this manually setting `__proto__ / // objects created using `Object.create` object.__proto__ = prototype; } object.__proto__ = prototype; Object.defineProperties(object, properties); } return object; }; } 上面考慮的就比較全面的程式碼考慮的就比較全面的程式碼,但是需要另外引入Object.defineProperties的補丁才行,原始碼相對就比較多了。 複製程式碼 程式碼如下:

// ES5 15.2.3.6
// http://es5.github.com/#x15.2.3.6
// WebKit 和IE8 標準模式修補程式
//由hax 設計
// 相關問題:https://github.com/kriskowal/es5-shim/issues#issue/5
// IE8 參考:
// http ://msdn.microsoft.com/ en-us/library/dd282900.aspx
// http://msdn.microsoft.com/en-us/library/dd229916.aspx
// WebKit 錯誤:
// https:// bugs.webkit.org/show_bug.cgi?id=36423
function doesDefinePropertyWork(object) {
try {
Object.defineProperty(object, "sentinel", {sen. });
傳回物件中的「哨兵」;
} catch (異常) {
// 回傳falsy
}
}
// 如果給定,檢查DefineProperty 是否有效。否則,
//部分填充。
if (Object.defineProperty) {
var DefinePropertyWorksOnObject = doesDefinePropertyWork({});
var DefinePropertyWorksOnDom = 文件類型==「未定義」||
doesDefinePropertyWork(document." ));
if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
var DefinePropertyFallback = Object.defineProperty;
}
}
if (!Object.defineProperty || || >var ERR_NON_OBJECT_DESCRIPTOR = "屬性描述必須是一個物件:";
var ERR_NON_OBJECT_TARGET = "在非物件上呼叫Object.defineProperty:"
var ERR_ACCESSORS_NOT_SUPORTED = "JAPORTEDPPORTED"好在此定義。 🎜>";
Object.defineProperty = function DefineProperty(物件, 屬性, 描述子) {
if ((typeof object != "object" && typeof object != "function") || object === null) {
拋出新的​​TypeError(ERR_NON_OBJECT_TARGET物件);
}
if ((描述符類型!= "物件" && 描述子類型!= "函數") || 描述符== = null) {
拋出新的​​TypeError(ERR_NON_OBJECT_DESCRIPTOR 描述詞);
}
// 大膽嘗試對I8 的DOM 元素使用真正的DefineProperty ///。 ) {
try {
return DefinePropertyFallback.call(物件, 物件, 屬性, 描述子);
} catch (異常) {
// 如果真正的墊片不起作用,請嘗試墊片
}
}
// 如果它是資料屬性。
if (owns(descriptor, "value")) {
// 如果請求“可寫”、“可枚舉”或“可配置”,則靜默失敗
// 被請求但不支援
/*
// 替代方法:
if ( // 無法實作這些功能;允許false 但不允許true
!(owns(descriptor, "writable") ? detector.writable : true) ||
!(owns(descriptor, "enumerable") ?descriptor.enumerable : true) ||
!(owns(descriptor, "configurable") ?descriptor.configurable : true)
)
拋出新的​​RangeError(
"Object.defineProperty 的此實作不"
"支援可設定、可枚舉或可寫。"
);
*/
if (supportsAccessors && (lookupGetter(object, property) ||
lookupSetter(object, property)))
{
// 因為訪問器僅在實作//`` __proto__` 我們可以在定義
// 屬性時安全地重寫`__proto__`,以確保我們不會碰到繼承的
// 訪問器。
var 原型 = object.__proto__;
object.__proto__=prototypeOfObject;
// 無論如何都要刪除屬性,因為 getter / setter 可能是
// 在物件本身上定義的。
刪除物件[屬性];
物件[屬性] = 描述符.值;
// 現在設定原來的`__proto__`。
object.__proto__ = 原型;
} else {
物件[屬性] = 描述子.值;
}
} else {
if (!supportsAccessors) {
} else {
if (!supportsAccessors) {
}拋出新的TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
}
// 如果我們做到了這一點,那麼就可以定義getter 和setter 了!
if (owns(descriptor, "get")) {
defineGetter(object, property, Descriptor.get);
}
if (owns(descriptor, "set")) {
defineSetter(object, property, Descriptor.set);
}
}
返回對象;
};
}
// ES5 15.2.3.7
// http ://es5.github.com/#x15.2.3.7
if (!Object.defineProperties) {
Object. DefineProperties = function DefineProperties(object,properties) {
for (properties, DefineProperties(object,properties) {
for (properties, DefineProperties(object,properties) {
for (properties, DefineProperties(object,properties) {
for (properties, DefineProperties(object,properties) {
for (properties, DefineProperties(object,properties) {
for (properties, 時期) {
if (owns(properties, property) && property != "__proto__") {
Object.defineProperty(object,財產,財產[財產]);
}
}
回物件;
};
}

EcmaScript6 的類別繼承。 複製程式碼
程式碼如下:


class module extends Base {s1.
}
}


越玩越像java了,不過es6很多瀏覽器不支援
最後推薦的寫法:程式碼如下:

if (!Object.create) {
Object.create = function create(o) {
var F = function(){};
F.prototype = o;
var 結果= new F();
F.prototype = null;
回傳結果;
}
}
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn