浅谈javascript的原型继承


Posted in Javascript onJuly 25, 2012

请看源码:

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( selector, context ) { 
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__` will 
// guarantee that `Object.getPrototypeOf` will work as expected with 
// objects created using `Object.create` 
object.__proto__ = prototype; 
} 
if (properties !== void 0) { 
Object.defineProperties(object, properties); 
} 
return object; 
}; 
}

上面的代码考虑的就比较全面,但是需要另外引入Object.defineProperties的补丁才行,源码相对就比较多了。
// ES5 15.2.3.6 
// http://es5.github.com/#x15.2.3.6 
// Patch for WebKit and IE8 standard mode 
// Designed by hax <hax.github.com> 
// related issue: https://github.com/kriskowal/es5-shim/issues#issue/5 
// IE8 Reference: 
// http://msdn.microsoft.com/en-us/library/dd282900.aspx 
// http://msdn.microsoft.com/en-us/library/dd229916.aspx 
// WebKit Bugs: 
// https://bugs.webkit.org/show_bug.cgi?id=36423 
function doesDefinePropertyWork(object) { 
try { 
Object.defineProperty(object, "sentinel", {}); 
return "sentinel" in object; 
} catch (exception) { 
// returns falsy 
} 
} 
// check whether defineProperty works if it's given. Otherwise, 
// shim partially. 
if (Object.defineProperty) { 
var definePropertyWorksOnObject = doesDefinePropertyWork({}); 
var definePropertyWorksOnDom = typeof document == "undefined" || 
doesDefinePropertyWork(document.createElement("div")); 
if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) { 
var definePropertyFallback = Object.defineProperty; 
} 
} 
if (!Object.defineProperty || definePropertyFallback) { 
var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: "; 
var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: " 
var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " + 
"on this javascript engine"; 
Object.defineProperty = function defineProperty(object, property, descriptor) { 
if ((typeof object != "object" && typeof object != "function") || object === null) { 
throw new TypeError(ERR_NON_OBJECT_TARGET + object); 
} 
if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null) { 
throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor); 
} 
// make a valiant attempt to use the real defineProperty 
// for I8's DOM elements. 
if (definePropertyFallback) { 
try { 
return definePropertyFallback.call(Object, object, property, descriptor); 
} catch (exception) { 
// try the shim if the real one doesn't work 
} 
} 
// If it's a data property. 
if (owns(descriptor, "value")) { 
// fail silently if "writable", "enumerable", or "configurable" 
// are requested but not supported 
/* 
// alternate approach: 
if ( // can't implement these features; allow false but not true 
!(owns(descriptor, "writable") ? descriptor.writable : true) || 
!(owns(descriptor, "enumerable") ? descriptor.enumerable : true) || 
!(owns(descriptor, "configurable") ? descriptor.configurable : true) 
) 
throw new RangeError( 
"This implementation of Object.defineProperty does not " + 
"support configurable, enumerable, or writable." 
); 
*/ 
if (supportsAccessors && (lookupGetter(object, property) || 
lookupSetter(object, property))) 
{ 
// As accessors are supported only on engines implementing 
// `__proto__` we can safely override `__proto__` while defining 
// a property to make sure that we don't hit an inherited 
// accessor. 
var prototype = object.__proto__; 
object.__proto__ = prototypeOfObject; 
// Deleting a property anyway since getter / setter may be 
// defined on object itself. 
delete object[property]; 
object[property] = descriptor.value; 
// Setting original `__proto__` back now. 
object.__proto__ = prototype; 
} else { 
object[property] = descriptor.value; 
} 
} else { 
if (!supportsAccessors) { 
throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED); 
} 
// If we got that far then getters and setters can be defined !! 
if (owns(descriptor, "get")) { 
defineGetter(object, property, descriptor.get); 
} 
if (owns(descriptor, "set")) { 
defineSetter(object, property, descriptor.set); 
} 
} 
return object; 
}; 
} 
// ES5 15.2.3.7 
// http://es5.github.com/#x15.2.3.7 
if (!Object.defineProperties) { 
Object.defineProperties = function defineProperties(object, properties) { 
for (var property in properties) { 
if (owns(properties, property) && property != "__proto__") { 
Object.defineProperty(object, property, properties[property]); 
} 
} 
return object; 
}; 
}

EcmaScript6的类继承。
class module extends Base { 
constructor() { 
} 
}

越玩越像java了,不过es6很多浏览器还不支持。
最后推荐的写法:
if (!Object.create) { 
Object.create = function create(o) { 
var F = function(){}; 
F.prototype = o; 
var result = new F(); 
F.prototype = null; 
return result; 
} 
}
Javascript 相关文章推荐
JavaScript 利用StringBuffer类提升+=拼接字符串效率
Nov 24 Javascript
javascript中类的定义及其方式(《javascript高级程序设计》学习笔记)
Jul 04 Javascript
用javascript添加控件自定义属性解析
Nov 25 Javascript
js charAt的使用示例
Feb 18 Javascript
JavaScript实现找出数组中最长的连续数字序列
Sep 03 Javascript
jquery mobile页面跳转后样式丢失js失效的解决方法
Sep 06 Javascript
moment.js轻松实现获取当前日期是当年的第几周
Feb 05 Javascript
jquery带有索引按钮且自动轮播切换特效代码分享
Sep 15 Javascript
jQuery 实现评论等级好评差评特效
May 06 Javascript
jQuery与JS加载事件用法分析
Sep 04 Javascript
jQuery中 bind的用法简单介绍
Feb 13 Javascript
vue+element ui实现锚点定位
Jun 29 Vue.js
基于jquery的多功能软键盘插件
Jul 25 #Javascript
基于jQuery判断两个元素是否有重叠部分的代码
Jul 25 #Javascript
JavaScript中的apply()方法和call()方法使用介绍
Jul 25 #Javascript
关于JavaScript中原型继承中的一点思考
Jul 25 #Javascript
原生js 秒表实现代码
Jul 24 #Javascript
javascript设计模式 接口介绍
Jul 24 #Javascript
javascript设计模式 封装和信息隐藏(上)
Jul 24 #Javascript
You might like
PHP生成随机用户名和密码的实现代码
2013/02/27 PHP
PHP+Ajax实现上传文件进度条动态显示进度功能
2018/06/04 PHP
window.showModalDialog使用手册
2007/01/11 Javascript
DOM相关内容速查手册
2007/02/07 Javascript
javascript new后的constructor属性
2010/08/05 Javascript
javascript中使用css需要注意的地方小结
2010/09/01 Javascript
js弹出div并显示遮罩层
2014/02/12 Javascript
js+jquery实现图片裁剪功能
2015/01/02 Javascript
jQuery Validation PlugIn的使用方法详解
2015/12/18 Javascript
JavaScript实现相册弹窗功能(zepto.js)
2016/06/21 Javascript
chrome下判断点击input上标签还是其余标签的实现方法
2016/09/18 Javascript
微信小程序 swiper组件轮播图详解及实例
2016/11/16 Javascript
微信小程序开发之实现自定义Toast弹框
2017/06/08 Javascript
AngularJS 限定$scope的范围实例详解
2017/06/23 Javascript
原生js实现简单的焦点图效果实例
2017/12/14 Javascript
使用vue实现grid-layout功能实例代码
2018/01/05 Javascript
webpack 插件html-webpack-plugin的具体使用
2018/04/09 Javascript
详解微信小程序实现仿微信聊天界面(各种细节处理)
2019/02/17 Javascript
Python网络爬虫项目:内容提取器的定义
2016/10/25 Python
python的Tqdm模块的使用
2018/01/10 Python
在python plt图表中文字大小调节的方法
2019/07/08 Python
python3实现raspberry pi(树莓派)4驱小车控制程序
2020/02/12 Python
python小程序之4名牌手洗牌发牌问题解析
2020/05/15 Python
Python中的__init__作用是什么
2020/06/09 Python
pycharm专业版远程登录服务器的详细教程
2020/09/15 Python
html5实现多图片预览上传及点击可拖拽控件
2018/03/15 HTML / CSS
app内嵌H5 webview 本地缓存问题的解决
2020/10/19 HTML / CSS
会议活动邀请函
2014/01/27 职场文书
铁路个人事迹材料
2014/01/30 职场文书
乡镇组织委员个人整改措施
2014/09/16 职场文书
运动会广播稿150字(9篇)
2014/09/20 职场文书
2014年药店工作总结
2014/11/20 职场文书
六一文艺汇演开幕词
2015/01/29 职场文书
2015年领班工作总结
2015/04/29 职场文书
Android Flutter实现3D动画效果示例详解
2022/04/07 Java/Android
Windows Server 版本 20H2 于 8 月 9 日停止支持,Win10 版本 21H1 将于 12 月结束支
2022/07/23 数码科技