JavaScripts高阶(8)前七章相关的面试题

199 阅读5分钟
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