Javascript 返回自身实例的对象
背景:我的最新项目无法使用大型库,这让我很难过。我想从任何库中获得一些东西,比如缺少的函数Javascript 返回自身实例的对象,javascript,library-design,Javascript,Library Design,背景:我的最新项目无法使用大型库,这让我很难过。我想从任何库中获得一些东西,比如缺少的函数addClass,hasClass,removeClass,compatibleaddEventListener,等等。所以我创建了它,我希望在其他时间能得到一些意见,但我在设置它时遇到了一些麻烦 为便于使用,我希望对象在创建时返回其自身的新实例。 鉴于: $ = function() { this.name = "levi"; return this; }; console.log(
addClass
,hasClass
,removeClass
,compatibleaddEventListener
,等等。所以我创建了它,我希望在其他时间能得到一些意见,但我在设置它时遇到了一些麻烦
为便于使用,我希望对象在创建时返回其自身的新实例。
鉴于:
$ = function() {
this.name = "levi";
return this;
};
console.log($());
我们使用DOMWindow而不是$
,这是因为JavaScript中这个
的古怪特性。更奇怪的是,console.log(new$().name)
正确地返回“levi”。如果此
绑定到窗口,为什么对象正确获取了值?。我们只需添加新的console.log(new$())
就可以了。然而,我不想每次都写新的。所以我试着:
$ = function() {
var obj = function() {
this.name = "levi";
};
return new obj();
};
console.log($());
这给了我想要的东西,但似乎没有必要将对象封装在创建它的函数中。此外,返回的对象是obj
,而不是$
。比较测试将失败
还有什么其他方法可以做到这一点?有没有更优雅的解决方案?我毫不犹豫地重新思考我的整个过程。我认为自己很擅长使用JavaScript,但是创建新的JavaScript是我很陌生的事情。
有人认为以下解决方案有什么问题吗
$a = function() {};
$ = function() {
if (!(this instanceof $)) {
return new $();
}
this.name = "levi";
return this;
};
//helper function
var log = function(message) {
document.write((message ? message : '') + "<br/>");
};
log("$().name == window.name: " + ($().name == window.name)); //false
log("$().name: " + $().name); //levi
log("window.name: " + window.name); //result
log();
log("$a instanceof $: " + ($a instanceof $)); //false
log("typeof $a: " + (typeof $a)); //function
log("typeof $: " + (typeof $)); //function
$a=function(){};
$=函数(){
如果(!(此实例为$){
返回新的$();
}
this.name=“levi”;
归还这个;
};
//辅助函数
变量日志=函数(消息){
编写((消息?消息:“”)+“
”);
};
日志(“$().name==window.name:”+($().name==window.name))//假的
日志(“$().name:”+$().name)//利维
日志(“window.name:+window.name”)//结果
log();
日志(“$a instanceof$:”+($a instanceof$)//假的
日志(“类型$a:”+(类型$a))//功能
日志(“typeof$:”+(typeof$)//功能
它似乎在我所有的测试中都起作用 jQuery的方法是首先测试
这个
是否是窗口
(作为函数调用),如果是,则返回自身的新实例。例如:
var $ = function() {
if(this === window) {
return new $();
}
this.name = "levi";
return this;
};
console.log($());
这是因为当您正常调用函数(func()
)时,此
将与调用方的此
相同。(相关但并非无关:obj.method()
将具有此
为obj
),因为默认范围是窗口
,当您将其称为$
时,此
内部的将是窗口
当您使用new
调用函数时,发生的情况是JavaScript创建一个新对象,然后在this
设置为该对象的情况下调用您的函数
此解决方案之所以有效,是因为它首先测试此
是否为窗口
,因此被称为$()
。如果像$()
那样调用它,它将返回new$()
。否则,它将使用new$()
调用,并将按预期工作
> $ = function() {
> this.name = "levi";
>
> return this; };
>
> console.log($());
我们得到的是一个窗口而不是一个窗口$
当您将$作为function调用时,它的this关键字将被设置为全局对象,就像任何这样调用的函数一样
因为这种奇怪的性质
在JavaScript中
Javascript的this关键字*按照指定的方式工作。它与其他语言不同,但这就是它的工作原理
对我来说更奇怪的是
console.log($().name)正确返回
“李维”
将$作为函数调用时,其this关键字是全局对象,因此:
this.name = 'levi';
创建名为name的全局对象的属性,其值为“levi”。当你知道发生了什么时并不奇怪。:-)
我们可以添加新的console.log(新的
$())并且有效
这就是在javascript中调用构造函数的方式。当使用new调用函数时,其this关键字设置为新构造的对象,因此this.name
将创建该对象的新属性。顺便说一句,返回这个
是多余的,构造函数默认返回这个
> $ = function() {
> var obj = function() {
> this.name = "levi";
> };
>
> return new obj(); };
console.log($());这给了我什么
我想要,但似乎有点不必要
将对象包裹在
创建它的函数。进一步的
更重要的是,它是obj型而不是$
假设您使用的是typeof,它只能返回ECMA-262指定的一个值。该短列表(包括对象、数字、字符串等)不包括$
还有什么其他的方法
完成了吗
您可以使用您已经发现的方法,Lasse Reichstein Nielsen的克隆(Doublas Crockford也将其称为“beget”)和Richard Cornford的模块模式。使用谷歌,有很多关于以上所有内容的帖子。试试这样的方式:
function $(name){
if( !(this instanceof arguments.callee) ){
return new arguments.callee(name);
}
this.name = name;
return this;
}
更新:
@李维莫里森
编辑:是否有人发现以下解决方案有任何问题:
自从你问起,。请尝试以下方法:
var log = function(message){
if(message){
document.body.appendChild(document.createTextNode(message));
}
document.body.appendChild(document.createElement('br'));
}
做你想做的事情最简单的方法是(我认为): 仅仅返回
this
并不会创建$instance,这是因为this
是作为常规函数执行$
而创建的:在这种情况下,this
的值指向全局对象(在浏览器中:窗口
,实际调用executing$()
与窗口相同。$()
)。可以说,这是javascript生活的一个事实。console.log(new$().name)
显示正确的值是因为您将函数作为构造函数调用,它返回该构造函数的实例(即$
的新实例)。但是console.log($().name)
$ = function(){ if (!(this instanceof $)){ return new $; } this.name = 'levi'; return this; }