WEB前端高级教程|web前端高级JavaScript - 关于变量提升this指向闭包作用域的一些练习题

  • 变量提升作业
//1. 答案: // undefined undefined undefined // 10 13 14 // 100 13 200 // 12 undefined 200console.log(a, b, c); // => undefined undefined undefined var a = 12, b = 13, c = 14; function fn(a) { console.log(a, b, c); // => 10 13 14 a = 100; c = 200; console.log(a, b, c); // => 100 13 200 } b = fn(10); console.log(a, b, c); // => 12 undefined 200

//2. 答案:10 10var i = 0; function A() { var i = 10; function x() { console.log(i); } return x; } var y = A(); y(); // => 10 作用域为:EC(A) function B() { var i = 20; y(); // => 10 作用域依然是:EC(A) } B();

//3. 答案:1 {name: "jack"}var a=1; var obj ={ name:"tom" } function fn(){ var a2 = a; obj2 = obj; a2 =a; obj2.name ="jack"; } fn(); console.log(a); // => 1 console.log(obj); // => {name: "jack"}

//4. 答案:f a(){}var a = 1; function fn(a){ // 形参赋值 a = 1; //变量提升 var a //变量提升 function a(){} a被重新定义 console.log(a); //执行代码 输出函数a var a = 2; // a 被重新赋值为2 function a(){}//不再处理 } fn(a); // 运行结果 // => f a(){}

//5. 答案: // undefined undefined 12 // undefined 12 13 // 报错:Uncaught ReferenceError: a is not defined; console.log(a); // => undefined var a=12; function fn(){ console.log(a); // => undefined var a=13; } fn(); console.log(a); // => 12---- console.log(a); // => undefined var a=12; function fn(){ console.log(a); // => 12 a=13; } fn(); console.log(a); // => 13----console.log(a); // Uncaught ReferenceError: a is not defined; a=12; //没有var 不存在变量提升,在前面访问a肯定会报错 function fn(){ console.log(a); a=13; } fn(); console.log(a);

// 6. 答案:'hello' 'hello' 'hello' var foo='hello'; (function(foo){ //先形参赋值 //再变量提升 console.log(foo); // => 'hello' var foo=foo||'world'; console.log(foo); // => 'hello' })(foo); console.log(foo); // => 'hello'

// 7. 答案: f foo(){}11 // 产生两个上下文导致{ function foo() {} foo = 1; } console.log(foo); // => f foo(){}----{ function foo() {} foo = 1; function foo() {} } console.log(foo); // => 1----{ function foo() {} foo = 1; function foo() {} foo = 2; } console.log(foo); // => 1

// 8. 答案: // 2 1 // 4 1 // 4 1var x = 1; function func(x, y=function anonymousl(){x=2}){ x = 3; y(); console.log(x); // => 2 } func(5); console.log(x); // => 1//-------- var x = 1; function func(x, y=function anonmousl(){x=2}){ var x = 3; y(); console.log(x); // => 2此步做错,正确答案是3 } func(5); console.log(x); // => 1//-------- var x = 1; function func(x,y=function anonymousl(){x=2}){ var x = 3; var y = function anonymousl(){x=4} y(); console.log(x); // => 4 } func(5); console.log(x); // => 1

  • 数据类型和基础知识作业
// 1. 答案:"NaNTencentnull9false"let result = 100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false; console.log(result); // "NaNTencentnull9false"

//2. 答案:'no' 'ok'{} + 0 ? alert('ok') : alert('no'); // 执行alert('no'),{} + 0 不认为是数学运算,得结果是0转换为boolean类型为false 0 + {} ? alert('ok') : alert('no'); // 执行alert('ok'),0 + {} 对象先转为字符串[object Object],得结果为'0[object Object]',转换boolean为true

//3.答案:'number'let res = Number('12px'); //NaN if(res===12){ alert(200); }else if(res === NaN){ alert(NaN); }else if(typeof res === 'number'){//NaN是number类型 alert('number'); //此句代码会执行,弹出字符串number }else{ alert('Invalid Number') }

//4. 答案:[27, NaN, 1, 1, 27]let arr = [27.2,0,'0013','14px',123]; arr = arr.map(parseInt); console.log(arr); //[27, NaN, 1, 1, 27]parseInt(27.2, 0); // => 27; 0或不传默认是10进制 parseInt(0, 1); // => NaN; 进制没有1 parseInt('0013', 2); // => 1 ; 先转为int是13,取二进制值是1,再转换为10进制 1 * 2^0 = 1 parseInt('14px', 3); // => 1; 先转为int是14,取三进制值是1, 再转为10进制 1*3^0 = 1 parseInt(123, 4); // => 27; 四进制的123转换为10进制:3*4^0 + 2 * 4^1 + 1 * 4^2 = 3+8+16=27

  • 闭包的作用域
// 1. 答案:10 11 3var a = 10, b = 11, c = 12; function test(a) { a = 1; var b = 2; c = 3; } test(10); console.log(a, b, c); // => 10 11 3 => 函数test中的a和b都是函数自己的私有变量,只有c改变的是全局变量

