js总结(二)

********************************************************************

总结过一次,再总结一下,思路会清晰很多。

一、闭包

内部方法使用外部方法的变量(下面图很好的展示对应关系)

两个方法指向的变量是同一个,外部的方法销毁,但却把内部方法返回(变量一直存在)

作用域

Activation Object (上下文环境作用域,简称AO)

Global Object (全局作用域,简称GO)

举个闭包的例子:

function add(){
    var i=0;
    function x(){
        i++;
    }
    return x;
}

条件:基本方法包含一个到多个内部方法;最后把内部方法return出来 

立即执行函数,只执行一次(立即执行---())

(function(){

 }())

(function(){

})()

例题

var x=1;
if(function f(){}){
    x+= typeof f;
}
console.log(x);

打印结果?


知识点:
if()中会自动转变成语句,而function f(){}则是未声明的语句 是undefined
typeof会返回字符串类型
所以结果是:1undefined

面试题一

function test(){
    var x=[]
    for(var i=0;i<10;i++){
        x[i]=function(){
            console.log(i);
        }
    
    }
    return x;
}

test();

本意:想打印从0~9 10个数,但结果却不是。匿名函数中并没有定义i。所以他是找不到i这个变量的,需要到外部函数找i,等到找到i的时候,循环结束。返回的是最终的结果

解决方案
function test(){
    var x=[]
    for(var i=0;i<10;i++){
        x[i]=(function(j){
            console.log(j);
        })(i)
    
    }
    return x;
}

test();
加入()立即执行(function(j){return j})(i)  i--实参 j--形参

面试题二


  抛出问题:
    此题的目的是想每次点击对应目标时弹出对应的数字下标 0~4,但实际是无论点击哪个目标都会弹出数字5
  问题所在:
    arr 中的每一项的 onclick 均为一个函数实例(Function 对象),这个函数实例也产生了一个闭包域,这
    个闭包域引用了外部闭包域的变量,其 function scope 的 closure 对象有个名为 i 的引用,外部闭包
    域的私有变量内容发生变化,内部闭包域得到的值自然会发生改变
      
       function onMyLoad(){
            var arr = document.getElementsByTagName("p");
            for(var i = 0; i < arr.length;i++){
                arr[i].onclick = function(){
                    alert(i);
                }
            }
        }

  <body onload="onMyLoad()">
    <p>产品一</p>
    <p>产品二</p>
    <p>产品三</p>
    <p>产品四</p>
    <p>产品五</p>
  </body>


解决
     function onMyLoad(){
         var arr = document.getElementsByTagName("p");
         for(var i = 0; i < arr.length;i++){
            (function(args){
              arr[i].onclick = function(){
                  alert(args);
              }
            })(i)

        }
     }

     function onMyLoad(){
         var arr = document.getElementsByTagName("p");
         for(var i = 0; i < arr.length;i++){
              arr[i].onclick = (function(args){
                    return function(){
                        alert(args);
                    }                 
              })(i)

        }
     }

可以试一下 

二、预编译

预编译引申出两个概念AO(局部变量)和GO(全局变量)

函数声明整体提升
变量 声明提升

预编译前奏

1.暗示全局变量:即任何变量 如未经声明,则变为全局对象
2.一切声明的全局变量,都是window的属性

预编译的四步

1.将var x;提出来  并赋予undefined
2.将实参赋予
3.将 function y(){}提出来 赋予undefined
4.编译

 环境的话 先执行GO,再执行AO,在AO找不到就会扩大作用域到GO去找

 三、运算符

1/0 --->infinity正无穷
NAN --->not a number

优先级
‘=’最弱,‘()’最强

四、作用域

每一个函数就是一个对象,对象中有些属性是可以访问的,有些则是不可以访问的。

[[scope]]就是其中一个,其是--作用域

同一个对象的AO都是独一无二的,用完即销毁。但[[scope]]却存了执行上下文的集合(作用域链)。

在查找作用域链的时候 从 顶端从下开始查找
例: var a=123;
     function test(){
         var a=234;
         console.log('a')
     }
     test()
此时打印出来的就是234,那么为什么不是123,这里就涉及到一个作用域链的问题。

五、原型

原型是对象的一个属性,他是对象共有的属性,通过该原型产生的对象会继承该属性或方法。原型也是对象。

隐式对象:__proto__

添加属性名字:prototype

    例如:xx.prototype.name='lina' 就给xx对象添加了一个隐式的name属性。他是共有的

  原型链

在对象中,有隐式变量。如果父对象中的子对象有隐式变量。可以访问到子对象的隐式变量。这样就形成了原型链。
    但最后的终点是Object.访问Object的原型是null.

 

 

 

 

 

 

 

 

 

 

 

 

 

************************持续更新**********************************

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值