练习题1
// 作用域链
var a = 10
var b = 11
var c = 12
function test(a) {
/*
* EC(TEST)
* 作用域链:<EC(TEST),EC(G)>
* 初始THIS:window
* 形参赋值:a=10 [私有变量]
* 变量提升:var b; [私有变量]
*/
a = 1;
var b = 2;
c = 3; // => 全局的c=3
}
test(10);
console.log(a, b, c); // => 10 11 3
练习题2
// arguments映射机制
var a = 4;
function b(x, y, a) {
/*
* EC(B)
* 作用域链:<EC(B),EC(G)>
* 初始THIS: window
* 初始化ARGUMENTS:[1,2,3] (类数组集合)
* 形参赋值: x=1 y=2 a=3 【在非严格模式下,形参个对应的arguments会建立映射机制(一改都改),而严格模式下没有这种处理机制】
*/
console.log(a); // => 3
arguments[2] = 10;
console.log(a); // => 10
x = 20;
console.log(arguments[0]); // => 20
}
a = b(1, 2, 3);
console.log(a); // => undefined 函数执行没有返回值
练习题3
function func(x, y) {
// * ARGUMENTS: [10,20,30]
// * 形参赋值: x=10 y=20 【只有x、y跟arguments中的前两项有映射机制,只有这个阶段会建立这种机制,代码执行的时候就没用了】
var z = arguments[2];
console.log(z) // 30
x = 100;
console.log(arguments[0]); // => 100
arguments[1] = 200;
console.log(y); // => 200
z = 300;
console.log(z) // 300
console.log(arguments[2]); // => 30
}
func(10, 20, 30);
练习题4
var a = 9;
function fn() {
a = 0;
return function (b) {
return b + a++;
}
}
var f = fn();
console.log(f(5));
console.log(fn()(5));
console.log(f(5));
console.log(a);
练习题5
var test = (function (i) {
/*
* 自执行函数执行的返回值赋值给TEST
* EC(AN)
* 作用域链:<EC(AN),EC(G)>
* 形参赋值:i=2 ->[4]
*/
return function () {
/*
* EC(TEST)
* 作用域链:<EC(TEST),EC(AN)>
* ARGUMENTS:[5]
* 形参赋值:--
*/
alert(i *= 2); // i=i*2=4 i是EC(AN)中的 "4"
} // return BBBFFF000;
})(2);
// test = BBBFFF000 -> EC(AN)不释放
test(5);
练习题6
var x = 4;
function func() {
return function (y) {
console.log(y + (--x));
}
}
var f = func(5);
f(6);
func(7)(8);
f(9);
console.log(x);
练习题7
var x = 5,
y = 6;
function func() {
x += y;
func = function (y) {
console.log(y + (--x));
};
console.log(x, y);
}
func(4);
func(3);
console.log(x, y);
练习题8
function fun(n, o) {
console.log(o);
return {
fun: function (m) {
return fun(m, n);
}
};
}
var c = fun(0).fun(1);
c.fun(2);
c.fun(3);
练习题9
var num = 10;
var obj = {
num: 20
};
obj.fn = (function (num) {
// var num = 20
this.num = num * 3; // this = window, window.num = 20 *3 = 60
num++; // num = 20 + 1 = 21
return function (n) {
this.num += n;
num++;
console.log(num);
}
})(obj.num); // obj.num = 20
var fn = obj.fn;
fn(5); // this = window, n = 5, window.num + 5 = 65, num++ 就是21 + 1 = 22,输出22
obj.fn(10); // this = obj, n = 10, obj.num + 10 = 30, num++就是22 + 1 = 23, 输出23
console.log(num, obj.num); // 65, 30
练习题10
let obj = {
fn: (function () {
return function () {
console.log(this);
}
})()
};
obj.fn();
let fn = obj.fn;
fn();
练习题11
var fullName = 'language';
var obj = {
fullName: 'javascript',
prop: {
getFullName: function () {
return this.fullName;
}
}
};
console.log(obj.prop.getFullName());
var test = obj.prop.getFullName;
console.log(test());
练习题12
var name = 'window';
var Tom = {
name: "Tom",
show: function () {
console.log(this.name);
},
wait: function () {
// this:Tom
var fun = this.show;
fun(); // this:window => window.name => 'window'
}
};
Tom.wait();
练习题13
window.val = 1;
var json = {
val: 10,
dbl: function () {
this.val *= 2;
}
}
json.dbl();
// this:json
// json.val = json.val * 2 = 20
var dbl = json.dbl;
dbl();
// this:window
// window.val = window.val * 2 = 2
json.dbl.call(window);
// this:window
// window.val = window.val * 2 = 4
alert(window.val + json.val); //=>'24'
练习题14
(function () {
var val = 1; // 变量 【注意,这个变量不是全局的,而是匿名函数私有上下文中的】
var json = {
val: 10, // 属性 【不是变量】
dbl: function () {
// this:json
val *= 2; // val=val*2=1*2=2
}
};
json.dbl();
alert(json.val + val); //=>'12'
})();
练习题15
简述你对闭包的理解,以及其优缺点?
简洁的语言(说到重点),唠嗑式回答(切忌背书),尽可能往实战和源码上引导。
1、回答什么是闭包
2、闭包的优缺点
3、谈谈在项目中的应用
4、谈谈在源码中的应用
练习题16
下面代码输出的结果是多少,为什么?如何改造一下,就能让其输出 20 10?
// 1.当前这个名字只能在函数内部使用, 外部是无法使用的
// 2.具名化的名字在函数内部是不能被修改值的
// 3.特殊:但是如果当前这名字在函数内部被重点的基于var/let等声明过,一切以自己声明的为主,此时的名字存储的值就不在是函数了
var b = 10;
// 匿名函数具名化(建议)
(function b() {
b = 20;
console.log(b); // => 函数 b=20没有作用
})();
(function b() {
let b = 20;
console.log(b); // => 20
})();
console.log(b); // => 10
let func = function sum() {
// 当前函数本身(用来递归,代替传统的arguments.callee【严格模式不支持】)
console.log(sum);
};
// console.log(sum); // => Uncaught ReferenceError: sum is not defined
func();