console.log(a)
var a=12;
funcyion fn(){
console.log(a)
var a=13;
}
fn()
console.log(a)
//undefined undefined 12
console.log(a)
var a=12;
function fn(){
console.log(a)
a=13;
}
fn()
console.log(a)
//undefined 12 13
console.log(a) //直接报错 a is not difined
a=12;
function fn(){
console.log(a)
a=13;
}
fn()
console.log(a)
//全局作用域 变量提升 var foo;var bar=AAAFFF111
//foo=1
//bar() 形参赋值 无
//变量提升 不管条件是否成立都要进行变量提升 var foo 私有的
// if(!foo) foo是私有的 私有的foo=undefined !foo =true 条件成立
//foo=10
//=>foo:10
var foo=1;
function bar(){
if(!foo){
var foo=10;
}
console.log(foo) //10
}
bar()
//全局作用域变量提升 var foo;
var foo='hello'; //foo='hello'
(function(foo){
//=>私有作用域
//形参赋值 foo = 'hello' foo为私有变量
console.log(foo); //'hello'
var foo=foo || 'world';
//因为已经存在私有变量foo 所以不再var不再变量提升
//'hello' || 'world' => 'hello'
console.log(foo) // 'hello'
})(foo) //=>把全局下foo的值当做实参传递给私有作用域中的形参
console.log(foo) //'hello'
//全局作用域 变量提升 var a;var fn=AAAFFF111;
//a=9
//fn()形成不销毁作用域A 形参赋值 变量提升 d都没有
//a=0 全局a=0
//return 函数 BBBFFF111
//f=fn() = BBBFFF111 ;
//F(5) 形参赋值 b=5 ;变量提升 无
//5+a++ a是全局的 =》log:5 全局a=1 销毁
//fn()(5)
//fn() 形成不销毁作用域B(临时不销毁当BBBFFF222(5)执行完后销毁) 形参赋值 变量提升 d都没有
//a=0 全局a=0
//return 函数 BBBFFF222
//BBBFFF222(5) 形参赋值 b=5 ;变量提升 无
//5+a++ =》log:5 全局a=1 销毁
//f(5) 形成私有作用域
//形参赋值 b=5 ;变量提升 无
//5+a++ //此时全局a=1
//=> log:6 ;全局a=2 销毁
//全局a=2
var a=9;
function fn(){
a=0;
return function(b){
return b+a++;
}
}
var f=fn();
console.log(f(5)) //5
console.log(fn()(5)) //5
console.log(f(5)) //6
console.log(a) //2
引用数据类型作为参数传递进入函数
传递进去的是堆内存空间地址,如果形参并未重新指向新的堆内存空间地址,则操作的就是原来的数据
私有变量和全局变量没有直接的关系,但是可能存在间接的关系
私有变量和全局变量都是引用数据类型的值,而且指向的是相同的堆内存空间
//全局作用域
//变量提升 var ary;var res; var fn=AAAFFF111(1、开空间;2、存东西3、赋值)
//ary(一个数组是一个对象)= AAAFFF222(1、开空间;2、存东西3、赋值)
//fn(ary) => 把全局ary存储的值当做实参传递给fn的形参:fn(AAAFFF222)
//形参赋值 ary=AAAFFF222 私有变量ary 和全局变量ary 共同指向了一个内存空间AAAFFF222 (引用数据类型操作 两个同时改变)
//变量提升 无
//ary[0]=0 AAAFFF222空间 内 索引1的值变为0 [0,2,3,4]
//ary=[0] BBBFFF111 //开辟新的内存空间 存东西 赋值
//这时候 私有变量ary(BBBFFF111) 与全局ary(AAAFFF222) 不再有关系
//ary[0]=100; BBBFFF111空间 内 索引1的值变为0 [100]
//return ary => return BBBFFF111
//res=fn(AAAFFF222) => res:BBBFFF111
var ary=[1,2,3,4];
function fn(ary){
ary[0]=0;
ary=[0];
ary[0]=100;
return ary;
}
var res=fn(ary)
console.log(ary) [0,2,3,4]
console.log(res) [100]
//全局作用域
//变量提升 var f; var fn=AAAFFF111(1、开空间;2、存东西3、赋值)
// fn(2) 开辟私有作用域A A是不销毁的
//形参赋值 i=2 A私有 //变量提升没有
//return 函数 开辟新的内存空间 BBBFFF111
//f=BBBFFF111
//f(3) BBBFFF111(3) 开辟私有作用域B
//形参赋值 B私有n=3 ; 变量提升 无
//n + (--i) 3+(--A.i) =>3+1 =4
//fn(4) 开辟私有作用域C 临时不销毁 BBBFFF222(5)执行完后销毁
//形参赋值 i=4 C私有的
//return 函数 开辟新的内存空间 BBBFFF222
//BBBFFF222(5) 开辟私有作用域D
//形参赋值 B私有n=5 ; 变量提升 无
//n + (--i) 5+(--A.i) =>5+3 =8
//f(8) =>BBBFFF111(8) 开辟私有作用域E
//形参赋值 E私有n=8 ; 变量提升 无
//n + (--i) 3+(--A.i) =>8+0 =8
function fn(i){
return function(n){
console.log(n + (--i))
}
}
var f=fn(2);
f(3); //4
fn(4)(5); //8
fn(6)(7); //12
f(8); //8
//全局作用域
//变量提升 var num; var obj;var fn;
//num=10 obj=AAAFFF111(1、开空间;2、存东西3、赋值)
//obj.fn= XXX 给obj加一项 就是给AAAFFF111加属性fn属性值是 自执行函数返回的结果,
//自执行函数执行
//开辟私有作用域A 不销毁
//形参赋值 A.num = 20 变量提升没有
//代码执行
//this.num=num*3;自执行函数执行 this为window num为A.num 全局num=20*3=60
//num++ A.num=21
//return 函数 开辟新的内存空间 BBBFFF111
//fn=obj.fn; fn=BBBFFF111;
//fn(5)
//开辟私有作用域B 销毁
//形参赋值 n=5 ; 变量提升 没有
// this.num+=n; this为window 全局 num=65
//num++ num不是私有的找到的是A.num A.num=22
//输出 22
//obj.fn(10);
//开辟私有作用域C 销毁
//形参赋值 n=10 ; 变量提升 没有
// this.num+=n; this为obj obj.num=30
//num++ num不是私有的找到的是A.num A.num=23
//输出 23
//console.log(num,obj.num) 65 30
var num =10;
var obj={
num:20
}
obj.fn=(function(num){
this.num=num*3; //this.num找到this的num num*3通过作用域链找到num再*3
num++;
return function(n){
this.num+=n;
num++;
console.log(num)
}
})(obj.num)
var fn=obj.fn;
fn(5); //22
obj.fn(10); //23
console.log(num,obj.num) //65 30
//Fn AAAFFF111 默认带有 prototype;
//浏览器默认为Fn.prototype 开辟堆内存 AAAFFF222 prototype默认带有 constructor:Fn
//prototype是对象数据类型 默认带有 \__proto__ 指向Object.prototype
//Fn.prototype= AAAFFF333 (1、开空间;2、存东西3、赋值) 存储公有属性
//也是对象 默认带有 \__proto__ 指向Object.prototype
//Fn.prototype不再指向AAAFFF222 而是指向AAAFFF333
//var f1=new Fn;
//开辟一个私有作用域
//f1.x=100; f1.y=200; f1.getX=AAAFFF444 都是私有属性
//f1是Fn的一个实例是一个对象 自带\__proto__ 指向Fn.prototype
//var f2=new Fn;
//开辟一个私有作用域
//f2.x=100; f2.y=200; f2.getX=AAAFFF444 都是私有属性
//f2 是Fn的一个实例是一个对象 自带\__proto__ 指向Fn.prototype
function Fn(){
this.x=100;
this.y=200;
this.getX=function(){
console.log(this.x)
}
}
Fn.prototype={
y:400,
getX : function(){
console.log(this.x);
},
getY : function(){
console.log(this.y);
},
sum:function(){
console.log(this.x + this.y);
}
}
var f1=new Fn;
var f2=new Fn;
console.log(f1.getX === f2.getX) //false
console.log(f1.getY === f2.getY) //true
console.log(f1.__proto__.getY === Fn.prototype.getY) //true
console.log(f1.__proto__.getX === f2.getX) //false
console.log(f1.getX == Fn.prototype.getX) //false
console.log(f1.constructor) //Object
console.log(Fn.prototype.__proto__.constructor) //Object(Fn.prototype={}是 改变公有方法指向,`如果不用constructor=Fn实例.__proto__不能找到Fn.prototype;实例.constructor就是Object`)
f1.getX() //this:f1 100
f1.__proto__.getX() //this:f1.__proto__(Fn.prototype) undefined
f2.getY() //this:f2 私有没有找到公有getY 但是this就是f2 200
Fn.prototype.getY() //this:(Fn.prototype 400
f1.sum(); //this:f1 f1.X+f1.Y=300
Fn.prototype.sum(); //this:Fn.prototype Fn.prototype.X+Fn.prototype.y=undefined+400=NaN