浅谈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 相关文章推荐
JQuery实现自定义对话框的代码
Jun 15 Javascript
JavaScript高级程序设计(第3版)学习笔记10 再访js对象
Oct 11 Javascript
使用jquery实现以post打开新窗口
Mar 19 Javascript
JS+CSS实现的日本门户网站经典选项卡导航效果
Sep 27 Javascript
jQuery Chart图表制作组件Highcharts用法详解
Jun 01 Javascript
javascript实现获取指定精度的上传文件的大小简单实例
Oct 25 Javascript
jquery实现左右滑动式轮播图
Mar 02 Javascript
jQuery制作input提示内容(兼容IE8以上)
Jul 05 jQuery
JS跳转手机站url的若干注意事项
Oct 18 Javascript
Angular中使用better-scroll插件的方法
Mar 27 Javascript
vue中实现上传文件给后台实例详解
Aug 22 Javascript
Element MessageBox弹框的具体使用
Jul 27 Javascript
基于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的ob_start() 控制您的浏览器cache
2009/08/03 PHP
php 短链接算法收集与分析
2011/12/30 PHP
PHP写的求多项式导数的函数代码
2012/07/04 PHP
基于php 随机数的深入理解
2013/06/05 PHP
PHP上传图片类显示缩略图功能
2016/06/30 PHP
PHP+JS实现的实时搜索提示功能
2018/03/13 PHP
PDO::_construct讲解
2019/01/27 PHP
PHP扩展mcrypt实现的AES加密功能示例
2019/01/29 PHP
laravel 实现根据字段不同值做不同查询
2019/10/23 PHP
用javascript来实现动画导航效果的代码
2007/12/16 Javascript
JavaScript中yield实用简洁实现方式
2010/06/12 Javascript
编写Js代码要注意的几条规则
2010/09/10 Javascript
jQuery的cookie插件实现保存用户登陆信息
2014/04/15 Javascript
如何用jquery控制表格奇偶行及活动行颜色
2014/04/20 Javascript
javascipt:filter过滤介绍及使用
2014/09/10 Javascript
浅谈Unicode与JavaScript的发展史
2015/01/19 Javascript
json的使用小结
2016/06/08 Javascript
深入分析javascript中console命令
2016/08/14 Javascript
Node连接mysql数据库方法介绍
2017/02/07 Javascript
js实现拖拽功能
2017/03/01 Javascript
node+express框架中连接使用mysql(经验总结)
2018/11/10 Javascript
Vue开发之封装分页组件与使用示例
2019/04/25 Javascript
浅谈Python实现2种文件复制的方法
2018/01/19 Python
关于python写入文件自动换行的问题
2018/06/23 Python
Python unittest 简单实现参数化的方法
2018/11/30 Python
安装docker-compose的两种最简方法
2019/07/30 Python
Python rabbitMQ如何实现生产消费者模式
2020/08/24 Python
爱淘宝:淘宝网购物分享平台
2017/04/28 全球购物
化工专业个人的求职信范文
2013/11/28 职场文书
赔偿协议书范本
2014/04/15 职场文书
充分就业社区汇报材料
2014/05/07 职场文书
大学教师师德师风演讲稿
2014/08/22 职场文书
纪律教育月活动总结
2014/08/26 职场文书
孝敬父母的活动方案
2014/08/31 职场文书
党的群众路线教育实践活动个人整改落实情况汇报
2014/10/28 职场文书
如何使用Python实现一个简易的ORM模型
2021/05/12 Python