今天偶然发现这个问题。看不懂。 请大家帮忙解答。
var log = console.log;
var $$ = ajQuery = function(selector) {
log(‘aaa’);
if(!(this instanceof ajQuery)){
log(‘bbb’);
return new ajQuery(selector);
}
log(‘ccc’);
this.selector = selector;
return this
}
$$(‘xxxxx’);
就是上面这个代码。 大家可以 复制 到 console 执行。 结果是: aaa bbb aaa ccc Object { selector="xxxxx"}
函数调用一次,却被执行了 2次。 求解。
第一次打印的bbb,是因为this在此时表示global context,所以进入if条件语句,当执行new ajQuery()的时候,因为Function也是javascript里面的一个对象,当你使用new关键字的时候,其实就相当于把function作为构造方法来调用(另外一种调用方式是直接function()),而第二次使用new 调用的时候context就是该方法本身了,所以if判断为false。既然是调用,那方法当然会执行,所以你的这个方法会调用2次。希望对你有帮助。
感谢大家解答。 我直接 从 控制台 copy 过来的。 看来是这个网站的编辑器会做符号替换。
不知道是不是这样理解。 这里出现了 函数内部又调用了自身。 这里是一个典型的 递归调用。 但是 js 的递归调用 和 其他语言 不太一样。 其他语言 必须明确 获取 递归调用的返回值。 在这个 js 里面。 并没有 获取 return new ajQuery(selector); 的返回值。
第一次调用 this 指向 window 并且返回了一个 this 指向 ajQuery 的对象实例
还是不明白 this 怎么就变了。
js的递归应该和其他语言的递归一样,递归不是语言的特性。 你要理解这个问题,得搞明白javascript的执行上下文。在一个方法的内部,this的指向取决于该方法被调用的方式,并且当使用*’use strict’的时候,它还有有所不同。 简单来说,当你用普通的方法调用function的时候,也就是ajQuery(selector). 此时的context是这个方法被调用的时候的context,你的代码在浏览器里面是window*。那么此时this就是window 但是当方法以构造方法的形式调用的时候,也就是new ajQuery(selector),此时this指向用新建的对象,这里也就是ajQuery。 不知道说的清不清楚。。道友,老夫只能帮你到这儿了。
if (!(this instanceof ajQuery)) return new ajQuery(selector);
这是一个经典的自调用构造函数。检查this是否是ajQuery创建的实例,否的话创建。
起源
如果构造函数没有通过new而直接调用,函数中的this将会默认为全局对象,由此造成的破坏将会十分可观。 比如:
var Func = function () {
this.name = 'Ven';
this.age = 'unknown';
};
Func();
console.log(window.name, age);//log ' Ven unknown '
PS: return this 很多余啊