首页 > 代码库 > JavaScript--对象+函数

JavaScript--对象+函数

1. 复杂数据类型 Object
 ECMAScript中的对象其实就是一组数据(属性)和功能(方法)的集合。
    1) 创建Object实例:
    1.使用构造函数创建,new Object()
       var person = new Object();
       person.name = "briup";
       person.age = 22;

    2.使用对象字面量表示法
       不同的属性之间用‘,‘分割,属性名和属性值之间用‘:‘分割
         var person = {
            name : "briup",
            age : 22
         };
    2) 访问对象属性
     1.点表示法,右侧必须是以属性名称命名的简单标识符
       person.name
     2.中括号表示法,中括号中必须是一个计算结果为字符串的表达式,可以通过变量访问属性,如果属性名中包含语法错误的字符,或者属性名使用的是关键字或保留字,可以使用中括号 person["first name"]
       var a = "name";
       person[a]; //既person["name"]
       person["first name"]
   
    3) 删除属性
     delete只是断开了属性和宿主对象的联系,而不会操作属性中的属性,并且delete只会删除自有属性,不能删除继承属性。在销毁对象时,为了防止内存泄露,遍历对象中的属性,依次删除所有属性。
     语法:delete 属性访问表达式
     例如:
       delete stu.name  //删除学生对象中的name属性
    4) 检测属性
    in 检测某属性是否是某对象的自有属性或者是继承属性,是就返回true,否则返回false
       "toString" in student
    hasOwnProperty()检测给定的属性是否是对象的自有属性,对于继承属性将返回false
       var o = {
          x:1
       }
       o.hasOwnProperty("x"); //true, x 为o的自有属性
       o.hasOwnProperty("y"); //false,o 中不存在属性y
       o.hasOwnProperty("toString"); //false,toString为继承属性
    propertyIsEnumerable() 检测给定的属性是否是该对象的自有属性,并且该属性是可枚举的通常由JS代码创建的属性都是可枚举的,但是可以使用特殊的方法改变可枚举性。
       student.propertyIsEnumerable("toString") //false 不可枚举
    5) Object属性及方法
       Object 类型所具有的任何属性和方法也同样存在于其他对象中,任何对象继承于Object对象
       Object中常用的方法:
       hasOwnProperty(propertyName); 
          检查给定的属性名是否是对象的自有属性,
       toString();  
          返回对象的字符串表示
       valueOf();  
          返回对象的字符串,数值,布尔值的表示。
       propertyIsEnumerable(propertyName); 
          检查给定的属性在当前对象实例中是否存在
       constructor:   
          保存用户创建当前对象的函数
       isPrototypeOf(object);  
          检查传入的对象是否是原型
       toLocaleString(); 
          返回对象的字符串表示,该字符串与执行环境的地区对应
  6) 对象序列化
    对象序列化是指将对象的状态转换为字符串,也可以反序列化,将字符串还原为对象函数,RegExp,Error对象,undefined值不能序列化和反序列化。
          JSON.stringify(obj)  
    将对象序列化为Json字符串,只能序列化对象可枚举的自有属性。
      JSON.parse(jsonStr)  
     反序列化

2. 函数

 0)声明提升:

  函数声明提升,所有的函数声明会提升至当前的作用域顶部

      //函数声明--->函数声明会提升

      function fnName(arg1,arg2){

        //function body

      }

      //函数表达式--->函数表达式并不会被提升

      var fnName=function(){

        //function body

      };

  变量声明提升

    alert("a" in window);

    var a;                      ===>var a;

                  alert(""a" in window);

    只有变量声明被提升而变量初始化不会提升(即变量直接赋值时在执行阶段创建)。

      var a=1;  ===>var a;

               a=1;

      alert(a); //undefined

      alert(b);//error

      b=10;

      var a=20;

    当变量声明并初始化,javascript会自动拆分变量声明和变量初始化

    为什么没有提升变量初始化?

      因为这样会影响变量值在代码执行期间导致不可预料的结果

  必须知道和理解函数声明会覆盖变量声明,但不会覆盖变量初始化

    function value(){

      return 1;

    }

    var value;

    alert(typeOf value); //function    (typeOf返回一个表示类型的字符串)

    //即使变量声明出现在函数声明之后,函数声明也会获得更高的优先权

    function value(){

      return 1;

    }

    var value=http://www.mamicode.com/1;

    alert(typeOf value); //Number  变量初始化覆盖了函数声明

    var a=1;                var a;

    function foo(){             function foo(){

      a=10;                  function a(){}

      function a(){}    ===>        a=10;

    }                    }

    foo();                  a=1;

    alert(a);                 foo();

                         alert(a); //1
 1) 作为值的函数
    由于函数名本身就是变量,所以函数可以当做值来使用(参数,返回值)。
    function callOther(fun,args){
       return fun(args);
    }
    function show(msg){
       alert(msg);
    }
    callOther(show,"哈哈"); //show为参数
