我感兴趣的源码
1函数、对象的嵌套问题
题目1.1
会输出什么?
var func = new Function("console.log('我是func')");
console.log(func());
题目1.2
会输出什么
var Cache1 = (function(){
var cache = {};
return {
getObj1:function(name){
if(name in cache){
return cache[name];
}
var temp = new Object(name);
cache[name] = temp;
return temp;
},
getObj2:function(name){
if(name in cache){
return cache[name];
}
var temp = new Object(name);
cache[name] = temp;
return temp;
}
}
})();
console.log(Cache1);
console.log(Cache1.getObj1('巧碧螺'));
2this相关的问题
2.1
var num = 20;
var obj = {
num:30,
fn:(function (num) {
this.num *= 3;
num += 15;
var num = 45;
return function () {
this.num *= 4;
num += 20;
console.log(this);
console.log(num);
}
})(num)
}
var fn = obj.fn;
fn();
obj.fn();
2.2
function a(xx){
this.x=xx;
return this;
}
var x=a(5);
console.log(x.x);
var y=a(6);
console.log(x.x);
console.log(y.x);
2.3
请说明要输出正确的myName的值要如何修改程序?
Foo = function(){
this.myName = "Foo function.";
}
Foo.prototype.sayHello = function(){
alert(this.myName);
}
Foo.prototype.bar = function(){
setTimeout(this.sayHello, 1000);
}
var f = new foo;
f.bar();
2.4
var length = 10;
function fn () {
console.log(this.length);
}
var obj = {
length: 5,
method: function (fn) {
fn();
arguments[0]();
},
fn:function(){
console.log(this);
console.log(this.length);
}
};
obj.method(obj.fn, 1);
2.5
window.val = 1;
var obj = {
val: 2,
dbl: function () {
this.val *= 2;
val *= 2;
console.log('val:', val);
console.log('this.val:', this.val);
}
};
// 说出下面的输出结果
obj.dbl();
var func = obj.dbl;
func();
3闭包相关的问题
闭包相关题目套路
- 先判断是否构成闭包(两个条件)。
- 如果构成闭包,观察外部函数是否只执行了一次。
- 每一个外部函数对应一组缓存(一组对应变量的最终值)
- 往难了走,难点会变成找到外部函数、找到闭包。
- 根据外部函数执行次数,找到最终值,
- 注意区分var和let。
- 只需关注真正处于闭包中的变量。
3.1
var i = 0;
function outerFn(){
function innnerFn(){
i++;
console.log(i);
}
return innnerFn;
}
var inner1 = outerFn();
var inner2 = outerFn();
inner1();
inner2();
inner1();
inner2();
3.2
function outerFn(){
var i = 0;
function innerFn(){
i++;
console.log(i);
}
return innerFn;
}
var inner = outerFn();
inner();
var inner2 = outerFn();
inner2();
inner2();
inner();
3.3
function fn(){
var arr = [];
for(var i = 0; i < 5; i++){
arr[i]= function(){
return i;
}
}
return arr;
}
var list = fn();
for(var i = 0; i < list.length; i++){
console.log(list[i]());
}
//----
function fn(){
var arr = [];
for(let i = 0; i < 5; i++){
arr[i]= function(){
return i;
}
}
return arr;
}
var list = fn();
for(var i = 0; i < list.length; i++){
console.log(list[i]());
}
3.4
(function() {
var m = 0;
function getM() { return m; }
function seta(val) { m = val; }
window.g = getM;
window.f = seta;
})();
f(100);
console.log(g())
3.5
```javascript <!DOCTYPE html>
- 1
- 2
- 3
<a name="n1HKR"></a>
### 3.6
```javascript
var fn = (function(){
var i=10;
function fn(){
console.log(++i);
}
return fn;
})()
fn();
fn();
答案
1
1.1
我是func
undefined
解析:
- console.log(函数的执行) ——>会先执行一次函数,再打印它的return对象
- 函数没有return或者没有返回值时会返回undefined
console.log(函数的名字,但不执行) ——>直接打印函数的代码
1.2
解析:输出1:
- Cache1本身是立即执行,所以console.log(函数的执行) ——>会先执行一次函数,再打印它的return对象
- 这次的return对象,是一个字面量表达的对象,分别有obj1和obj2两个方法。
- 输出2:
解析
- 自执行函数的this指向window
- 闭包涉及的局部变量会常驻内存
var num = 20; //window.num
var obj = { //obj.num
num:30,
fn:(function (num) { //自执行函数新开的num,随便叫什么都可以
this.num *= 3; //自执行函数的this指向window
num += 15;
var num = 45; //会声明提前,但由于var可以反复声明,因此没有影响。
//且因为不在最外层的window里,this.num和num是独立的、无关的
return function () { //函数新开的num形成了闭包,会“常驻内存”
this.num *= 4;
num += 20;
console.log(this);
console.log(num);
}
})(num)//往上找,由于没有函数作用域,直接找到全局作用域。
}
var fn = obj.fn;//自执行函数只会执行一次,从此fn和obj.fn都是return值
fn();
obj.fn(); //!<==>fn();对于fn()而言,调用它的对象是window
答案:
window
65
obj
85
2.2
解析:对于window,定义在最外层window上的var变量 和 window./this. 是一体的
function a(xx){
this.x=xx;
return this;
}
var x=a(5);//window.x = 5; window.x = window;
console.log(x.x);//window.x = window,因此window
var y=a(6);//window.x = 6; window.y = window
console.log(x.x);//第一个x是6,因此undefined
console.log(y.x);//window.y = window,而window.x = 6,因此6
答案:
window
undefined
6
2.3
解析:普通函数的this根据调用者动态改变,而回调函数在执行时已经找不到调用者了(即使setTimeOut设置s),会指向window,因此需要改变的就是回调函数的this指向 / 把myName放在全局上。
- 方法
- 法一:箭头函数
因为箭头函数里面所有的this会与其第一层的this保持一致,在定义时静态决定,不会动态改变。
foo = function(){
this.myName = "Foo function.";
}
foo.prototype.sayHello = function(){
alert(this.myName);
}
foo.prototype.bar = function(){
setTimeout(()=>{this.sayHello}, 1000);
}
var f = new foo;
f.bar();
法二:使用bind,修改this指向。
- 注意这里不能用call和apply,否则setTimeOut会失去意义
- bind会储存this
foo = function(){
this.myName = "Foo function.";
}
foo.prototype.sayHello = function(){
alert(this.myName);
}
foo.prototype.bar = function(){
setTimeout(this.sayHello.bind(this), 1000);
}
var f = new foo;
f.bar();
法三:调用一次foo()
相当于把myName放到windows对象上
foo = function(){
this.myName = "Foo function.";
}
foo.prototype.sayHello = function(){
alert(this.myName);
}
foo.prototype.bar = function(){
setTimeout(this.sayHello, 1000);
}
var f = new foo;
foo();
f.bar();
- 法四:添加参数that
foo = function(){
this.myName = "Foo function.";
}
foo.prototype.sayHello = function(that){
alert(that.myName);
}
foo.prototype.bar = function(){
var that = this;
setTimeout(function(){that.sayHello(that)}, 1000);
}
var f = new foo;
foo();
f.bar();
2.4
- 解析:
- 两次fn调用都调用的是obj.fn,但this指向都不是obj
- 对象方法中的方法指向window
- arguments 是一种特殊的对象,因此第二次fn的指向是arguments,而arguments.length = 2。 ```javascript var length = 10;
function fn () { console.log(this.length); }
var obj = { length: 5, method: function (fn) { fn(); arguments0; }, fn:function(){ console.log(this); console.log(this.length); } };
obj.method(obj.fn, 1);
- 答案:
```javascript
window
10
2
2.5
- 解析
- 因为js不存在块级作用域的概念,因此在非window作用域(即全局作用域)中调用不带this的变量时,会先从当前块中找,没有的话就从父块中找,直到找到window(window的挂载和var定义的变量是一体的)。
- 最后调用func()和obj.dbl是不一样的。 ```javascript window.val = 1;
var obj = {
val: 2,
dbl: function () {
this.val = 2;
val = 2;
console.log(‘val:’, val);
console.log(‘this.val:’, this.val);
}
};
// 说出下面的输出结果 obj.dbl(); var func = obj.dbl; func();
- 答案:
```javascript
2 4 8 8
3
3.1
- 解析
- 没有形成闭包
- 每次内部函数执行时的i,是炫从全局变量中获取的
- 没有形成闭包
答案
1 2 3 4
3.2
解析
- 构成闭包、外部函数执行两次、var
- 每重新执行一次外部函数,就会创建一组新的缓存。
function outerFn(){
var i = 0;
function innerFn(){
i++;
console.log(i);
}
return innerFn;
}
var inner = outerFn();
inner();//1
var inner2 = outerFn();
inner2();//1
inner2();//2
inner();//2
- 每重新执行一次外部函数,就会创建一组新的缓存。
- 构成闭包、外部函数执行两次、var
答案
1 1 2 2
3.3
解析
- 构成闭包、外部函数只执行一次、需要区分var和let
- ①和②中外部函数都只执行了一次,则分别对应一组缓存,只不过①中只缓存了一个i值,②中缓存了5个i值
//①
function fn(){
var arr = [];
for(var i = 0; i < 5; i++){
arr[i]= function(){
return i;//真正受缓存影响的只有这个i
}
}
return arr;
}
var list = fn();
for(var i = 0; i < list.length; i++){
console.log(list[i]());
}
//②
function fn(){
var arr = [];
for(let i = 0; i < 5; i++){
arr[i]= function(){
return i;//真正受缓存影响的只有这个i
}
}
return arr;
}
var list = fn();
for(var i = 0; i < list.length; i++){
console.log(list[i]());
}
- ①和②中外部函数都只执行了一次,则分别对应一组缓存,只不过①中只缓存了一个i值,②中缓存了5个i值
- 构成闭包、外部函数只执行一次、需要区分var和let
答案
55555
01234
3.4
解析
- 每一次外部函数的执行会对应一组缓存。
答案
100
3.5
解析
- 构成闭包、外部函数执行了3次
- 该题目是事件处理函数总闭包的写法
答案
//需要点击3次: 0 1 2
3.6
解析
- 构成闭包、外部函数只执行了一次
test.html里那道题11 12
https://blog.csdn.net/Hunt_bo/article/details/107699137
- 构成闭包、外部函数只执行了一次