浅谈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 相关文章推荐
浏览器无法运行JAVA脚本的解决方法
Jan 09 Javascript
不用构造函数(Constructor)new关键字也能实现JavaScript的面向对象
Jan 11 Javascript
JavaScript 模块化编程(笔记)
Apr 08 Javascript
js跨域资源共享 基础篇
Jul 02 Javascript
AngularJS删除路由中的#符号的方法
Sep 20 Javascript
JS模拟实现哈希表及应用详解
May 04 Javascript
小程序云开发教程如何使用云函数实现点赞功能
May 18 Javascript
如何用原生js写一个弹窗消息提醒插件
May 24 Javascript
vue+element树组件 实现树懒加载的过程详解
Oct 21 Javascript
KnockoutJS数组比较算法实例详解
Nov 25 Javascript
Node.JS如何实现JWT原理
Sep 18 Javascript
js实现日历
Nov 07 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 和 MySQL 基础教程(二)
2006/10/09 PHP
PHP array操作10个小技巧分享
2011/06/23 PHP
PHP封装的Twitter访问类实例
2015/07/18 PHP
JavaScript 页面编码与浏览器类型判断代码
2010/06/03 Javascript
JavaScript自定义方法实现trim()、Ltrim()、Rtrim()的功能
2013/11/03 Javascript
基于jQuery通过jQuery.form.js插件使用ajax提交form表单
2015/08/17 Javascript
jfinal与bootstrap的登录跳转实战演习
2015/09/22 Javascript
javascript图片切换综合实例(循环切换、顺序切换)
2016/01/13 Javascript
JavaScript基础之AJAX简单的小demo
2017/01/29 Javascript
js推箱子小游戏步骤代码解析
2018/01/10 Javascript
Vue实现点击时间获取时间段查询功能
2020/08/21 Javascript
vue+axios 前端实现的常用拦截的代码示例
2018/08/23 Javascript
关于vue利用postcss-pxtorem进行移动端适配的问题
2019/11/20 Javascript
[02:20]2014DOTA2西雅图邀请赛 MVP外卡赛首胜采访
2014/07/09 DOTA
[00:32]2018DOTA2亚洲邀请赛OpTic出场
2018/04/03 DOTA
深入理解 Python 中的多线程 新手必看
2016/11/20 Python
Python用list或dict字段模式读取文件的方法
2017/01/10 Python
socket + select 完成伪并发操作的实例
2017/08/15 Python
浅谈python迭代器
2017/11/08 Python
Python框架Flask的基本数据库操作方法分析
2018/07/13 Python
python实现五子棋人机对战游戏
2020/03/25 Python
关于 Python opencv 使用中的 ValueError: too many values to unpack
2019/06/28 Python
python 数据提取及拆分的实现代码
2019/08/26 Python
Python使用random模块生成随机数操作实例详解
2019/09/17 Python
Django-xadmin后台导入json数据及后台显示信息图标和主题更改方式
2020/03/11 Python
Python 程序员必须掌握的日志记录
2020/08/17 Python
Python模块常用四种安装方式
2020/10/20 Python
python 爬虫爬取京东ps4售卖情况
2020/12/18 Python
美国最受欢迎的度假目的地优惠套餐:BookVIP
2018/09/27 全球购物
Charles&Keith美国官方网站:新加坡快时尚鞋类和配饰零售商
2019/11/27 全球购物
美国高端牛仔品牌:Silver Jeans
2019/12/12 全球购物
《放飞蜻蜓》教学反思
2014/04/27 职场文书
关于美容院的活动方案
2014/08/14 职场文书
租房协议书样本
2014/08/20 职场文书
债务纠纷代理词
2015/05/25 职场文书
TensorFlow的自动求导原理分析
2021/05/26 Python