jQuery'原型部分继承失败
Inheritance of jQuery's prototype partially fails
我想用Coffeescript创建一个UIObject类。这个类应该继承自jQuery,这样UIObject的实例就可以被使用,就好像它们是用jQuery创建的。
class UIObject
isObject: (val) -> typeof val is "object"
constructor: (tag, attributes) ->
@merge jQuery(tag, attributes), this
@UIObjectProperties = {}
merge: (source, destination) ->
for key of source
if destination[key] is undefined
destination[key] = source[key]
else if @isObject(source[key])
@merge(source[key], destination[key])
return
部分有效。考虑下面的Foobar类:
class Foobar extends UIObject
constructor: -> super("<h1/>", html: "Foobar")
$("body").append(new Foobar)
工作良好。BUT: (new Foobar). appendto ("body")放置标签,但也引发RangeError: Maximum call stack size exceeded
。
继承jQuery是一个坏主意吗?或者有解决方案吗?
对于那些不知道CoffeeScript的人,JavaScript源代码是:
var Foobar, UIObject;
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
return child;
};
UIObject = (function () {
UIObject.prototype.isObject = function (val) {
return typeof val === "object";
};
function UIObject(tag, attributes) {
this.merge(jQuery(tag, attributes), this);
this.UIObjectProperties = {};
}
UIObject.prototype.merge = function (source, destination) {
var key;
for (key in source) {
if (destination[key] === void 0) {
destination[key] = source[key];
} else if (this.isObject(source[key])) {
this.merge(source[key], destination[key]);
}
}
};
return UIObject;
})();
Foobar = (function () {
__extends(Foobar, UIObject);
function Foobar() {
Foobar.__super__.constructor.call(this, "<h1/>", {
html: "Foobar"
});
}
return Foobar;
})();
这确实有点难以实现(但很有创意!),因为jQuery和CoffeeScript类都有关于.constructor()
方法的想法。
在jQuery 1.6.4(今天CoffeeScript主页上使用的)中,在jQuery本身的第246行创建了一个无限递归,在这行代码中:
var ret = this.constructor();
这里的 this
指向您的构造函数,但jQuery希望它指向自己。你的@merge()
方法没有正确地替换构造函数。还有一种更黑客的方法,将@merge()
方法更改为:
merge: (source, destination) ->
for key of source
if destination[key] is undefined
destination[key] = source[key]
else if @isObject(source[key])
@merge(source[key], destination[key])
@constructor = jQuery
在"Try coffeescript"下的随机测试表明它可以工作,但我要小心以后可能会出现奇怪的效果,所以如果您继续使用这种方法,请彻底测试。
相关文章:
- 当json解析空响应时,Whatwg-Fetch失败,我该如何防止它
- 从控制器继承了隔离的作用域以生成可重用的指令
- JsFiddle在分叉后描述失败
- 两个指令创建新的继承的和隔离的作用域-元素得到哪个
- 为什么不'当单元测试出现解析错误时,我的因果报应测试会失败
- 当使用控制器作为语法时,如何从父指令继承属性
- 当一些承诺失败时,如何继续使用$q.all()
- 失败:等待Protractor与页面同步时出错:“”;在窗口上找不到角度”;
- 在Jquery中单击传播失败
- 以jquery方式继承Javascript
- 网页上失败的javascript会导致所有其他脚本失败
- 带有对象解析的响应javascript ajax失败
- 一台特定计算机的Ajax请求数据未定义/失败
- JavaScript对象不是从原型链继承的
- Nodejs服务器:加载资源失败:服务器的响应状态为404(未找到)
- 使用Object.create()的角度服务继承
- JavaScript继承(将原型设置为内部)失败
- jQuery'原型部分继承失败
- 高级javascript继承失败- parent <- parent <- child
- 在继承的ASP上使用Javascript清除选定项失败.净RadioButtonList