浅谈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 相关文章推荐
extjs 学习笔记 四 带分页的grid
Oct 20 Javascript
jquery 操作DOM的基本用法分享
Apr 05 Javascript
jquery多行滚动/向左或向上滚动/响应鼠标实现思路及代码
Jan 23 Javascript
javascript验证上传文件的类型限制必须为某些格式
Nov 14 Javascript
jquery操作HTML5 的data-*的用法实例分享
Aug 17 Javascript
jQuery中find()方法用法实例
Jan 07 Javascript
基于JS实现数字+字母+中文的混合排序方法
Jun 06 Javascript
Bootstrap 按钮样式与使用代码详解
Dec 09 Javascript
JS实现移动端在线签协议功能
Aug 22 Javascript
JS实现提示效果弹出及延迟隐藏的功能
Aug 26 Javascript
JS数组方法shift()、unshift()用法实例分析
Jan 18 Javascript
微信小程序上传帖子的实例代码(含有文字图片的微信验证)
Jul 11 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
ThinkPHP3.1新特性之动态设置自动完成及自动验证示例代码
2014/06/23 PHP
php几个预定义变量$_SERVER用法小结
2014/11/07 PHP
PHP实现链式操作的原理详解
2016/09/16 PHP
弹出广告特效(一个IP只弹出一次)的代码
2007/07/27 Javascript
jquery之empty()与remove()区别说明
2010/09/10 Javascript
NodeJS使用jQuery选择器操作DOM
2015/02/13 NodeJs
JS+CSS实现Div弹出窗口同时背景变暗的方法
2015/03/04 Javascript
js获取当前日期时间及其它操作汇总
2015/04/17 Javascript
javascript绘制漂亮的心型线效果完整实例
2016/02/02 Javascript
理解js回收机制通俗易懂版
2016/02/29 Javascript
JS不用正则验证输入的字符串是否为空(包含空格)的实现代码
2016/06/14 Javascript
BootStrap 模态框实现刷新网页并关闭功能
2017/01/04 Javascript
JavaScript实现鼠标点击导航栏变色特效
2017/02/08 Javascript
10道典型的JavaScript面试题
2017/03/22 Javascript
分析javascript中9 个常见错误阻碍你进步
2017/09/18 Javascript
jQuery实现的事件绑定功能基本示例
2017/10/11 jQuery
vue 解决addRoutes动态添加路由后刷新失效问题
2018/07/02 Javascript
layui复选框的全选与取消实现方法
2019/09/02 Javascript
nodejs开发一个最简单的web服务器实例讲解
2020/01/02 NodeJs
[02:17]《辉夜杯》TRG战队巡礼
2015/10/26 DOTA
全面了解Python环境配置及项目建立
2016/06/30 Python
python中安装Scrapy模块依赖包汇总
2017/07/02 Python
pandas求两个表格不相交的集合方法
2018/12/08 Python
Numpy中对向量、矩阵的使用详解
2019/10/29 Python
python PyAUtoGUI库实现自动化控制鼠标键盘
2020/09/09 Python
国际书籍零售商:Wordery
2017/11/01 全球购物
美国地毯购买网站:Rugs USA
2019/02/23 全球购物
劳资人员岗位职责
2013/12/19 职场文书
入党积极分子自我鉴定
2014/02/18 职场文书
大学毕业生求职自荐信
2014/02/20 职场文书
财产保全担保书范文
2014/04/01 职场文书
出生公证书样本
2014/04/04 职场文书
中学生评语大全
2014/04/18 职场文书
小学生运动会报道稿
2014/09/12 职场文书
2014年技术员工作总结
2014/11/18 职场文书
三八红旗手主要事迹材料
2015/11/04 职场文书