浅谈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正则表达式中参数g(全局)的作用
Nov 11 Javascript
JavaScript高级程序设计阅读笔记(十六) javascript检测浏览器和操作系统-detect.js
Aug 14 Javascript
JS的replace方法介绍
Oct 20 Javascript
利用jQuery的deferred对象实现异步按顺序加载JS文件
Mar 17 Javascript
JQuery拖动表头边框线调整表格列宽效果代码
Sep 10 Javascript
关于Jquery中的bind(),on()绑定事件方式总结
Oct 26 Javascript
获取JavaScript异步函数的返回值
Dec 21 Javascript
Node.js中多进程模块Cluster的介绍与使用
May 27 Javascript
Swiper实现轮播图效果
Jul 03 Javascript
jQuery初级教程之网站品牌列表效果
Aug 02 jQuery
JS实现的数组去除重复数据算法小结
Nov 17 Javascript
微信小程序实现蒙版弹窗效果
Nov 01 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
56.com视频采集接口程序(PHP)
2007/09/22 PHP
防止MySQL注入或HTML表单滥用的PHP程序
2009/01/21 PHP
PHP 魔术函数使用说明
2010/05/14 PHP
JavaScript中的闭包原理分析
2010/03/08 Javascript
js动态加载以及确定加载完成的代码
2011/07/31 Javascript
创建公共调用 jQuery Ajax 带返回值
2012/08/01 Javascript
ie下jquery.getJSON的缓存问题的处理方法
2013/03/29 Javascript
解决JS中乘法的浮点错误的方法
2014/01/03 Javascript
JS中怎样判断undefined(比较不错的方法)
2014/03/27 Javascript
原生Js实现简易烟花爆炸效果的方法
2015/03/20 Javascript
jquery实现选中单选按钮下拉伸缩效果
2015/08/06 Javascript
JavaScript中push(),join() 函数 实例详解
2016/09/06 Javascript
jQuery实现的图片轮播效果完整示例
2016/09/12 Javascript
使用angular帮你实现拖拽的示例
2017/07/05 Javascript
vue环形进度条组件实例应用
2018/10/10 Javascript
jQuery表单元素过滤选择器用法实例分析
2019/02/20 jQuery
一文看懂如何简单实现节流函数和防抖函数
2019/09/05 Javascript
vscode自定义vue模板的实现
2021/01/27 Vue.js
python微信跳一跳系列之棋子定位像素遍历
2018/02/26 Python
TensorFlow的权值更新方法
2018/06/14 Python
Selenium鼠标与键盘事件常用操作方法示例
2018/08/13 Python
pytorch 可视化feature map的示例代码
2019/08/20 Python
Python定时发送天气预报邮件代码实例
2019/09/09 Python
Python3 main函数使用sys.argv传入多个参数的实现
2019/12/25 Python
详解HTML5中垂直上下居中的解决方案
2017/12/20 HTML / CSS
HTML5 progress和meter控件_动力节点Java学院整理
2017/07/06 HTML / CSS
美国在线鞋类零售商:LifeStride
2019/06/09 全球购物
应届毕业生如何写求职信
2014/02/16 职场文书
计生专干事迹
2014/05/28 职场文书
优秀毕业生求职信
2014/06/05 职场文书
中学生民族团结演讲稿
2014/08/27 职场文书
上班离岗检讨书
2014/09/10 职场文书
2014年高中生自我评价范文
2014/09/26 职场文书
增值税发票丢失证明
2015/06/19 职场文书
Python竟然能剪辑视频
2021/05/25 Python
健身房被搭讪?用python写了个小米计时器助人为乐
2021/06/08 Python