JavaScript学习笔记6

一、作业域初探

作用域定义:变量(变量作用于又称上下文)和函数生效(能被访问)的区域

全局、局部变量

作用域的访问顺序

作用域:函数里面的可以访问外面的全局变量

在这里插入图片描述
函数外面不能用函数里面的。里面的可以访问外面的,外面的不能访问里面的,彼此独立的区间不能相互访问

test{}和demo{}不能互相访问,但是可以访问外面的全局变量

例:彼此独立的区间不能相互访问,全局变量都可以访问

在这里插入图片描述

function test(){
 var a =123;
 function demo(){
var b = 234;
document.write(a);
}
demo();
document.write(b);
}
上面的 document.write(b);不能访问 var b ,
上面的 document.write(a);可以访问 a

外层函数不能访问里层的,里层的可以访问外层的,越往里权限越大

作业:要求输入一串低于10位的数字,输入这串数字的中文大写

例如:input :10000 output:壹万

例如:input :1001010 output:壹佰万壹仟零壹拾

千分位如果是 0 必须读零


二、js 运行三部曲

1 语法分析 → 2 预编译 → 3 解释执行


三、预编译前奏

function test(){
 console.log('a');
}
test();
//a
//可以执行
test();
function test(){
 console.log(‘a’);
}
//也能执行,因为有预编译的存在
var a = 123;
console.log(a);
//答案 123
例 
console.log(a);
var a = 123;
//答案 undefined
例
console.log(a);

//Uncaught ReferenceError: a is not defined

函数声明整体提升函数不管写在哪里,都会被提升到逻辑的最前面。所以不管在哪里调用,本质上都是在后面调用

变量 声明提升把var a提升到最前面

var a=123;
这是变量声明再赋值
变量 声明提升是把它拆分成var a; a=123;然后把 var a 提升到最前面

上面这两句话没办法解决下面例子的问题

  function a(a) {
            var a = 234;
            var a = function() {

            }
            a();
        }
        var a=1232;

1.imply global

imply global 暗示全局变量 :即任何变量,如果变量未经声明就赋值,此变量就为全局对象(就是window)所有

全局变量是window

window.a = 10;
a = 10; === > windows.a = 10;

2.一切声明的全局变量,全是window的属性

var a=123;==>window.a=123;

window就是全局的域

如果在全局变量中var a=123;那么就会返回到window

var a = 123
console.log(a) ===> window.a

例 var a = b = 234;
是把 234 的值赋给 b,在把 b 的值赋给 a 

此时访问a和b都属于window域

function test(){
 var a = b = 123;
}
test()

写test()代表执行test,赋值是自右向左的,上面先把123赋值给b的时候,b未经声明,然后再声明a,再把b的值赋给a,导致b未经声明,所以b归window所有
访问window.a是undefined,访问window.b是123


function test(){
 var b = 123;
}
test();
console.log(window.b);
//答案 undefined
//window 就是全局
var a = 123;
console.log(a); → console.log(window.a);var a = 123;
var b = 234;
var c = 345;
window{
 a : 123,
 b : 234,
 c : 345
}
//如果 var a 对应会有 window.a

四、预编译(解决执行顺序问题)

function fn(a){
 console.log(a);
 var a = 123;
 console.log(a);
 function a (){}
 console.log(a);
 var b = function (){}
 console.log(b);
 function d() {}
}
fn(1);

//答案是 function a(){}//123//123//function (){}

这个例子的形参是(a),变量声明也是 a

上面的例子按四部曲变化如下:
找形参和变量声明,将变量和形参(a)名作为 AO 属性名,值为 undefined ,AO{
 a : undefined,
 b : undefined,
}

(把实参值传到形参里)AO{
 a : 1,
 b : undefined,
}

function a () {}function d () {}都是函数声明,但是 var b = function (){}不是。AO{
 a : function a () {},
 b : undefined,
 d : function d () {}
}

执行第一行 console.log(a);时,用的是 AO{
a : function a () {},
b : undefined,
d : function d () {}
}

