zoukankan      html  css  js  c++  java
  • javascript引用类型

    对象的创立:
    1.new构造法 var person = new object(); person.name = "qi";
    2.对象字面量(首选) var person={name:"qi",age:22} //也可以 "name":"qi" 这里的name会自动转换为字符串
    或者 var person={}; //等同于构造

    .表示法与[]表示法
    person.name person["name"] 除非必须使用变量访问,否则通常使用.来访问属性

    Array类型
    ECMAScrip的数组与其他语言不同,其可以动态的改变长度,并且每个数组元素所存放的数据类型也可以互不相同
    数组的创建:
    var arr = new Array();
    var arr = new Array(20);
    var arr = new Array('red','green','blue');
    也可以省略new
    var arr = Array('red','green','blue');
    当参数传入数值时,则会构建指定项数的数组
    当传入的是非数值时,则会创建只包含这个值的的一项数组

    数组字面量法,该方法不会调用构造函数 (最好是复数)
    var colors = ["red","green","blue"];
    var names = [];
    使用索引来访问数组
    注意:
    1.数组长度是可以变化的,允许在赋值时增加数组的长度
    colors[3] = "brown"; //新增第四项
    2.数组长度length不是只读的,可以通过设置length来设定数组的长度(移除或者新增)
    colors.length=2; //该colors[2] = undefined
    或者 colors.length = 4; //多出来的项都是 undefined
    或者 colors[colors.length] = "block"; //在末尾新增一项

    Array.isArray(value) //检测是不是数组
    转换方法:
    所有对象都会有 toLocaleString()、toString()和valueOf()方法。
    具体转换如下(生成以,分割的字符串)
    alert(colors.toString()); //red,green,blue,会调用每一项的toString方法
    alert(colors.valueOf()); //red,green,blue 本身就返回一个数组
    alert(colors); //red,green,blue

    colors.toLocaleString(); 会调用每一项的toLocaleString() 方法。

     1 var person1 = {
     2     toLocaleString:function(){
     3         return "zhd"
     4     }
     5     toString:function(){
     6         return "qi";
     7     }
     8 }
     9 var person2 = {
    10     toLocaleString:function(){
    11         return "zhd2"
    12     }
    13     toString:function(){
    14         return "qi2";
    15     }
    16 }
    17 var people = [person1,person2];
    18 alert(people.toString());            //qi,qi2
    19 alert(people.toLocaleString());   //zhd,zhd2

    join()方法, 默认会使用,进行隔开,join可以指定以某种分隔符分隔开
    alert(colors.join("||")); // red||green||blue

    使用数组模仿栈的特性
    栈:线性数据结构,只在栈顶进行数据的进栈出栈操作,先进后出
    var colors = new Array();
    colors.push("red","green"); //推出两项

    var items = colors.pop(); // 取栈顶元素。而后出栈,对于传统语言来讲,
    //数据出栈后,长度减1,javascript会自动将长度减少
    //,同理,进栈也是
    队列:1.在尾部插入push元素,在顶部移除shift元素,与栈部分基本相同
    2.使用unshift(在末尾移除)与pop(在顶部插入元素)组合,
    可以将队列反过来处理
    数组排序:
    默认的数组排序在对字符串排序时,容易出现混乱。例如:在升序排序中,
    它会把"10"排在"5"的前面,因为 1 < 5,因此,必要时需要指定一个排序规则
    例:

     1 var arr = [0,3,5,10,9];
     2 alert(arr.sort()); //错乱的输出 0,10,3,5,9
     3 function compare(value1,value2){
     4   if (value1 > value2) {
     5     return -1;
     6   } else if(value1 <value2){
     7     return 1;
     8   }else{
     9     return 0;
    10   }  
    11 }
    12 alert(arr.sort(compare)); //正确的排序:0,3,5,9,10

    在chrome v8引擎中,sort底层实现中,有一个参数可以指定需要调用的回调函数,
    可以在该函数中指明规则,v8给出了两种底层排序 InsertionSort 和 QuickSort
    源码地址:https://github.com/v8/v8/blob/master/src/js/array.js#L726
    不同的js引擎,具体的sort算法也不会相同

    数组的反转函数 reverse();

    数组的"拼接":concat
    在使用concat方法中,它会将原来的数组进行复制,并将concat中的参数拼接在数组
    的后面。如果参数为数组,那么就会将参数数组的每一项“拼接”上数组上,如果参数
    不是数组,那么就会简单的添加到数组的末尾
    注意:原数组不变,拼接的只是一个复制出来的新数组
    var colors = ["red","green","blue"];
    var colors2 = colors.concat("yellow",["black","brown"]);

    alert(colors); //red,green,blue
    alert(colors2); //red,green,blue,yellow,brown

    数组的截取:1.slice(start,end) 该方法可以在原有基础的数组上,截取一部分成为一个新数组
    slice只有一个参数时:截取从当前位置到数组末尾的所有项
    两个参数时,截取从第一个参数位置,
    到第二个参数位置(不包括结束位置的项)的所有项
    参数可以为负数,为负数时,基本等于从数组的末尾向前数参数所表示的位置
    既:若数组有5项,slice(-2,-1)与slice(3,4)时一样的

    2.splice方法的使用:删除 插入 替换
    splice (start, deleteCount, [item1[, item2[, . . . [,itemN]]]])
    删除:只有前两个参数时,数组从 start下标开始,删除deleteCount 个元素
    当参数只有start参数时,就是删除 从start下标起至最后 的元素
    插入:当deleteCount 均为0 的时候,在数组的start位置插入新的item元素。
    替换:当deleteCount 不均为0 的时候,在数组的start位置开始,删除deleteCount 个元素,
    在从start位置插入新的item元素。

    当参数 为负的时 则该参数规定的是从数组元素的尾部开始算起的位置 (-1 指的是 数组中倒数第一个元素, -2 指的是,数组中倒数第二个元素。)

    splice(0,2); //原数组删除数组的前两项,返回前两项
    splice(2,0,"red")//原数组在第二项位置上添加新项red,返回0,没有删除将返回空数组
    splice(2,1,"red")//原数组将第2项后面的1项替换为red,返回被替换的数据组成的数组

    splice操作的原始数组,对原始数组进行splice将会改变原始数组的长度以及数据变化,相应的
    splice方法返回的是被操作的数据组成的数组。

    位置方法 indexOf()和lastIndexOf()
    两个参数:搜索项与查找起点的索引位置(可选)
    返回搜索项的索引位置(未搜索到返回-1)
    迭代方法:5个,每个迭代方法都已传入一个方法(一套规则),使得数组中的每一项都执行一边,返
    回数组每一项执行方法后的逻辑值;
    暂时省略 原书98页
    缩小方法:缩小范围 省略 原书98页

    Date类型: var now = new Date();如果有参数,要根据参数创建对象,则参数只接受毫秒值
    Date.parse() 将日期字符串转化为毫秒,可以省略不写,系统默认调用
    Date.UTC();将日期字符串转化为毫秒,例子:
    //GMT 2000年1月1日 3时 0 分0秒0毫秒 (年月必须提供参数,其他默认为0,月从0开始)
    var d = new Date(Data.UTC(2000,0,3,0));

    如果构造函数第一个参数为数值,构造函数也可以这么写
    var d = new Date(2000,0,3,0);

    Date.now(); 返回调用这个方法的日期和时间的毫秒数
    var start = Date.now();
    doSomething();
    var stop = Date.new();
    return stop - start;

    在不支持Date.new方法的浏览器中,可以使用“+”转化为字符串也可以实现同样的效果
    var start = +Date.now();
    doSomething();
    var stop = +Date.new();
    return stop - start;

    日期可以直接比较大小,会默认比较毫秒数
    日期的若干getter/setter(可获取/设置毫秒,年,月,日....) 原书102页

    正则表达式:原书103页

    function函数:实际上也是对象,每个函数都是function的实例,每个函数名实际上也是指向函数对象的指针
    function sum(num1,num2){return num1+num2;};

    var sum = function(num1,num2){return num1+num2;};
    等价,调用时直接使用sum即可

    由于函数名是一个指向函数对象的指针,因此一个函数可能会有很多函数名
    var autosum = sum; //不带(),是指函数指针而不是指这个函数对象
    alert(autosum(10,10)); //20,即使将sum = null,autosum同样起作用

    没有重载!!!因为没有具体的方法签名,而实际上,第二次声明的函数会被看作第一次函数
    声明的引用
    函数声明与函数表达式:函数声明即 function sum(){} 会被提前加载到执行环境中
    而 var sum = function(){};则不会提前加载,在使用sum时,应该在该表达式的后面使用,否则会
    出现 unexpecter identifier(意外的标识符)错误

    作为值传递:函数名称也可以作为值传递,因为本身就是一个变量。
    即可以吧一个函数作为参数传递,也可以把函数的返回结果作为参数传递

    1 function callSomeFunction(SomeFunction,SomeArgument){
    2     return SomeFunction(SomeArgument);//传入的函数可以在函数体里面执行
    3 }//要访问函数的指针而不执行函数的话,就必须去掉函数的"()"

    //同时也可以把一个函数写在另一个函数里面 例子

    function createComparisonFunction(propertyName){
        return function(object1,object2){
            var value1 = object1[propertyName];
            var value1 = object2[propertyName];
    
            if(value1 < value2){
                return -1;
            }else if(value1 > value2){
                return 1;
            }else{
                return 0;
            }
        }; //不要忘了这个分号  作为return一条语句看待
    }
    var data = [{"Name":"zhd"},{"Name":"qi"}];
    data.sort(createComparisonFunction("Name"));
    alert(data[0].Name);  //zhd

    函数内部属性:两个特殊对象 this,arguments
    arguments包含所有传入函数的参数,其中还有一个 callee的属性,这是一个指针,指向拥有
    这个arguments的函数。 目的:可以实现函数与代码的解耦和关系
    阶乘例子解析:

    function factorial(num){
        if(num < 1){
            return num;
        }else{
            //return num * factorial(num-1)  //第一种写法
            return num * arguments.callee(num-1)  //第二种写法
        }
    }
    //注意
    var trueFactorial = factorial;//trueFactorial与factorial指向同一个function对象
    factorial = function{
        return 0;    //factorial指向的函数被更改,那么在阶乘原阶乘函数里,如果使用
                    //第一种写法,那么在调用trueFactorial时,它将不会返回正确的结果
                    //因为在函数体阶乘递归计算时调用了被更改的factorial而返回结果0
    }
    alert(trueFactorial(5)); //返回120  第一种写法  返回 0

    this:引用函数据以执行的环境对象 谁引用的,指向谁,如果没有任何对象引用该函数(
    即在全局环境中)那么它会指向window对象

    caller:保留调用当前函数的函数的引用,不能为该属性赋值,如果是全局环境,则为null

    1 function outer(){
    2     inner();
    3 }
    4 funcion inner(){
    5     alert(inner.caller);
    6     alert(arguments.callee.caller); //解耦合
    7 }
    8 outer(); //返回outer的源码,因为inner.caller指向了outer函数

    函数的属性与方法: 记住::::函数是对象!!!
    每个函数都包含两个属性 length(函数的参数个数)和prototype(第六章细讲)
    包含两个非继承而来的方法 apply()和call(),都用在特殊特定作用域中调用函数,实际上等于
    设置函数体this的值

    apply() 接受两个参数,第一个参数其中运行函数的作用域,
    另一个参数是参数数组(可以是Array的实例,也可以是arguments对象)

     1 function sum(num1,num2){
     2     return num1+num2;
     3 }
     4 function callSum1(num1,num2){
     5     return sum.apply(this,arguments); //这个this指callSum1,指向最外面的函数    
     6 }
     7 function callSum2(num1,num2){
     8     return sum.apply(this,[num1,num2]);    
     9 }
    10 alert(callSum1(10,10)); // 20
    11 alert(callSum2(10,10)); // 

    关于this的指向 http://www.cnblogs.com/pssp/p/5216085.html
    call() 与apply作用相同,区别在于,第二个参数要一次列举出来

    1 functio callSum3(num1,num2){
    2   return sum.call(this,num1,num2);
    3 }



    !!!apply和call最强大的地方 是扩充了函数赖以生存的作用域!!!

     1 window.color = "red";
     2 var o = {color:"blue"};
     3 function sayColor(){
     4     alert(this.color);
     5 }
     6 sayColor.call(this); // red this在这里指window 在全局环境下执行
     7 sayColor.call(window); // red  同理
     8 sayColor.call(o); // blue  此时函数体内的this对象指向了o,实现了函数对象与o对象的解耦和
     9 
    10 // var o = {
    11 //     color:'blue';
    12 //     function sayColor(){
    13 //         alert(this.color);
    14 //     }
    15 // }
    16 //o.sayColor = sayColor;
    17 //o.sayColor();
    18 
    19 //或者:
    20 var o = {
    21     color:'blue',
    22     sayColor:function (){
    23         alert(this.color);
    24     }
    25  }
    26 o.sayColor();


    bind(); 将函数本身绑定在被传入的参数上
    var objectSayColor = sayColor.bind(o); //此时函数体内 this指向 参数 o
    objectSayColor(); // blue 即使在全局环境中运行,也会返回blue

    每个函数继承的toString(),toLocaleString(),valueOf 都会返回函数代码

      

  • 相关阅读:
    递推数列
    大数阶乘
    成绩排序
    DevC++ return 1 exit status
    POJ 1061 青蛙的约会
    ZOJ 2750 Idiomatic Phrases Game
    nyoj 545 Metric Matrice
    nyoj 308 Substring
    nyoj 515完全覆盖 II
    nyoj 1248 海岛争霸
  • 原文地址:https://www.cnblogs.com/luckyQi/p/7518593.html
Copyright © 2011-2022 走看看