ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 10407|回复: 82

[分享] 再见了

[复制链接]

TA的精华主题

TA的得分主题

发表于 2012-10-25 07:33 | 显示全部楼层 |阅读模式
本帖最后由 yiyiyicz 于 2012-11-10 07:57 编辑

按照EH规定,此贴由于涉嫌刷分、盖楼、剽窃,所以删掉
不过我没有见过这样的规定

再见了,曾经帮助我的,和曾经在一起讨论的
有关资料的检索线索还在



TA的精华主题

TA的得分主题

 楼主| 发表于 2012-10-25 07:35 | 显示全部楼层
本帖最后由 yiyiyicz 于 2012-11-9 12:32 编辑

Javascript 面向对象编程---封装


TA的精华主题

TA的得分主题

 楼主| 发表于 2012-10-25 07:39 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 yiyiyicz 于 2012-11-9 12:31 编辑

Javascript 面向对象编程---构造函数的继承

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-10-25 07:42 | 显示全部楼层
本帖最后由 yiyiyicz 于 2012-11-9 12:31 编辑

Javascript 面向对象编程---非构造函数的继承

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-10-25 07:50 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 yiyiyicz 于 2012-11-9 12:30 编辑

JavaScript继承详解 <1>

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-10-25 07:58 | 显示全部楼层
本帖最后由 yiyiyicz 于 2012-11-9 12:30 编辑

JavaScript继承详解 <2>


TA的精华主题

TA的得分主题

 楼主| 发表于 2012-10-25 07:59 | 显示全部楼层
本帖最后由 yiyiyicz 于 2012-11-9 12:29 编辑

JavaScript继承详解 <3>

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-10-25 08:00 | 显示全部楼层
本帖最后由 yiyiyicz 于 2012-11-9 12:29 编辑

JavaScript继承详解 <4>




TA的精华主题

TA的得分主题

 楼主| 发表于 2012-10-25 08:01 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 yiyiyicz 于 2012-11-9 12:28 编辑

JavaScript继承详解 <5>



TA的精华主题

TA的得分主题

 楼主| 发表于 2012-10-25 08:02 | 显示全部楼层
本帖最后由 yiyiyicz 于 2012-11-9 12:28 编辑

JavaScript继承详解 <6>

在本章中,我们将分析Prototypejs中关于JavaScript继承的实现。
Prototypejs是最早的JavaScript类库,可以说是JavaScript类库的鼻祖。 我在几年前接触的第一个JavaScript类库就是这位,因此Prototypejs有着广泛的群众基础。

不过当年Prototypejs中的关于继承的实现相当的简单,源代码就寥寥几行,我们来看下。
早期Prototypejs中继承的实现
  1.         var Class = {
  2.             // Class.create仅仅返回另外一个函数,此函数执行时将调用原型方法initialize
  3.             create: function() {
  4.                 return function() {
  5.                     this.initialize.apply(this, arguments);
  6.                 }
  7.             }
  8.         };
  9.         
  10.         // 对象的扩展
  11.         Object.extend = function(destination, source) {
  12.             for (var property in source) {
  13.                 destination[property] = source[property];
  14.             }
  15.             return destination;
  16.         };
  17.         
复制代码
调用方式:
  1.         var Person = Class.create();
  2.         Person.prototype = {
  3.             initialize: function(name) {
  4.                 this.name = name;
  5.             },
  6.             getName: function(prefix) {
  7.                 return prefix + this.name;
  8.             }
  9.         };

  10.         var Employee = Class.create();
  11.         Employee.prototype = Object.extend(new Person(), {
  12.             initialize: function(name, employeeID) {
  13.                 this.name = name;
  14.                 this.employeeID = employeeID;
  15.             },
  16.             getName: function() {
  17.                 return "Employee name: " + this.name;
  18.             }
  19.         });


  20.         var zhang = new Employee("ZhangSan", "1234");
  21.         console.log(zhang.getName());   // "Employee name: ZhangSan"
复制代码
很原始的感觉对吧,在子类函数中没有提供调用父类函数的途径。

Prototypejs 1.6以后的继承实现 首先来看下调用方式:

  1.         // 通过Class.create创建一个新类
  2.         var Person = Class.create({
  3.             // initialize是构造函数
  4.             initialize: function(name) {
  5.                 this.name = name;
  6.             },
  7.             getName: function(prefix) {
  8.                 return prefix + this.name;
  9.             }
  10.         });
  11.         
  12.         // Class.create的第一个参数是要继承的父类
  13.         var Employee = Class.create(Person, {
  14.             // 通过将子类函数的第一个参数设为$super来引用父类的同名函数
  15.             // 比较有创意,不过内部实现应该比较复杂,至少要用一个闭包来设置$super的上下文this指向当前对象
  16.             initialize: function($super, name, employeeID) {
  17.                 $super(name);
  18.                 this.employeeID = employeeID;
  19.             },
  20.             getName: function($super) {
  21.                 return $super("Employee name: ");
  22.             }
  23.         });


  24.         var zhang = new Employee("ZhangSan", "1234");
  25.         console.log(zhang.getName());   // "Employee name: ZhangSan"
