JS 继承又一法

简介: 首先贴出 DC 的 Object.create(),这是理解 js 创建对象的关键。如下: if (!Object.create) { /** * @ref https://developer.

首先贴出 DC 的 Object.create(),这是理解 js 创建对象的关键。如下:

if (!Object.create) {
    /**
    * @ref https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create
    */
    Object.create = function (o) {
        if (arguments.length > 1) {
            throw new Error('Object.create implementation only accepts the first parameter.');
        }
        function F() { }
        F.prototype = o;
        return new F();
    };
}
然后,贴出我写的 $$.define/ $$.mix。如下:

/**
* 定义一个类并让它继承于某个父类。
* @param {Function/[]/Object} fatherClass	父类函数引用
* @param {Function} classBody		子类函数体
* @param {Object}	 args			构造器参数,当前仅单参数
*/
$$.define = function (fatherClass, classBody, args) {
    if (fatherClass instanceof Array) {
        return $$.mix.apply(this, arguments);
    }

    // 如果从 Object 继承 则分配一个虚拟的父类。
    classBody.prototype = fatherClass === Object ? function () {
        this.constructor = function () { }
    } : fatherClass.prototype;


    var _pro = args ? new classBody(args) : new classBody;
    if (_pro.constructor) {
        _pro.constructor.prototype = _pro;
        return _pro.constructor;
    } else {
        function F() { } 	// 不提供构造器,设置一个空的。
        F.prototype = _pro;
        return F;
    }
}

/**
* 混入
* 参见:
* 《JS OO继承、多态一法》 http://blog.csdn.net/zhangxin09/article/details/6226279
* 《透视Ext JS 4类背后的机制与特点(上)》http://blog.csdn.net/zhangxin09/article/details/6197408
* @param {Function []} _Class 父类
* @param {Object} sub 子类
* @param {Array} args 可选的参数列表
*/
$$.mix = function (fatherClasses, classBody, args) {
    var _pro = args ? new classBody(args) : new classBody;
    _pro.constructor.prototype = _pro;

    for (var _fatherClass, _newSubClass, i = 0, j = fatherClasses.length; i < j; i++) {
        fatherClasses[i].prototype.constructor.call(_pro);
    }

    return _pro.constructor;
}

主要理解两点:

  • prototype = new Function,必须以“对象/函数”二义性的写法写出对象 prototype;
  • 构造器同一闭包下的写法。做法就是 new 了 prototype 之后,用其 constructor:Function 作构造器并赋予“类”返回。
举一个例子如下,某组件的写法:
$$.Component = function(){
	
}
/**
 * @param {Object} defaultCfg
 * @return {Object}
 */
$$.Component.loadCfg = function (defaultCfg, instanceCfg){
	instanceCfg = instanceCfg || new Object; // 新建一个配置容器
	for(var i in defaultCfg){
		if(!instanceCfg[i]){
			instanceCfg[i] = defaultCfg[i]; // 读取默认值
		}
	}
	
	return instanceCfg;
}
$$.Component.prototype = new function(){
	var getEl = document.getElementById;
	this.getEl = $$.Component.getEl = function(cfg){
		var el;
		if(cfg instanceof HTMLElement){
			el = cfg;
		}else if(typeof cfg == 'string'){
			el = getEl(cfg);
		}else if(cfg.el || cfg.container){
			return arguments.callee(cfg.el || cfg.container);
		}
		
		if(!el){
			console.dir(cfg);
			throw '没有指定的元素!';
		}
		
		return el;
	}
}

/**
 * @class $$.dhtml.ExpandBox
 * 可折叠的一个容器。结构如下:
 * <container>
 * 	<p>
 * 	</p>
 *  <mask></mask>
 * </container>
 */
