浅谈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(一)工厂方式 js面象对象的定义方法
Dec 15 Javascript
jQuery表单域选择器用法分析
Feb 10 Javascript
Jquery插件easyUi实现表单验证示例
Dec 15 Javascript
JavaScript实现页面跳转的方式汇总
May 16 Javascript
jQuery事件委托之Safari
Jul 05 Javascript
详解vue2路由vue-router配置(懒加载)
Apr 08 Javascript
微信小程序 动态传参实例详解
Apr 27 Javascript
node中实现删除目录的几种方法
Jun 24 Javascript
使用Node.js在深度学习中做图片预处理的方法
Sep 18 Javascript
JavaScript Array对象使用方法解析
Sep 24 Javascript
JavaScript RegExp 对象用法详解
Sep 24 Javascript
uni-app如何页面传参数的几种方法总结
Apr 28 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
解析htaccess伪静态的规则
2013/06/18 PHP
PHP生成静态HTML页面最简单方法示例
2015/04/09 PHP
PHP中的函数声明与使用详解
2017/05/27 PHP
php实现微信公众号创建自定义菜单功能的实例代码
2019/06/11 PHP
window.showModalDialog使用手册
2007/01/11 Javascript
Highslide.js是一款基于js实现的网页中图片展示插件
2020/03/30 Javascript
jquery1.4.2 for Visual studio 2010 模板文件
2010/07/14 Javascript
fancybox1.3.1 基于Jquery的插件在IE中图片显示问题
2010/10/01 Javascript
javascript淡入淡出效果的实现思路
2012/03/31 Javascript
js拆分字符串并将分割的数据放到数组中的方法
2015/05/06 Javascript
angularjs学习笔记之完整的项目结构
2015/09/26 Javascript
JS递归遍历对象获得Value值方法技巧
2016/06/14 Javascript
Vue.js组件tree实现省市多级联动
2016/12/02 Javascript
使用Sonarqube扫描Javascript代码的示例
2018/12/26 Javascript
Javascript读写cookie的实例源码
2019/03/16 Javascript
ES6入门教程之变量的解构赋值详解
2019/04/13 Javascript
p5.js码绘“跳动的小正方形”的实现代码
2019/10/22 Javascript
vue+vant使用图片预览功能ImagePreview的问题解决
2020/04/10 Javascript
python中的全局变量用法分析
2015/06/09 Python
Python实现各种排序算法的代码示例总结
2015/12/11 Python
Python基于高斯消元法计算线性方程组示例
2018/01/17 Python
python 巧用正则寻找字符串中的特定字符的位置方法
2018/05/02 Python
Python进阶之全面解读高级特性之切片
2019/02/19 Python
实例详解Matlab 与 Python 的区别
2019/04/26 Python
Django通用类视图实现忘记密码重置密码功能示例
2019/12/17 Python
python3光学字符识别模块tesserocr与pytesseract的使用详解
2020/02/26 Python
Python中random模块常用方法的使用教程
2020/10/04 Python
css和css3弹性盒模型实现元素宽度(高度)自适应
2019/05/15 HTML / CSS
法国购买隐形眼镜和眼镜网站:Optical Center
2019/10/08 全球购物
Diesel美国网上商店:意大利牛仔时装品牌
2020/12/10 全球购物
小学安全教育材料
2014/02/17 职场文书
基层干部2014全国两会学习心得体会
2014/03/10 职场文书
毕业生就业协议书
2014/04/11 职场文书
工作作风承诺书
2014/08/30 职场文书
违反交通安全法检讨书
2014/10/24 职场文书
详解python的内存分配机制
2021/05/10 Python