闭包作用域实践题
let obj={
fn:(function(n){
//把自执行函数执行的返回结果赋值给fn
//this:window
return fucntion(){};
//=>fn等于这个返回的小函数
//this:obj
})(10
};
obj.fn();
//==============================================
function fn(){
//this:window
console.log(this);
}
document.body.onclick=function(){
//this:document.body
}
在全局作用域下,带var或者function声明的全局变量相当于给window设置了对应的属性(即全局变量也是属性),不带var等声明只是给window设置了对应的属性,如果let/const声明的,只是全局变量,没有给window设置属性
console.log(a);
var a=12; //=>a即使全局变量也是属性
console.log(a);
var a=12; //=>a只是属性
console.log(a);
let/const a=12; //=>只是全局变量
console.log(a); =>undefined
var a=12;
function fn(){
console.log(a); =>undrfined
var a=13;
}
fn();
console.log(a); =>12
//==============================================
console.log(a);
let a=12; //全局作用域,let没有变量提升
function fn(){
console.log(a);
let a=13;
}
fn();
console.log(a); //let没有变量提升但有此法解析
Uncaught ReferenceError: Cannot access 'a' before initialization
在当前作用域下(全局,私有,块作用域), 如果创建变量使用let/const声明的变量,一定不能在创建代码的前面使用这些变量,否则会报错:ReferenceError: Cannot access 'a' before initialization
块级作用域:
//let所在的大括号是一个块级作用域(私有作用域)
if (1===1){
var a=12; //没有块级作用域,还是全局下的a
let b=13; //有块级作用域,是私有kuai
}
console.log(a); =>12
console.log(b); =>b is not defined
let foo =1;
if ( !foo ) { } 非1转化为boolean为false !1 =>false (私有的就是只声明未定义undefined,非undefined 取反 undefined,0、NaN、空字符串、null、undefined这五个值代表的是false
),所以取反就是true,下面条件成立
var foo=1;
function bar(){
if (!foo){ //if ( !foo ) { } 非1转化为boolean为false !1 =>false (私有的就是`只声明未定义undefined,非undefined 取反 undefined,0、NaN、空字符串、null、undefined这五个值代表的是false`),所以取反就是true,下面条件成立
var foo=10; //不管条件是否成立都进行变量提升
}
console.log(foo) =>10
}
bar();
//==============================================
let foo=1; //块级作用域
function bar(){
console.log(foo) =>1
if (!foo){ //!foo == !1 1转换boolean为false, 此时为true
let foo=10;
console.log(foo) =>10
}
console.log(foo) =>1
}
bar();
//==============================================
let n=12;
if(1){ //1永远代表true , 相当于1===1
let n=13;
}
console.log(n) =>12
//==============================================
~ function () {
let n=12;
if(1){
let n=13;
}
console.log(n) =>12
}();
//==============================================
let n=12;
~ function () {
//作用域A
if(1){
//作用域B B是A的儿子
let n=13;
}
console.log(n) =>12
}();
if ( 1 ) { //1永远为true
let n=13;
}
let n=12;
~ function () {
let n=0;
if(1){
n=13;
}
console.log(n) =>13 私有块级作用域
}();
console.log(n) =>12 全局作用域
//==============================================
/*
* 不管条件是否成立都要进行变量提升
* var a; //全局作用域声明一个a也相当于给window.a ,a in window 是true,所以取反为false,a不存在,就是undefined
*/
if(!("a" in window)){
var a=12;
}
console.log(a); =>undefined
//==============================================
//逻辑|| 和逻辑与&& 在赋值操作中的意义
//A||B : 先验证A的真假,如果A为真,返回A的值,如果A为假返回的是B的值
//A&&B : A为真返回B的值,A为假返回A的值
let a = 0 || false;
console.log(a); =>FALSE
a = 1 || false;
console.log(a); =>1
a = 1 && 100;
console.log(a); =>100
a = 0 && 100;
console.log(a); =>0
a = 0 || 1 && 2 || 3; //=>先算1&&2 =>0||2||3 =>再算0||2 =>2 =>最后2||3 =>2
console.log(a); =>2
例如:
function fn(x ,callback){
//callback代表回调函数(传递的是一个函数):我们需要保证它是一个函数才能执行
//typeof callback === 'function' ? callback() : null;
callback && callback
}
fn(); //x和callback都是undefined
扩展:如果给x赋值,es6写法function fn(x=6 ,callback){ }
fn(10); //x是10,callback为undefined
fn(10, function(){}); //x为10,callback为function(){}
开启js严格模式:use strict
(es6或者平时开发,一般给予严格模式)
严格模式下arguments和形参映射机制就切断了
例题:
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);
function fn(i){
return function (n){
console.log(n + (i++))
}
}
var f =fn(10);
f(20);
fn(20)(40);
fn(30)(40);
f(30);