复制代码
这里我们将Prototypejs 1.6.0.3中继承实现单独取出来, 那些不想引用整个prototype库而只想使用prototype式继承的朋友, 可以直接把下面代码拷贝出来保存为JS文件就行了。

  1.         var Prototype = {
  2.             emptyFunction: function() { }
  3.         };

  4.         var Class = {
  5.             create: function() {
  6.                 var parent = null, properties = $A(arguments);
  7.                 if (Object.isFunction(properties[0]))
  8.                     parent = properties.shift();

  9.                 function klass() {
  10.                     this.initialize.apply(this, arguments);
  11.                 }

  12.                 Object.extend(klass, Class.Methods);
  13.                 klass.superclass = parent;
  14.                 klass.subclasses = [];

  15.                 if (parent) {
  16.                     var subclass = function() { };
  17.                     subclass.prototype = parent.prototype;
  18.                     klass.prototype = new subclass;
  19.                     parent.subclasses.push(klass);
  20.                 }

  21.                 for (var i = 0; i < properties.length; i++)
  22.                     klass.addMethods(properties[i]);

  23.                 if (!klass.prototype.initialize)
  24.                     klass.prototype.initialize = Prototype.emptyFunction;

  25.                 klass.prototype.constructor = klass;

  26.                 return klass;
  27.             }
  28.         };

  29.         Class.Methods = {
  30.             addMethods: function(source) {
  31.                 var ancestor = this.superclass && this.superclass.prototype;
  32.                 var properties = Object.keys(source);

  33.                 if (!Object.keys({ toString: true }).length)
  34.                     properties.push("toString", "valueOf");

  35.                 for (var i = 0, length = properties.length; i < length; i++) {
  36.                     var property = properties[i], value = source[property];
  37.                     if (ancestor && Object.isFunction(value) && value.argumentNames().first() == "$super") {
  38.                         var method = value;
  39.                         value = (function(m) {
  40.                             return function() { return ancestor[m].apply(this, arguments) };
  41.                         })(property).wrap(method);

  42.                         value.valueOf = method.valueOf.bind(method);
  43.                         value.toString = method.toString.bind(method);
  44.                     }
  45.                     this.prototype[property] = value;
  46.                 }

  47.                 return this;
  48.             }
  49.         };

  50.         Object.extend = function(destination, source) {
  51.             for (var property in source)
  52.                 destination[property] = source[property];
  53.             return destination;
  54.         };

  55.         function $A(iterable) {
  56.             if (!iterable) return [];
  57.             if (iterable.toArray) return iterable.toArray();
  58.             var length = iterable.length || 0, results = new Array(length);
  59.             while (length--) results[length] = iterable[length];
  60.             return results;
  61.         }

  62.         Object.extend(Object, {
  63.             keys: function(object) {
  64.                 var keys = [];
  65.                 for (var property in object)
  66.                     keys.push(property);
  67.                 return keys;
  68.             },
  69.             isFunction: function(object) {
  70.                 return typeof object == "function";
  71.             },
  72.             isUndefined: function(object) {
  73.                 return typeof object == "undefined";
  74.             }
  75.         });

  76.         Object.extend(Function.prototype, {
  77.             argumentNames: function() {
  78.                 var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1].replace(/\s+/g, '').split(',');
  79.                 return names.length == 1 && !names[0] ? [] : names;
  80.             },
  81.             bind: function() {
  82.                 if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
  83.                 var __method = this, args = $A(arguments), object = args.shift();
  84.                 return function() {
  85.                     return __method.apply(object, args.concat($A(arguments)));
  86.                 }
  87.             },
  88.             wrap: function(wrapper) {
  89.                 var __method = this;
  90.                 return function() {
  91.                     return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
  92.                 }
  93.             }
  94.         });

  95.         Object.extend(Array.prototype, {
  96.             first: function() {
  97.                 return this[0];
  98.             }
  99.         });
  100.         
复制代码
首先,我们需要先解释下Prototypejs中一些方法的定义。
&#10026;  argumentNames: 获取函数的参数数组

  1.                 function init($super, name, employeeID) {
  2.                 }
  3.                 console.log(init.argumentNames().join(",")); // "$super,name,employeeID"
复制代码
&#10026;  bind: 绑定函数的上下文this到一个新的对象(一般是函数的第一个参数)
  1.                 var name = "window";
  2.                 var p = {
  3.                     name: "Lisi",
  4.                     getName: function() {
  5.                         return this.name;
  6.                     }
  7.                 };

  8.                 console.log(p.getName());   // "Lisi"
  9.                 console.log(p.getName.bind(window)());  // "window"
复制代码
&#10026;  wrap: 把当前调用函数作为包裹器wrapper函数的第一个参数

  1.                 var name = "window";
  2.                 var p = {
  3.                     name: "Lisi",
  4.                     getName: function() {
  5.                         return this.name;
  6.                     }
  7.                 };

  8.                 function wrapper(originalFn) {
  9.                     return "Hello: " + originalFn();
  10.                 }

  11.                 console.log(p.getName());   // "Lisi"
  12.                 console.log(p.getName.bind(window)());  // "window"
  13.                 console.log(p.getName.wrap(wrapper)()); // "Hello: window"
  14.                 console.log(p.getName.wrap(wrapper).bind(p)()); // "Hello: Lisi"
复制代码
有一点绕口,对吧。这里要注意的是wrap和bind调用返回的都是函数,把握住这个原则,就很容易看清本质了。

后接18楼

http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html




评分

1

查看全部评分

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-6-16 10:04 , Processed in 0.036253 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表