//2. 答案:3 10 undefinedvar a = 4; function b(x, y, a) { console.log(a); // => 3 形参a(私有变量),实参值为3 arguments[2] = 10; //函数的参数列表,改变的是第三个参数的值 console.log(a); // => 10 a的值在上一步被改为10 } a = b(1, 2, 3); //函数没有返回值,默认返回undefined console.log(a); // undefined

//3. 答案:5 5 6 2var a = 9; function fn() { a = 0; //VO(G)中的a值变为0 return function (b) { return b + a++; } } var f = fn(); // function(b){return b + a++} console.log(f(5)); // => 5; VO(G)中的a值变为1 console.log(fn()(5)); // => 5; VO(G)中的a值变为先变为0再变为1 console.log(f(5)); // => 6; VO(G)中的a值变为2 console.log(a); // => 2

// 4. 答案:'4'var test = (function (i) { return function () { alert(i *= 2); } })(2); test(5); // => '4'

// 5. 答案:9 10 10 1var x = 4; function func() { return function(y) { console.log(y + (--x)); } } var f = func(5); f(6); // => 9; x = 3 func(7)(8); // => 10; x = 2 f(9); // => 10; x = 1 console.log(x); // => 1

// 6. 答案:11 61310 6var x = 5, y = 6; function func() { x += y; // => x = x + y = 5 + 6 = 11 func = function (y) { console.log(y + (--x)); // 13 }; console.log(x, y); // => 11 6 } func(4); func(3); console.log(x, y); // 10 6

// 7. 答案:undefined 0 1 1function fun(n, o) { console.log(o); // => undefined 0 1 1 return { fun: function (m) { return fun(m, n); } }; } var c = fun(0).fun(1); c.fun(2); c.fun(3);

WEB前端高级教程|web前端高级JavaScript - 关于变量提升this指向闭包作用域的一些练习题
文章图片

  • 8.简述对闭包的理解,及优缺点
函数在执行时,会形成一个私有上下文,私有上下文中的私有变量会被保护起来,与外界隔离,同时如果当前上下文中的一些事物被当前上下文以外的其它事物(如变量/事件绑定)所引用,那么当前这个上下文是不会被释放的并且这些变量和值会被保存起来,供其下级上下文使用。这种保存保护机制称为闭包。

【WEB前端高级教程|web前端高级JavaScript - 关于变量提升this指向闭包作用域的一些练习题】优点:可以访问函数内部的私有变量,解决一下事件循环绑定的问题。
缺点:使用多了就会消耗性能,占用大量内存空间,造成页面卡顿
  • 9.let和var 的区别
  • var 存在变量提升机制,let不存在
  • 全局上下文中,用var声明的变量,也会给window添加一个与变量名相同名称的属性,并且一个更改另一个也会随着改,let则不会
  • let声明的变量存在块级作用域,而var没有
  • 在相同向上文中,let不允许声明相同名称的变量,不管之前是用什么方式声明的都不能再基于let重复声明,而var没有限制,
//10. f b(){} 10 // 匿名函数具名化,函数名可以在函数内部使用,但是不能修改(修改无效) var b = 10; (function b() { b = 20; console.log(b); })(); console.log(b); //改造:能输出20 10 的两个方案 //方案一: var b = 10; (function b(b) { b = 20; console.log(b); })(b); console.log(b); //方案二: var b = 10; (function b() { var b = 20; console.log(b); })(); console.log(b);

//11.实现函数fnfunction fn(m,n){ return function(x){ return m + n + x; } } let res = fn(1,2)(3); console.log(res);

  • THIS 的作业题
//1. 答案:22 2365 30var num = 10; var obj = { num: 20 }; obj.fn = (function (num) { this.num = num * 3; // => window.num = 20 * 3 = 60 num++; //21 return function (n) { this.num += n; //window.num = 65; obj.num = 30 num++; //22 console.log(num); //22 23 } })(obj.num); var fn = obj.fn; fn(5); obj.fn(10); console.log(num, obj.num); // 65 30

//2. 答案:{fn: f(){}}Windowlet obj = { fn: (function () { return function () { console.log(this); } })() }; obj.fn(); // => obj对象 let fn = obj.fn; fn(); // => window

//3. 答案:undefined 'language'var fullName = 'language'; var obj = { fullName: 'javascript', prop: { getFullName: function () { return this.fullName; } } }; console.log(obj.prop.getFullName()); // => undefined var test = obj.prop.getFullName; console.log(test()); // => 'language'

//4. 答案: 'window'var name = 'window'; var Tom = { name: "Tom", show: function () { console.log(this.name); }, wait: function () { var fun = this.show; fun(); // => 'window' } }; Tom.wait();

//5. 答案:'24'window.val = 1; var json = { val: 10, dbl: function () { this.val *= 2; } } json.dbl(); // => json.val = 20 var dbl = json.dbl; dbl(); // => window.val = 2 json.dbl.call(window); // window.val = 4 alert(window.val + json.val); '24'

//6. 答案:'12'(function () { var val = 1; var json = { val: 10, dbl: function () { val *= 2; } }; json.dbl(); alert(json.val + val); // '12' })();

    推荐阅读