2) 作为返回值的函数
        eg:多功能自定义排序函数
    function myCompare(pro){
     //函数将作为返回值返回
       return function(obj1,obj2){
          var val1 = obj1[pro];
          var val2 = obj2[pro];
          if(val1<val2){
             return -1;
          }else if(val1>val2){
             return 1;
          }else {
             return 0;
          }
       }
    }
    var data = http://www.mamicode.com/[
     {
        name : "aaa",
        age :12
     },{
        name:"ccc",
        age : 8
     },{
        name :"bbb",
        age : 71
     }
    ];
    console.log(data);
    data.sort(myCompare("age"));
    console.log(data);
 3) 函数内部属性
  1. arguments :是类数组对象,包含着传入函数中参数,arguments对象还有一个callee的属性,用来指向拥有这个arguments对象的函数
     //实现多个数值类型的相加
    var addAll = function(){
     console.log(arguments.callee == addAll);
     // arguments = [1,2,3,5];
     var total = 0;
     for(var key in arguments){
        //通过索引获取值,key索引 0,1,2,3
        var value = http://www.mamicode.com/arguments[key];
        total +=value;
     }
     return total;
   }
    var result = addAll(1,2,3,5,3,4);
    console.log("结果为:"+result);
   例如:
   num的阶乘,使用递归函数
   function factorial(num){
    if(num<=1){
     return 1;
    }else{
     //return num * factorial(num-1);
     return num * arguments.callee(num-1);
    }
   }
  2. this: 指向的是函数赖以执行的环境对象
      window.color = "window";
      var person = {
       color:"person"
      };

      function sayColor(){
       alert(this.color);
      }
      sayColor();  //window对象调用,所以弹出 "window"
      person.sayColor = sayColor; //将该方法赋给person对象
      person.sayColor();//使用person对象调用该方法,弹出"person"
 4) 函数的属性
        length: 表示函数希望接受的命名参数的个数
    function say(msg){} //say.length 1 希望接受一个参数
    function add(m,n){} //add.length 2 希望接受两个参数
        prototype: 保存实例方法的真正所在。在自定义引用数据类型以及继承时非常重要。
5) 函数的方法
    this->该函数所在的环境对象
    <script>
     var person = {
        name:"terry",
        add:function(){
     
        }
     }
     person.add();

     function add(a,b){
        alert(a+b);
     }
     add(1,2);// this->window
     =>
     add.call(window,1,2);
   </script>
  
    apply : 参数(在其中运行函数的作用域,参数数组(Array,arguments));
    call  : 参数(在其中运行函数的作用域,参数列表)
          这两个方法作用都是在特定的作用域中调用函数,实际上等于设置函数内部的this的值

    用法一:
     function sum(m,n){
        return m+n;
     }
     function call(m,n){
        //return sum.apply(this,arguments);
        return sum.call(this,m,n);
     }
     alert(call(1,2)); 
    用法二:
           扩充函数赖以运行的作用域
       window.color = "window";
       var person = {
       color:"person"
       };

       function sayColor(){
       alert(this.color);
       }
       sayColor.call(this);
       sayColor.call(window);
       sayColor.call(person);

3. 基本数据类型,引用数据类型
   基本数据类型的变量:
      可以直接操作保存在变量中的实际的值
      参数传递的时候传递的是实际值
   引用数据类型的变量:
      不能直接操作对象的内存空间,实际上是在操作对象的引用。
      可以为引用类型变量天极爱属性和方法,也可以改变和删除其属性和方法
      参数传递的时候传递的是引用地址。
   值传递
      值的拷贝
   引用传递
      引用地址的拷贝

    var a = 3;
      var p1 = {
        name:"larry",
        age:14,
        gender:"男",
     };
     function changeA(a){
       ++a;//4
     }
     function changeName(p){
       //b001
       p.name ="tom"
     }
     function changeP(p){
       //p = b001
       //p = b002
       p = {
          name:"jacky",
          age:14,
          gender:"男",
       }
    }
    console.log(p1);// b001  Object {name: "larry", age: 14, gender: "男"}
    changeName(p1); //b001
    //changeP(p1);
    console.log(p1);//b001  Object {name: "tom", age: 14, gender: "男"}

   console.log("before a:"+a); //3
    changeA(a);
    console.log("after a:"+a); //3

JavaScript--对象+函数