javaScript复习(八)对象、闭包

Function对象

Function对象:一切(引用类型)都是对象,对象是属性的集合

undefined, number, string, boolean属于简单的值类型,不是对象。剩下的一切都是对象,包括函数、数组、对象、null、new Number(10)都是对象。他们都是引用类型。

判断一个变量是不是对象非常简单。值类型的类型判断用typeof,引用类型的类型判断用instanceof。

 

1、arguments对象:

重载概念:程序中可定义多个相同函数名,不同参数列表的函数调用者不必区分每个函数的参数,在执行时,程序根据传入的参数个数,自动判断选择哪个函数执行。

js语法不支持重载!但可用arguments对象模拟重载效果*

     arguments对象:函数对象内,自动创建的专门接收所有参数值得类数组对象。

     arguments[i]: 获得传入的下标为i的参数值

     arguments.length: 获得传入的参数个数!

    即使定义了参数变量,arguments对象同样会收到所有参数值

③例:function a(){

         if(arguments.length==1){

          //如果传入一个参数,求平方

 alert(arguments[0]*arguments[0]);

}else if(arguments.length==2){

 //如果传入两个参数,求和

alert(arguments[0]+arguments[1])

}}a(3);a(5,5);    //输出:9    10

 

2函数对象

        创建函数对象时:同时创建2个对象:

             函数对象:函数的定义

   作用域链对象:保存了函数对象可用变量的位置的对象(栈)

                 默认第一项指向window对象

        调用函数时:又会创建1个新对象:

             活动对象:专门保存局部变量的对象

             在作用域链对象中追加指向活动对象的引用

        调用后:作用域链中活动对象的引用出栈

                活动对象因无人引用而释放

                

   3匿名函数:定义时,不指定函数名的函数

      何时使用:2大用途:

       匿名函数自调:定义完,立刻执行

                       执行完立刻释放

         何时使用:只有确定函数只执行一次时!

         如何自调:(function(参数){

函数体

   })(参数值);

         自调:定义在哪儿,就在哪儿执行,不提前

       匿名函数回调:将函数作为对象传递给另一个函数

                       由另一个函数自主决定在需要时调用

        何时使用:只要将一个函数对象传递给其他方法调用时

        如何回调:直接将匿名函数的声明传入另一个函数中。

 

   4闭包:

      问题:全局变量和局部变量的缺陷

全局变量:容易全局污染

局部变量:无法共享,不能长久保存

闭包好处:即反复使用局部变量,又避免全局污染 就要用闭包

 

     解决:3步:闭包三特点:

      定义外层函数,封装被保护的局部变量

      定义内层函数,执行对外层函数局部变量的操作

      外层函数返回内层函数的对象并且外层函数被调用,结果被保存在全局变量中

     

标准的闭包写法

function outer(){           //定义外层函数

var n=1;             //封装被保存的局部变量

function inner(){     //定义内层函数

return n++;}      //执行对外层函数局部变量的操作

return inner;         //外层函数返回内层函数的对象

}

var getNum=outer();      //外层函数被调用

getNum();             

 

例:

function add() {         //定义外层函数

  var x = 1;             //封装被保存的局部变量

  return function() {    //外层函数返回内层函数的对象,定义内层函数,两步一起写

    console.log(++x);  //执行对外层函数局部变量的操作

  };

}

var num1 = add();        //外层函数返回内层函数的对象

var num2 = add();     //外层函数返回内层函数的对象

num1(); //输出2, 

num1(); //输出3,

num2(); //输出2,

 

例:下面这段代码想要循环延时输出结果 0 1 2 3 4,请问输出结果是否正确,如果不正确请说明为什么,并修改循环内的代码使其输出正确结果

for (var i = 0; i < 5; ++i) {

     setTimeout(function() {

      console.log(i + " ");

  }, 100);

}

原因: js 运行环境为单线程,setTimeout 注册的函数需要等到线程空闲时才能执行,此时 for 循环已经结束,i 值为 5,又因为循环中 setTimeout 接受的参数函数通过闭包访问变量 i,所以 5 个定时输出都是 5。

 

修改方法:将 setTimeout 放在立即执行函数中,将 i 值作为参数传递给包裹函数,创建新闭包。就会保护每个不同的i值

 

for (var i = 0; i < 5; ++i) {

   (function(i) {                   //定义外层函数

    setTimeout(function() {  //定义内层函数,并且参数i就是需要被保存的局部变量

      console.log(i + " ");      //对外层局部变量进行操作

    }, 100);  //setTimeout()本身就是回调函数,相当于外层函数返回内层函数的对象

  })(i);       //立即执行函数,属于自己调用自己,就是外层函数被调用

}

输出结果为: 0 1 2 3 4

 

5、 面向对象:在程序中都是用一个对象来描述现实中一个具体的东西。

          现实中的一个东西都包含属性和功能:

             属性:描述一个东西特点的变量,一个值

             功能:东西可以执行的操作

      什么是对象:封装多个数据和方法的存储空间

      什么是自定义对象:封装现实中一个东西的属性和功能的存储空间。

现实中东西的属性会成为对象中的属性变量。

现实中东西的功能,会成为对象中的方法(函数)

6、 创建对象

①对象直接量

      var obj={"属性名":值,

             ...  :  ...,

               "方法名" : function(){ ...this.属性名... }

               }

  ② var obj=new Object(); //创建一个空对象

      obj.属性名=值;

      obj.方法名=function(){...this.属性名...}

 

  ③ 利用构造函数*反复*创建*相同结构*的对象共2步:

      构造函数:描述一类对象结构的特殊函数

    第一步: 定义构造函数

  function 构造函数名|类型名(属性参数1,.....){

             this.属性名=属性参数1;

             //在当前正在创建的对象中添加一个属性名

         //赋值为属性参数1的值

             ...

             this.方法名=function(){

                  ...this.属性名...

             }

        }

      第二步: 利用构造函数创建对象:

        var obj=new 构造函数名|类型名(属性值1,...);

  7、访问对象的属性与方法

   属性:如何访问属性:2种:obj.属性名  obj["属性名"]

      访问对象中不存在的属性(访问数组中不存在的下标): 不会出错,返回undefined

      强行给不存在属性赋值,不报错!js会自动创建同名属性

 

      如何判断某个对象是否包含指定成员:3种

      ①obj.hasOwnProperty("成员名")

      ② "属性名" in 对象

如果找到,返回true,否则返回false!

      ③ 直接使用obj.属性名作为条件:

 arr.indexOf!==undefined      

        如果不包含,返回undefind-->false

        如果包含,返回值或function-->true

        何时省略:判断方法是否存在时,可省略!==

                  如果确定属性值一定不是null,0,"",NaN

                  也可省略

 

方法:如何在方法中,访问当前对象自己:

        this关键字:运行时,指代正在*调用*方法的对象

                                 (.前的对象)

        this本质是window下唯一的一个指针,指向当前正在调用方法的对象      

在方法内访问当前对象自己的属性,必须用this.属性名

        this和定义在哪儿无关!仅和调用时使用的当前对象有关

        如果无主的调用或赋值,默认this都是window!

改变this的指向有call()、apple()和 bind(),想详细了解请看我转载的另一篇文章

 

8、JavaScript原型与原型链

知识较多较杂,梳理不清楚,推荐大家看我转载的一篇文章《详解JavaScript原型链》

这里面说的提别清楚

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/shilipeng666/article/details/84199658
今日推荐