执行 var a =123;改变的是 AO{
 a : 123,
 b : undefined,
 d : function d () {}
}b = function (){}AO{
 a : 123,
 b : function () {},
 d : function d () {}
}

预编译发生在函数执行的前一刻


五、(函数)预编译的四部曲:

1.创建 AO 对象 Activation Object(执行期上下文,作用是理解的作用域,函数产生的执行空间库)

2.找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined
相当于 AO{
a : undefined,
b : undefined
}

3.将实参值和形参统一(把实参值传到形参里)

4.在函数体里面找函数声明,值赋予函数体
(先看自己的 AO,再看全局的 GO)

在这里插入图片描述

答题过程:找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined, AO{
 a : 1,
 b : undefined,
 c : undefined
}

函数声明 function b(){}function d(){}AO{
 a : 1,
 b : function b(){},
 c : undefined,
 d : function d(){}
}

执行 console.log(a);答案是 1

执行 c = 0;AO{
 a : 1,
 b : function b(){},
 c : 0,
 d : function d(){}
}

var c 不用管,因为 c 已经在 AO 里面了

执行 a = 3;AO{
 a : 3,
 b : function b(){},
 c : 0,
 d : function d(){}
}

执行 b = 2;AO{
 a : 3,
 b : 2,
  c : 0,
 d : function d(){}
}

执行 console.log(b);答案是 2

function b () {}function d(){}已经提过了,不用管

执行 console.log(b);答案是 2


在这里插入图片描述
一旦有重名的,一但有 a 变量又有 a 函数【如 function a (){}】,又在第一条访问的是a,一定是函数

答题过程: 将变量和形参名作为 AO 属性名,AO{
a : undefined,
b : undefined
}

将实参值和形参统一,AO{
a : 1,
b : undefined
}

找函数声明 function a (){}AO{
a : function a (){},
b : undefined
}

执行 console.log(a);答案是 function a (){}

执行 console.log(b);答案是 undefined

执行 var b = 234;AO{
a : function a (){},
b : 234
}

执行 console.log(b);答案是 234

执行 a = 123;AO{
a : 123,
b : 234
}

执行 console.log(a);答案是 123

然后 function a (){};var a ;都可以不看了

执行 b = 234,b 值还是 234,不变

执行 var b = function (){},变 AO{
a : 123,
b : function (){}
}

执行 console.log(a);答案是 123

执行 console.log(b);答案是 function (){}

下面开始讲全局的预编译

例 console.log(a);
var a = 123;
答案 undefined
例 console.log(a);
var a = 123;
function a (){}
答案是打印 a 是 function a (){}

全局的预编译三部曲:
1、生成了一个 GO 的对象 Global Object(window 就是 GO)

2、找形参和变量声明,将变量和形参名作为 GO 属性名,值为 undefined

3、在函数体里面找函数声明,值赋予函数体


例 console.log(a);
var a = 123;
function a (){}

答案过程,GO{
 a : undefined
}
函数声明 GO{
 a : function a (){}
}
执行 var a = 123;GO{
 a : 123
}
执行 console.log(a);就是 123

GO === window, GO 和 window 是一个东西

console.log(a);和 console.log(window.a);和 console.log(go.a);是一样

任何全局变量都是 window 上的属性
没有声明就是赋值了,归 window 所有,就是在 GO 里面预编译

function test(){
 var a = b =123;
 console.log(window.b);
}
test();
答案 a 是 undefined,b 是 123
先生成 GO{
 b : 123
}
再有 AO{
a : undefined
}



先生成 GO 还是 AO?
想执行全局,先生成 GO,在执行 test 的前一刻生成 AO
在几层嵌套关系,近的优先,从近的到远的,有 AO 就看 AO,AO 没有才看 GO

在这里插入图片描述