$$.dhtml.ExpandBox = $$.define($$.Component, function(){
	this.constructor = function(el){
		this.container = el.container;
		// p 即 contetnt 区域是必须的
		
		// mask 是可选的,视乎你在 HTML 有否安排 mask tag
		this.mask = this.container.querySelector('.x-contMask');
		
		this.el = el;
		this.btn = el.toogleBtn;
		if(!this.btn){
			throw '找不到按钮!';
		}
		this.init();
	}
	
	this.showMoreText = "显示更多";
	this.closeText = '收 起';
	
	this.init = function (){
		this.p = this.container.querySelector('p');
		if(!this.p){
			throw '正文内容必须具备,请设置好元素!';
		}
		this.colHeight = this.p.clientHeight; /* 此处的 80 是与 css 设置的一样 */
		if(!this.colHeight){
			throw '不能获取原始高度';
		}

		this.btn.onClk(toggleHandler.bind(this));
		this.el.toggleHandler && this.btn.onClk(this.el.toggleHandler.bind(this));
	}
	
	var fxFn = $$.dhtml.Fx.slide;
	var dTime = 150;
	
	function toggleHandler(e){
		var btn = e.currentTarget;
		if(	btn.innerHTML == this.closeText){
//			fxFn(this.p, 'height', this.p.scrollHeight, this.colHeight, dTime);
			move(this.p, this.p.scrollHeight,  this.colHeight);
			btn.innerHTML = this.showMoreText;
			this.mask && this.mask.addClass('x-contMask_bg');
			this.currentState = 'closed';
		}else{
//			fxFn(this.p, 'height', this.colHeight, this.p.scrollHeight, dTime);
			move(this.p,  this.colHeight, this.p.scrollHeight);
			btn.innerHTML = this.closeText;
			this.currentState = 'opened';
			this.mask && this.mask.removeClass('x-contMask_bg');
		}
	}
	
	/**
	 * 缓动公式
	 * @param {Element} el
	 * @param {Number} s 初始值
	 * @param {Number} v 目标值
	 */
	function move(el, s, v){
		var style = el.style;
		function fx(){
//			debugger;
//			console.log(v);
			/*用来保存上一次的左标*/
			var old = style.height || s || 0;
			var x = window.parseInt(old);
			style.height = x + 0.800 * (v - x) + 'px';
			/*如果和上一次左边的坐标相等则清除定时器*/
			if(style.height === old)window.clearInterval(si);
		}
		var si = window.setInterval(fx, 20);
	}
});

目录
相关文章
|
10月前
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
10月前
|
JavaScript 前端开发 开发者
js实现继承怎么实现
【10月更文挑战第26天】每种方式都有其优缺点和适用场景,开发者可以根据具体的需求和项目情况选择合适的继承方式来实现代码的复用和扩展。
170 61
|
10月前
|
JavaScript 前端开发
Javascript如何实现继承?
【10月更文挑战第24天】JavaScript 中实现继承的方式有很多种,每种方式都有其优缺点和适用场景。在实际开发中,我们需要根据具体的需求和情况选择合适的继承方式,以实现代码的复用和扩展。
104 11
|
10月前
|
JavaScript 前端开发
如何使用原型链继承实现 JavaScript 继承?
【10月更文挑战第22天】使用原型链继承可以实现JavaScript中的继承关系,但需要注意其共享性、查找效率以及参数传递等问题,根据具体的应用场景合理地选择和使用继承方式,以满足代码的复用性和可维护性要求。
|
12月前
|
自然语言处理 JavaScript 前端开发
一文梳理JavaScript中常见的七大继承方案
该文章系统地概述了JavaScript中七种常见的继承模式,包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合继承等,并探讨了每种模式的实现方式及其优缺点。
一文梳理JavaScript中常见的七大继承方案
|
12月前
|
JavaScript 前端开发
js之class继承|27
js之class继承|27
|
12月前
|
JSON JavaScript 前端开发
js原型继承|26
js原型继承|26
|
12月前
|
JavaScript 前端开发 开发者
JavaScript 类继承
JavaScript 类继承
72 1
|
开发者 图形学 iOS开发
掌握Unity的跨平台部署与发布秘籍,让你的游戏作品在多个平台上大放异彩——从基础设置到高级优化,深入解析一站式游戏开发解决方案的每一个细节,带你领略高效发布流程的魅力所在
【8月更文挑战第31天】跨平台游戏开发是当今游戏产业的热点,尤其在移动设备普及的背景下更为重要。作为领先的游戏开发引擎,Unity以其卓越的跨平台支持能力脱颖而出,能够将游戏轻松部署至iOS、Android、PC、Mac、Web及游戏主机等多个平台。本文通过杂文形式探讨Unity在各平台的部署与发布策略,并提供具体实例,涵盖项目设置、性能优化、打包流程及发布前准备等关键环节,助力开发者充分利用Unity的强大功能,实现多平台游戏开发。
600 0
|
12月前
|
JavaScript 前端开发
JS的几种继承方式
JavaScript中的几种继承方式视频。
55 0