浅谈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 02 Javascript
js获取某月的最后一天日期的简单实例
Jun 22 Javascript
封装的jquery翻页滚动(示例代码)
Nov 18 Javascript
jquery使用jxl插件导出excel示例
Apr 14 Javascript
JavaScript中的对象序列化介绍
Dec 30 Javascript
情人节单身的我是如何在敲完代码之后收到12束玫瑰的(javascript)
Aug 21 Javascript
Javascript中for循环语句的几种写法总结对比
Jan 23 Javascript
Angular动态添加、删除输入框并计算值实例代码
Mar 29 Javascript
微信小程序 实现动态显示和隐藏某个控件
Apr 27 Javascript
laydate 显示结束时间不小于开始时间的实例
Aug 11 Javascript
浅谈Javascript中的对象和继承
Apr 19 Javascript
Vue基于vuex、axios拦截器实现loading效果及axios的安装配置
Apr 26 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 采集程序原理分析篇
2010/03/05 PHP
PHP5.6新增加的可变函数参数用法分析
2017/08/25 PHP
PHP实现PDO操作mysql存储过程示例
2019/02/13 PHP
PHPstorm激活码2020年5月13日亲测有效
2020/09/17 PHP
一句话JavaScript表单验证代码
2009/08/02 Javascript
学习ExtJS table布局
2009/10/08 Javascript
jQuery EasyUI 中文API Layout(Tabs)
2010/04/27 Javascript
自写简单JS判断是否已经弹出页面
2010/10/20 Javascript
利用div+jquery自定义滚动条样式的2种方法
2013/07/18 Javascript
jQuery之ajax删除详解
2014/02/27 Javascript
js实现弹出窗口、页面变成灰色并不可操作的例子分享
2014/05/10 Javascript
JavaScript中的逻辑判断符&amp;&amp;、||与!介绍
2014/12/31 Javascript
jQuery实现多级联动下拉列表查询框
2016/01/18 Javascript
js基于cookie记录来宾姓名的方法
2016/07/19 Javascript
JS常见算法详解
2017/02/28 Javascript
使用watch监听路由变化和watch监听对象的实例
2018/02/24 Javascript
JS 使用 window对象的print方法实现分页打印功能
2018/05/16 Javascript
详解Vue组件之间通信的七种方式
2019/04/14 Javascript
转换layUI的数据表格中的日期格式方法
2019/09/19 Javascript
JS实现iframe中子父页面跨域通讯的方法分析
2020/03/10 Javascript
python基于pyDes库实现des加密的方法
2017/04/29 Python
python 利用pandas将arff文件转csv文件的方法
2019/02/12 Python
Pytorch使用MNIST数据集实现基础GAN和DCGAN详解
2020/01/10 Python
PyTorch如何搭建一个简单的网络
2020/08/24 Python
HTML5是否真的可以取代Flash
2010/02/10 HTML / CSS
使用HTML5 Canvas绘制圆角矩形及相关的一些应用举例
2016/03/22 HTML / CSS
HTML5 通过Vedio标签实现视频循环播放的示例代码
2020/08/05 HTML / CSS
企业业务员岗位职责
2014/03/14 职场文书
2014年巴西世界杯口号
2014/06/05 职场文书
群众路线剖析材料
2014/09/30 职场文书
安全保证书格式
2015/02/28 职场文书
入团介绍人意见范文
2015/06/04 职场文书
庆七一主持词
2015/06/29 职场文书
导游词之潮音寺
2019/09/26 职场文书
10大幻兽系恶魔果实 蝙蝠果实上榜,第一自愈能力强
2022/03/18 日漫
SQL Server中锁的用法
2022/05/20 SQL Server