答题过程:想执行全局,先有 GO,GO{
 test : undefined
24
}
发现有函数声明 GO{
 test : function (){
.....
} }
执行 console.log(test),
执行 test(1)之前生成 AO{
 test : function (){}
}
执行 var test = 234;变成 234
AO 上面有就用 AO 的,没有就看 GO 的 例 var global = 100;
function fn(){
 console.log(global);
}
fn();
答题过程 GO{
 global : undefined,
 fn : function(){.....}
}
执行 var global = 100;GO{
 global : 100,
 fn : function(){.....}
}
不看 function fn(){...}里面的东西
执行 fn()之前 AO{
 访问 GO 的 global
}

在这里插入图片描述

答题过程,GO{
 global : undefined
 fn : undefined(没用可以不写) }GO{
 global : 100
 fn : undefined
}
执行 fn()之前,AO{
 global : undefined
}
执行结果是 undefined,200

在这里插入图片描述

答案//undefined //undefined //234 //234
过程 GO{
 a : undefined
 test:undefined(没用可以不写) }
AO{
 b : undefined //不管 if(a){},可以提出 var b 的 b }
执行到 c=234GO{
 a : undefined
 c : 234
}
执行到 a=10GO{
 a : 10
 c : 234}
25function bar(){
return foo;
foo = 10;
function foo(){}
var foo = 11;
}
console.log(bar());
答案:function foo(){}
如果在第一行 return foo,下面有 foo 这个函数,一定打印这个函数
例 console.log(bar());
function bar(){
 foo = 10;
 function foo(){}
 var foo = 11;
 returm foo;
}答案 11
例 console.log(b);
var b = function (){}
答案是 undefined


现在在 if 里面定义函数声明 function 是不允许的,但是过去可以,下面就是过去的旧题,按可以来做
在这里插入图片描述

GO{
 a : undefined
}

GO{
 a : undefined
 demo : function (){}
}

开始执行 a=100GO{
 a : 100
 demo : function (){}
}

AO{
 e : undefined,
 b : undefined,
 c : undefined,
 a : undefined
}

形参实参相统一,AO{
 e : 1,
 b : undefined,
 c : undefined,
 a : undefined
}

赋值 AO{
 e : function e (){},
 b : undefined,
 c : undefined,------旧规则里面可以提出 function(){}
 a : undefined
}

执行 arguments[0] = 2;实参列表和传参是否相映射,变 AO{
 e : 2,
 b : undefined,
 c : undefined,
 a : undefined
}

执行 console.log(e);答案 2
if(a)由于 a 在 AO 里面是 undefined,所以不走 if 
26
执行 a = 10;AO{
 e : 2,
 b : undefined,
 c : undefined,
 a : 10
}

执行 console.log(b),答案 undefined

执行 f = 123,变 GO{
 a : 100,
demo : function (){},
 f : 123
}

执行 console.log(c); 之前打印 function(){},改语法后打印 undefined

执行 console.log(a); 答案 10

执行 console.log(a); 因为在外面是全局的,答案 100

执行 console.log(a); 答案 123


在这里插入图片描述

//1 false+1 因为有+,两边都不是字符串,就转换成数字,false 是 0 

//false false==1,false 肯定不等于 1,所以把 false 再赋给 demo

//undefined 

typeof(a) 出现”undefined” -true 转换成数字是-1 +undefined 显示“NaN-1 + NaN = NaN

-1 + NaN + “” =NaN” “undefined” &&NaN”转换成 boolean,就都是 true11* 2*把两边转换成了数字,所以 11 +11* 2 =3333 == 33,两边相等

!!非非就是正

“ ”这不是空串,是空格字符串

!!” ”转换成 Boolean 为 true

!!””非非空串,转换为 Boolean 为 false

!!false 就是 false

true + false - false = 1 + 00 =1

11|| document.write(‘你觉得能打印?’)

||遇到真就听,1 为真,所以返回 1
(window.foo || (window.foo = ‘bar’));
求 window.foo
答案”bar”

这道题要先看(window.foo = ‘bar’)这一边的,再看左边的 window.foo,因为运算符的顺序;但是这道题错误的读法(从左到右)也是 bar

(window.foo || window.foo = ‘bar’);这么写就报错;||或运算符优先级高于=等号
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值