引用类型,Function等引用类型

作者: 网络应用  发布:2019-09-03

阅读目录

一、Array

Object类型

  1 、创建数组的方式

1、通过构造函数来创建
2、通过字面量表示法来创建对象

//Array构造函数(可以去掉new)
var colors0 = new Array();
var colors1 = new Array(20);
var colors3 = new Array("red","blue","green");

//数组字面量
var colors4 = ["red","blue","green"];
var colors5 = [];

Array类型

  可以根据元素的索引对数组元素进行访问,在数组末尾增加(或者删除)元素可以用colors.length,此种方式在末尾添加的元素自动获得undefined值。也可以用堆栈和队列的方式(见后文)。

同样Array也有两种创建方式:
如果我们想要打印数组中所有的值,直接打印数组的变量名就可以:
往数组添值:
栈方法、队列方法:
 关于数组的排序:
 数组的一些操作方法:
查找位置方法
迭代方法

2、数组常见方法

归并方法

     2.1、数组检测

Date类型

//检测某个对象是不是数组
if(value instanceof Array)
{
  //操作
}
//instanceof只在只有一个全局执行环境时才有效,对于多框架网页,此方法不适合
//ECMAScript5 新增isArray()方法,可以解决instanceof的问题

if(Array.isArray(value))
{
  //操作
}

RegExp类型

     2.2、转换方法:toString()、valueOf()、toLocaleString()

Function类型

var colors = ["red","blue","green"];
//均显示red,blue,green
alert(colors.toString());
alert(colors.valueOf());
alert(colors);

三种表示法:

  toString()返回由数组元素用逗号(,)拼接而成的字符串,valueOf返回的还是数组,alert(colors)会在后台调用toString()方法。toLocaleString()会调用数组每一项的toLocaleString()方法,而不是toString(),通常返回值和调用toString()和valueOf()相同,但是有例外。

方法重载
函数内部属性(arguments 和 this)

var person1 = 
{
    toLocaleString:function()
    {
        return "test1";
    },
    toString:function()
    {
        return "test2";
    }
};
var person2 = 
{
    toLocaleString:function()
    {
        return "dwqs";
    },
    toString:function()
    {
        return "ido321";
    }
};
var people = [person1,person2];
alert(people);                     //test2,ido321
alert(people.toString());          //test2,ido321
alert(people.toLocaleString());    //test1,dwqs

基本包装类型

    2.3、栈和队列方法:push()、pop()、shift()、unshift()

浏览器的内置对象
URI 编码方法

           栈是一种先进后出(LIFO)的数据结构。在栈中插入项称为推入,删除项称为弹出,两个动作均只发生在栈的顶部。在ECMAScript中,推入和弹出对应的方法是push()和pop(),分别在数组末尾添加和末尾删除数组元素。

总结

var colors = new Array();
var count = colors.push('red','green');   //推入两项,并返回修改后的数组长度
alert(count);  //2
count = colors.push("black");
alert(count);  //3
var item = colors.pop();
alert(item);  //black
alert(colors.length); //2

我们在《一步步学习javascript基础篇(1):基本概念》中简单的介绍了五种基本数据类型Undefined、Null、Boolean、Number和String。今天我们主要介绍下复杂数据类型(即引用数据类型)

          队列是先进先出(FIFO)的数据结构,push()在队列末端添加项,shift()在前端删除项,数组长度减1,并返回删除项。与shift()相反的是unshift(),其在前端添加项并返回新数组的长度。

Object类型

var colors = new Array();
var count = colors.push('red','green');   //推入两项,并返回修改后的数组长度
alert(count);  //2
count = colors.push("black");
alert(count);  //3
var item = colors.shift();
alert(item);  //black
alert(colors.length); //2

我们用的最多的引用类型就属object类型了,一般用来存储和传输数据是再好不过的。然,它的两种创建方式我们是否了解呢?

     2.4、数组排序:sort()和reverse()

1、通过构造函数来创建

           默认情况下,sort()会调用每一个数组元素的toString()方法,得到字符串,按照ASCII码的升序排序;reverse()则是反序排序。sort()和reverse()返回排序后的数组

如: var obj = new Object();

//reverse反序
var values1 = [1,2,3,4,5];
alert(values1.reverse());  //5,4,3,2,1
//sort排序
var values2 = [0,1,5,10,15];
alert(values2.sort());  //0,1,10,15,5

在js中的引用类型有个非常灵活的用法,可以动态的附加属性和赋值。

  得到10和5的字符串形式时,1的ASCII码是49,5的ASCII码是52,所以默认下,sort()会认为5>10。为按照自然顺序排序,sort()接受一个比较函数作为参数,根据返回值确定哪一个排前排后。

如:

function compare(value1, value2)
{
    if(value1 < value2)
    {
        return -1;
    }
    else if(value1 > value2)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
var values2 = [0,1,5,10,15];
alert(values2.sort(compare));  //0,1,5,10,15
var obj = new Object();
obj.name = "张三";//动态添加属性并赋值
obj.age = 23;
alert(obj.name);

     2.5、迭代方法:every()、filter()、forEach()、map()、some()

2、通过字面量表示法来创建对象

          上述的5个迭代方法均在ECMAScript 5中定义,每个方法均接收两个参数:数组每一项上运行的函数和运行该函数的作用域对象—影响this。传入方法中的函数均接收三个参数:数组项的值、该值 在数组中的位置和数组对象本身。此5个方法均不会修改数组中包含的值。(IE9+等现代主流浏览器均支持ECMAScript 5)

现在大家用得比较多的就是字面量表示法来创建对象了。

           every():对数组中的每一项运行给定的函数,若该函数对每一项都返回true,则返回true。

如:

           filter():对数组中的每一项运行给定的函数,返回该函数返回true的项组成的数组。

var obj = {
 name: "张三",
 age: 23
};
alert(obj.age);

           forEach():对数组中的每一项运行给定的函数,无返回值。

和上面的效果是等效的。通过这样方式创建感觉结构更加的清晰,更加有封装的感觉。:)

           map():对数组中的每一项运行给定的函数,返回每次函数调用的结果组成的数组。

我们还可以这样用

           some():对数组中的每一项运行给定的函数,若该函数对任一项返回true,则返回true。

如:

//every函数
var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item,index,array)
{
   return (item > 2);
});
alert(everyResult);  //false
//some函数
var someResult = numbers.some(function(item,index,array)
{
   return (item > 2);
});
alert(someResult);  //true
var obj = {};
obj.name = "张三";
obj.age = 23;
alert(obj.age);

     2.6、其它函数:concat()、slice()、splice()、indexOf()、lastIndexOf()、reduce()、reduceRight()

如:

var colors = ["red","green","blue"];
//concat():基于当前数组返回一个新的数组
var colors2 = colors.concat("yellow",["black","brown"]);
alert(colors);     //red,green,blue
alert(colors2);    //red,green,blue,yellow,black,brown

//slice():基于当前数组的一个或多个项创建一个新数组
var colors3 = colors2.slice(1);
var colors4 = colors2.slice(1,4);
alert(colors3);    //green,blue,yellow,black,brown
alert(colors4);    //green,blue,yellow(不包括位置4的元素)

//splice():对数组元素进行删除、插入和替换
//1、删除:指定两个参数,要删除的第一项的位置和删除的项数,返回从数组中删除的项
var removed = colors3.splice(1,2);
alert(colors3);  //green,black,brown
alert(removed);  //blue,yellow

//2、插入和替换:三个参数,起始位置、要删除的项数和插入的项
//若第二个参数是0,执行插入,返回空数组;不为0,则执行替换,返回删除的项组成的数组
var newcolors = ["red","green","blue"];
var removed2 = newcolors.splice(1,2,"yellow","orange");
alert(newcolors);    //red,yellow,orange
alert(removed2);  //green,blue
var obj = {
 "name": "张三",//给属性加上双引号
 age: 23
};
alert(obj.name);

 

是不是感觉很强大很灵活呢?我在访问属性的时候一般都是点出来,但是还有另外的方式。

  splice() 方法与 slice() 方法的作用是不同的,splice() 方法会直接对数组进行修改。slice不会。

如:(我们可以使用中括号的形式来访问属性值)

  reduce()和reduceRight()对数组执行归并,会迭代数组的所有项,返回迭代后的结果。前者从第一项开始迭代,后者从最后一项开始迭代。 二者接收两个参数:一个在每一项上调用的函数和(可选的)作为归并的初始值,函数接收四个参数:前一个值、当前值、项的索引和数组对象。

var obj = {
 "name tow": "张三",
 age: 23
};
//alert(obj.name tow);//这里会报错,属性不能有空格
alert(obj["name tow"]);//这里可以正常弹出
var values = [1,2,3,4,5];
var sum = values.reduce(function(prev,cur,index,array){
    return prev+cur;
});
alert(sum);  //15

例:

 

Array类型

二、Date

除了object之外,应该属数组用的最多了。下面来罗列下常见用法。

    ECMAScript中的Date类型是在Java的java.util.Date类基础上构建的,因此,Date类型使用自UTC 1970.1.1午夜零时开始经过的毫秒数来保存时间。

同样Array也有两种创建方式:

   1、创建日期对象

var arr = new Array(1, 2, 3, 4, 5);//通过构造函数创建
var arr2 = [5, 4, 3, 2, 1];//通过字面量表达式来创建 
//基于当前时间
var now0 = new Date();  
//基于指定的日期字符串
var now1 = new Date(Date.parse("May 25,2004")); 
//基于UTC时间创建
var now2 = new Date(Date.UTC(2014,11,16));

上面两种方式是等效的,我们可以直接通过下标的方式来访问数组: alert(arr[2]); 。

  也可以传一个毫秒数给Date创建对象,而Date.parse()和Date.UTC()也返回一个基于指定日期的毫秒数.。Date.parse() 基于GMT,传给Date.parse()的字符串不能解析为字符串则返回NaN;Date.UTC()的参数分别是年份、基于0的月份(0是1月份)、 月中的一天(1到31)、小时数(0到23)、分钟、秒和毫秒数,年份和月份是必须的参数,其他参数可选(也可将相同的参数传给Date的构造函数)。

如果我们想要打印数组中所有的值,直接打印数组的变量名就可以:

  ECMAScript 5新增了一个Date.now(),获取当前日期和时间,参见:。对于不支持此方法的浏览器,可以使用+操作符将Date对象转为字符串。

var arr2 = [5, 4, 3, 2, 1];//通过字面量表达式来创建
var str2 = "";
for (var i = 0; i < arr2.length; i++) {
 str2 += arr2[i] + ","
}
alert(str2);//打印拼接的字符串  
alert(arr2);//直接打印变量名(实际上会自动调用数组的toString方法)

  2、Date对象常见方法

例:

     getFullYear():取得四位数的年份

 var arr2 = [5, 4, 3, 2, 1];//通过字面量表达式来创建
var str2 = "";
for (var i = 0; i < arr2.length; i++) {
 str2 += arr2[i] + ","
}
alert(str2);//打印拼接的字符串

     getMonth():返回日期中的月份,0表示一月

例:

     getDate():返回日期中的天数(1到31)

 var arr2 = [5, 4, 3, 2, 1];//通过字面量表达式来创建
alert(arr2);//直接打印变量名(实际上会自动调用数组的toString方法)

     getDay():返回日期中星期的星期几(0是星期日,6是星期六)

上面直接打印arr2,我们发现默认都是以逗号分隔的。那么有时候,我们不想用逗号怎么办呢。那你可能可以用到join方法

     getHours():返回日期中的小时数(0~23)

 var arr2 = [5, 4, 3, 2, 1];//通过字面量表达式来创建
alert(arr2.join('_'));//直接打印变量名(实际上会自动调用数组的toString方法)

     getMinutes():返回日期中的分钟数(0~59)

往数组添值:

     getSeconds():返回日期中的秒数(0~59)

我们可以直接: arr2[4] = 7; arr2[5] = 8; 

     getMilliseconds():返回日期中的毫秒数

还有一种更加巧妙地添值方式: arr2[arr2.length] = 9; arr2[arr2.length] = 10; ,下标length刚好是数组最大长度的下一个,添加值后length再次动态自动累计。

     更多方法:

栈方法、队列方法:

 

什么是栈?(后进先出)。什么是队列?(先进先出),我们怎样用数组来模仿这种数据结构的访问方式?下面通过一张图来解释下数组对象提供的四个方法。

三、Function

图片 1

   1、概述

从图可以看出:shift和push、unshift和pop的组合可以实现栈的数据结构访问,shitf和pop、shift和unshift的组合可以实现队列的数据机构访问方式。 这里需要注意:pop和shift取数据的同时,数组中对于的值也同时移除了。

     在JavaScript中,Function是一种对象类型,所以每个函数都是Function的实例,而函数名则只是一个指向函数对象的指针,不会与某个函数绑定。

例:

//以下三种方式是等价的
function sum(num1,num2)
{
     return num1+num2;
}

var sum = function(num1,num2)
{
     return num1+num2;
}

var sum = new Function("num1","num2","return num1+num2");
 var arr2 = [5, 4, 3, 2, 1];
alert("arr2.pop:" + arr2.pop() + " arr2:" + arr2);

  第三种方式始终把第三个参数当作函数体,不推荐使用。第一种相对第二种,有函数声明提升的优势。因为函数名是一个指针,这对于理解JavaScript没有重载很有用处。

 关于数组的排序:

function add(num)
{
     return num+100;
}
function add(num)
{
    return num+200;
}
alert(add(100));  //300

关于数组的排序有sort(正)reverse(反)。

声明的两个同名函数,后者覆盖了前者.(可以把函数名当作特殊的变量处理,所以也可以用于参数和作为函数的返回值),所以,其等价代码:

先看个例子,大家猜想下结果:

var add = function(num)
{
     return num+100;
};

add = function(num)
{
    return num+200;
}
var arr2 = [5, 14, 23, 12, 1];
alert(arr2.sort());

 
2、属性和方法

 然结果并不是我们想要的:

   arguments:保存函数的参数,是一个数组对象,其拥有一个callee属性,是一个指针,指向拥有arguments对象的函数(一般就函数本身)

 var arr2 = [5, 14, 23, 12, 1];
alert(arr2.sort());

   this:函数的执行环境对象,一般指向本身,但可以用call()或者apply()改变this的指向。

 为什么会这样呢?因为sort不会直接比较数字类型,而已转为string了再做的比较。那么我们想要比较数字怎办?我们可以往sort传函数,例:

   caller:ECMAScript 5新增的属性,指向调用当前函数的函数的引用。若在全局调用当前函数,则其值是null。

 function mycompare(o1, o2)
{
 return o1 - o2;//如果为正数则o1大,负数则o2大,零则相等。
}
var arr2 = [5, 14, 23, 12, 1];
alert(arr2.sort(mycompare));
function outer()
{
     inner();
}

function inner()
{
     alert(arguments.callee.caller);  //返回outer函数的整个定义
}
outer();

 有人会问o1和o2是怎么来的?这是sort函数规定的。这样说大家可能不好接受。下面,我们自己来模拟下sort的排序,大家就明白了。

   prototype:指向对象的原型对象(在面向对象的笔记中会详细介绍)

var arr2 = [5, 14, 23, 12, 1, 123, 23, 4, 5, 6, 32, 5, 3, 2, 1];
arr2.mysort = function (fun) {
 //*********************具体排序过程*******************
 for (var i = 0; i < arr2.length - 1; i++) {
  for (var j = 0; j < arr2.length - i; j++) {
   if (fun(arr2[j], arr2[j + 1]) > 0) {//这里用我们传进来的方法判断是否要排序调换位置
    var temp = arr2[j];
    arr2[j] = arr2[j + 1];
    arr2[j + 1] = temp;
   }
  }
 }
 //***************************************************
 return arr2;
} 
function mycompare(o1, o2) {
 return o1 - o2;//回调函数(具体的比较规则)
}
alert(arr2.mysort(mycompare));

 var arr2 = [5, 14, 23, 12, 1, 123, 23, 4, 5, 6, 32, 5, 3, 2, 1];
arr2.mysort = function (fun) {
 //*********************具体排序过程*******************
 for (var i = 0; i < arr2.length - 1; i++) {
  for (var j = 0; j < arr2.length - i; j++) {
  if (fun(arr2[j], arr2[j + 1]) > 0) {//这里用我们传进来的方法判断是否要排序调换位置
   var temp = arr2[j];
   arr2[j] = arr2[j + 1];
   arr2[j + 1] = temp;
   }
  }
 }
 //***************************************************
 return arr2;
}
function mycompare(o1, o2) {
 return o1 - o2;//回调函数(具体的比较规则)
}
alert(arr2.mysort(mycompare));

   apply()和call():设置函数体中的this指向,二者区别是:apply()以数组形式将参数传递给函数,call()列举出全部参数再传给函数。

当然,我们模拟的并不是那么的好,大概就是这么个意思。

function sum(num1,num2)
{
     return num1+num2;
}
function applySum(num1,num2)
{
     return sum.apply(this,arguments); //return sum.apply(this,[num1,num2]); 
}
function callSum(num1,num2)
{
     return sum.call(this,num1,num2);
}
alert(applySum(10,10));  //20
alert(callSum(10,20));  //30

反序就简单了:(直接reverse()就可以了)

 

function mysort(o1, o2)
{
 return o1 - o2;//如果为正数则o1大,负数则o2大,零则相等。
}
var arr2 = [5, 14, 23, 12, 1];
arr2.sort(mysort);
arr2.reverse();
alert(arr2);

四、基本包装类型

数组的一些操作方法:
concat创建一个新的副本,并合并传进来的参数

    ECMAScript提供了3个特殊的引用类型:Boolean、Number和String(后续放在正则表达式一文中介绍),用于操作基本类型。当读取一个基本类型的值时,后台会创建一个对应的基本包装类型的对象,然后可以调用对应的方法来操作数据。

var colors = ["red", "green", "blue"];
var colors2 = colors.concat("yellow", ["black", "brown"]);
alert(colors); //red,green,blue
alert(colors2); //red,green,blue,yellow,black,brow
var s1 = "test string";
var s2 = s1.substring(4);
alert(s2);  //string

slice创建一个新的副本,取数组的位置数据

  s1是一个基本类型,本身没有定义任何的方法。但是,当读取到s1时,后台会创建一个String类型的实例,在实例上调用指定方法,再销毁实例,其等价如下:

var colors = ["red", "green", "blue", "yellow", "purple"];
var colors2 = colors.slice(1);//从下标为1的开始,到末尾
var colors3 = colors.slice(1, 4);//从下标1(包含1)到4(不包含4)
alert(colors2); //green,blue,yellow,purple
alert(colors3); //green,blue,yellow
//后台等价的代码
var s1 = new String("test string");
var s2 = s1.substring(4);
s1 = null;

splice会改变原数组数据,可实现对数组的删、插和替换

  所以基本类型和引用类型的主要区别是对象的生存期。new出来的对象实例在执行流离开当前作用域之前一直存在,而基本类型的对象只存在于一行代码的执行瞬间,然后立即被销毁了。

 var colors = ["red", "green", "blue"];
 var removed = colors.splice(0, 1); // 删除第一项(从下标0开始,删除1项)
 alert(colors); // green,blue
 alert(removed); // red,返回的数组中只包含一项
 removed = colors.splice(1, 0, "yellow", "orange"); // 从位置 1 开始插入两项(从下标0开始,删除0项,并插入后面的参数数据)
 alert(colors); // green,yellow,orange,blue
 alert(removed); // 返回的是一个空数组
 removed = colors.splice(1, 1, "red", "purple"); // 插入两项,删除一项(从下标1开始,删除1项[也就是yellow],并插入后面的参数数据)
 alert(colors); // green,red,purple,orange,blue
 alert(removed); // yellow,返回的数组中只包含一项
var s1="test string";
s1.color = "red";   
alert(s1.color);  //undefined

查找位置方法

  其次,二者还存在一个区别,当用类型检测函数时,返回值不一样。见代码:

indexOf()和 lastIndexOf(),就是查找在数组中的位置,和string中的对应方法差不多。

var value = "25";
var number = Number(value);
alert(typeof number);  //number

var obj = new Number(value);
alert(typeof obj);  //object

迭代方法

1、Boolean

 every():对数组中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 true。
 filter():对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组。
 forEach():对数组中的每一项运行给定函数。这个方法没有返回值。
 map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
 some():对数组中的每一项运行给定函数,如果该函数对任一项返回 true,则返回 true。

   Boolean类型是与布尔值对应的引用类型,重写了valueof()和toString()方法,前者返回基本类型值true和false,后者返回字符串”true”和”false”。区别和注意点看代码:

以上方法都不会修改数组中的包含的值。

//注意点
var falseObject = new Boolean(false);
var result0 = falseObject && true;
alert(result0);  //true;

var falseValue = false;
var result1 = falseValue && true;
alert(result1);  //false;

//区别
alert(typeof falseObject);  //object
alert(typeof falseValue); //boolean
alert(falseObject instanceof Boolean);  //true;
alert(falseValue instanceof Boolean); //false

如:

2、Number

var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item, index, array){
return (item > 2);
});
alert(everyResult); //false

    Number类型是与数字值对应的引用类型,valueof()返回基本数字值,toString([param])返回字符串形式,param表示按哪种进制的字符串形式返回。

其中。forEach和map区别不大,只是一个有返回值,一个没有。实际中我们用forEach比较多,下面我们模拟forEach的实现。

var num = 10;
alert(num.toString()); //"10"
alert(num.toString(2)); //"1010"
alert(num.toString(8)); //"12"
alert(num.toString(10)); //"10"
alert(num.toString(16)); //"a"
var str = "", str2 = "";
var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
numbers.forEach(function (item, index, array) {
 str += item + "_";
});
//**************其实我们完全可以自己模拟实现*******
numbers.myforEach = function (fun) {
 for (var i = 0; i < numbers.length; i++) {
  fun(numbers[i], i, numbers);
 }
}
numbers.myforEach(function (item, index, array) {
 str2 += item + "*";
})
//***************************************************
alert("str:" + str + " str2:" + str2);

var str = "", str2 = "";
var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
numbers.forEach(function (item, index, array) {
 str += item + "_";
});
//**************其实我们完全可以自己模拟实现*******
numbers.myforEach = function (fun) {
 for (var i = 0; i < numbers.length; i++) {
  fun(numbers[i], i, numbers);
 }
}
numbers.myforEach(function (item, index, array) {
 str2 += item + "*";
})
//***************************************************
alert("str:" + str + " str2:" + str2);

   另外,Number类型提供格式化字符串的函数

归并方法

//toFixed(number):返回指定小数位数的数值字符串形式,
var num = 10;
var num1 = 10.005;
alert(num.toFixed(2));  //"10.00"
alert(num1.toFixed(2));  //"10.01"
//toExponential(number):返回指数表示的字符串形式
alert(num.toExponential(1));  //"1.0e+1"
//toPrecision(number):返回上述两种方式中最合适的一种
var num2 = 99;
alert(num2.toPrecision(1));  //"1e+2"
alert(num2.toPrecision(2));  //"99"
alert(num2.toPrecision(3));  //"99.0"

 reduce()和 reduceRight(),这两个方法是比较有意思的,以前还真没接触过。先看例子,再解释:

   Number类型与基本类型的区别同Boolean类型一致

var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
 return prev + cur;
});
alert(sum); //15

 

也是个循环,第一次执行 prev 是 1, cur 是 2。第二次, prev 是 3(1 加 2 的结果), cur 是 3(数组的第三项)。这个过程会持续到把数组中的每一项都访问一遍,最后返回结果。reduceRight只是方向相反。

五、单体内置对象

下面我们来模拟:

  ECMA-262对内置对象的定义是:有ECMAScript实现提供的、不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存 在了。Object、Array、String等都是内置对象,可以直接使用。除了这些,还有两个:Global和Math

var numbers = [1, 2, 3, 4, 5, 3];
var sum = numbers.reduce(function (prev, cur, index, array) {
 return prev + cur;
});
//***********************模拟实现reduce**************************
numbers.myreduce = function (fun) {
 for (var i = 0; i < numbers.length; i++) {
  var temp = 0;
  for (var j = 0; j < i; j++)
   temp += numbers[j];
  var tempNum = fun(temp, numbers[i], i, numbers);
 }
 return tempNum;
}
//*************************************************
var sum2 = numbers.myreduce(function (prev, cur, index, array) {
 return prev + cur;
})
alert("sum:" + sum + " sum2:" + sum2); //

var numbers = [1, 2, 3, 4, 5, 3];
var sum = numbers.reduce(function (prev, cur, index, array) {
 return prev + cur;
});
//***********************模拟实现reduce**************************
numbers.myreduce = function (fun) {
for (var i = 0; i < numbers.length; i++) {
 var temp = 0;
 for (var j = 0; j < i; j++)
  temp += numbers[j];
   var tempNum = fun(temp, numbers[i], i, numbers);
  }
  return tempNum;
}
//*************************************************
var sum2 = numbers.myreduce(function (prev, cur, index, array) {
 return prev + cur;
})
alert("sum:" + sum + " sum2:" + sum2); //

  1、Global对象

Date类型

  Global对象时ECMAScript的全局对象,对于不属于任何其它对象的方法和属性、所有在全局作用域中定义的属性和函数,都是Global对象的 属性,如isNaN()、isFinite()、parseInt()和parseFloat()等。ECMAScript没有直接指出如何访问 Global对象,但Web浏览器都将Global对象作为window对象的一部分加以实现。因此,在全局作用域中的函数和变量,都成了window对 象的一部分。

我们很多时候需要测试一个函数的性能,可以取它的执行进过时间:

  除了上述方法,Global对象还定义了URI编码方法和eval()方法。

//取得开始时间
var start = Date.now();
//调用函数
doSomething();
//取得停止时间
var stop = Date.now(),
result = stop – start;

  encodeURI(uristring)/encodeURIComponent(uristring):对URI编码,返回编码后的字符串。前者用于 对整个URI编码,不会对冒号、正斜杠(/)、问号和井字号等本身属于URI的特殊字符进行编码;后者主要对URI的某一段进行编码,对于冒号、正斜杠 (/)、问号和井字号等任何的非标准字符都会编码。

下面列出一些常用方法

  decodeURI(uristring)/decodeURIComponent(uristring):前者对 encodeURI(uristring)编码的字符串进行解码;后者对encodeURIComponent(uristring)编码的字符串进行解 码。

getTime() 返回表示日期的毫秒数;与valueOf()方法返回的值相同
setTime(毫秒) 以毫秒数设置日期,会改变整个日期
getFullYear() 取得4位数的年份(如2007而非仅07)
getUTCFullYear() 返回UTC日期的4位数年份
setFullYear(年) 设置日期的年份。传入的年份值必须是4位数字(如2007而非仅07)
setUTCFullYear(年) 设置UTC日期的年份。传入的年份值必须是4位数字(如2007而非仅07)
getMonth() 返回日期中的月份,其中0表示一月, 11表示十二月
getUTCMonth() 返回UTC日期中的月份,其中0表示一月, 11表示十二月
setMonth(月) 设置日期的月份。传入的月份值必须大于0,超过11则增加年份
setUTCMonth(月) 设置UTC日期的月份。传入的月份值必须大于0,超过11则增加年份
getDate() 返回日期月份中的天数(1到31)
getUTCDate() 返回UTC日期月份中的天数(1到31)
setDate(日) 设置日期月份中的天数。如果传入的值超过了该月中应有的天数,则增加月份
setUTCDate(日) 设置UTC日期月份中的天数。如果传入的值超过了该月中应有的天数,则增加月份
getDay() 返回日期中星期的星期几(其中0表示星期日, 6表示星期六)
getUTCDay() 返回UTC日期中星期的星期几(其中0表示星期日, 6表示星期六)
getHours() 返回日期中的小时数(0到23)
getUTCHours() 返回UTC日期中的小时数(0到23)
setHours(时) 设置日期中的小时数。传入的值超过了23则增加月份中的天数
setUTCHours(时) 设置UTC日期中的小时数。传入的值超过了23则增加月份中的天数
getMinutes() 返回日期中的分钟数(0到59)
getUTCMinutes() 返回UTC日期中的分钟数(0到59)
setMinutes(分) 设置日期中的分钟数。传入的值超过59则增加小时数
setUTCMinutes(分) 设置UTC日期中的分钟数。传入的值超过59则增加小时数
getSeconds() 返回日期中的秒数(0到59)
getUTCSeconds() 返回UTC日期中的秒数(0到59)
setSeconds(秒) 设置日期中的秒数。传入的值超过了59会增加分钟数
setUTCSeconds(秒) 设置UTC日期中的秒数。传入的值超过了59会增加分钟数
getMilliseconds() 返回日期中的毫秒数
getUTCMilliseconds() 返回UTC日期中的毫秒数
setMilliseconds(毫秒) 设置日期中的毫秒数
setUTCMilliseconds(毫秒) 设置UTC日期中的毫秒数
getTimezoneOffset() 返回本地时间与UTC时间相差的分钟数。例如,美国东部标准时间返回300。在某地进入夏令时的情况下,这个值会有所变化

  eval(string):string是要执行的JavaScript字符串,eval()对JavaScript字符串进行解析,并将执行结果插入到 原来的位置。eval()执行的代码是包含该次调用的执行环境的一部分,被执行的代码与该执行环境有相同的作用域链。在eval()中创建的任何变量或者 函数都不会被提升。

RegExp类型

var x3 = "test";
var x=3;
var y = eval("x"+x);
alert(y);  //test

两种表示法:

  2、Math对象

var pattern1 = /at/g; 
var re = new RegExp("cat", "g"); 

  常见属性和方法

后面的参数代表模式,如:g:表示全局(global)模式、i:表示不区分大小写(case-insensitive)模式、m:表示多行(multiline)模式

属性 说明
Math.E 常量e的值
Math.LN10 10的自然对数
Math.LN2 2的自然对数
Math.LOG2E 以2为底e的对数
Math.LOG10E 以10为底e的对数
Math.PI 圆周率的值
Math.SQRT1_2 1/2的平方根
Math.SQRT2 2的平方根
Math.min()与Math.max() 求一组数的最小和最大值
Math.ceil() 进1取整
Math.floor() 舍1取整
Math.round() 四舍五入
Math.random 返回0~1的随机数,包含0不包含1

关于正则了解不是很清楚,后期有机会在单独学习整理正则这块。

原文首发:

Function类型

三种表示法:

function sum (num, num) { return num + num; } 
var sum = function(num, num){ return num + num; }; 
var sum = new Function("num", "num", "return num + num"); 

以上三种都是可行的,不过我们平时用得比较多的是第一种,第二种也有用,第三种用得比较少,但是最能看出function的本质,其实就是一个Function对象的实例。

我们来看看1和2的区别。

alert(sum1(1, 2));//弹出值 3
alert(sum2(1, 2));//报异常[sum2 is not a function]
function sum1(num1, num2) { return num1 + num2; }
var sum2 = function (num1, num2) { return num1 + num2; };

因为js解析器是从上到下的解析,在执行sum2的时候还没有定义,所以报异常。但是sum1比较特殊,是申明式的。在执行sum1之前就会”预解析“(函数声明提升)。相当于把sun1的定义提到了最上面(放到源代码树的顶部)。

方法重载

严格来说,js中是没有方法重载的,不过我们可以根据参数的个数来模拟。(还有,js中函数的形参我们是不确定类型的)

例:
上面并没有出现我们预料中的结果,因为第二次定义的sun1不是实现的重载,而是直接覆盖了第一次的定义。下面,我们就简单的模拟实现方法重载:

function sum1(num1, num2, num3) {
 if (num1 != undefined && num2 != undefined && num3 != undefined) {
  return num1 + num2 + num3;
 }
 else if (num1 != undefined && num2 != undefined)
  return num1 + num2;
}
alert(sum1(1, 2));
alert(sum1(1, 2, 3));

 函数内部属性(arguments 和 this)

arguments:类数组对象,包含着传入函数中的所有参数。下面通过arguments实现上面的模拟重载:

function sum(num, num, num) {
 var temp = ;
 if (arguments.length == ) {
  //***********具体实现其逻辑*********************
  for (var i = ; i < arguments.length; i++) {
   temp += arguments[i];
  }
 }
 else {
  //***********具体实现其逻辑*********************
  for (var i = ; i < arguments.length; i++) {
   temp += arguments[i];
  }
 }
 return temp;
}
alert("+=" + sum(, ) + " ++=" + sum(, , ));

 function sum1(num1, num2, num3) {
var temp = 0;
if (arguments.length == 3) {
//***********具体实现其逻辑*********************
for (var i = 0; i < arguments.length; i++) {
temp += arguments[i];
}
}
else {
//***********具体实现其逻辑*********************
for (var i = 0; i < arguments.length; i++) {
temp += arguments[i];
}
}
return temp;
}
alert("1+2=" + sum1(1, 2) + " 1+2+3=" + sum1(1, 2, 3));

我们在第一篇博文里面有提一个问题:

六、

 var fun = function (num1) {
  if (num1 <= 1) {
   return 1;
  }
  else {
   return num1 * fun(num1 - 1);
  }
 }
 var fun2 = fun;
 fun = function () {
  return 1;
 }
 alert(fun2(5));//这里弹出什么? 

 不过,并没有同学去解答,有人可能觉得太简单,或是不乐意懒得去解答。这题的答案是:

 为什么会是这个答案呢?好像和我们预料中的不一样。下面我们图解:

图片 2

我们可能发现了一个问题,那就是第4步调用的已经不是所在的这个函数本身了(也就是没有递归了),这不是我们想要的。我们要的是,不管外面怎么改变,4处都代表所在的函数指针。那么我们可以用到arguments的callee方法,例:

 函数的另一个内部属性this:

 首先我们看看这样一个问题:

var color = "red";
var o = { color: "blue" };
function sayColor() {
 alert(this.color);
}
sayColor(); //"red"
o.sayColor = sayColor;
o.sayColor(); //"blue"

为什么会有不同的结果?我们记住一句话,一般情况"哪个对象点出来的方法,this就是哪个对象"。上面的例子其实等效于:

window.color = "red";
var o = { color: "blue" };
function sayColor() {
 alert(this.color);
}
window.sayColor(); //"red"
o.sayColor = sayColor;
o.sayColor(); //"blue" 

 虽然"哪个对象点出来的方法,this就是哪个对象",但是有时候我们不想要这样的结果,我们不想用对象点或者对象点出了想this是另外的对象。那么我们可以使用call:

 传如的第一个参数,直接赋值给函数里面的this。和call类似的有apply,区别看下面:

 var o = { color: "blue" };
 var o2 = { color: "red" };
 function sayColor(a, b) {
  alert(this.color + a + b);
 }
 sayColor.apply(o, [1, 2]);//只传两个参数,第一个是为this赋值的对象,第二个是函数实参数组
 sayColor.call(o2, 1, 2);//可以传多个参数,第一个是为this赋值的对象,后面的是函数实参用逗号分割

基本包装类型

 在这个系列的第一篇中有个问题:

四、

var obj1 = {}; obj1.name2 = "张三";
var str1 = "test"; str1.name2 = "李四";
alert(obj1.name2 + " " + str1.name2);

 为什么会是这样的结果?因为str1.name2设置值的时候访问的是string的包装类,然后再次访问str1.name2之前就把之前那个包装类已经被销毁。

为什么要有包装类?

因为可以像操作引用对象一样操作基本数据类型,如: var s1 = "some text"; var s2 = s1.substring(2);

哪些基本类型有包装类?

Boolean、Number和String类型。

浏览器的内置对象

Global(其实也就是我们平时用的window)和Math(一些计算功能)

URI 编码方法

encodeURI、encodeURIComponent、decodeURI、decodeURIComponent
//encodeURI主要对完整的url进行编码(空格会编码成%20)【对应该的解码decodeURI】
alert(window.encodeURI("http://i.cnblogs.com/EditPosts.aspx?postid = 5002381"));
//encodeURIComponent会把url中的所有特殊字符进行转码(所以,我们一般用来进行部分url转码,如Url中的参数)【对应的解码decodeURIComponent】
alert(window.encodeURIComponent("http://i.cnblogs.com/EditPosts.aspx?postid = 5002381"));
eval

这是一个js中最最最强大的函数了,相对与一个独立的解析器。如我文中的操作实例就是用这个函数实现的。

如:

 <textarea class="test_code" style="width: %;height:px; max-height: px;">
//。。。。这里面写js代码
var obj = {}; obj.name = "张三";
var str = "test"; str.name = "李四";
alert(obj.name + " " + str.name);
 </textarea>
 <input type="button" class="test_code_but" onclick="eval($(this).prev().val());" value="运行" />

效果图:

图片 3

当然,你还的引入jqeruy问题,博客园中默认就已经引入了。所以,你不需要再次引入,你测试的话是看不到alert弹框的,因为博客园禁掉了。我的是用的jquery ui中的Dialog对话框做的。

您可能感兴趣的文章:

  • js中判断Object、Array、Function等引用类型对象是否相等
  • 详解JavaScript基础知识(JSON、Function对象、原型、引用类型)
  • JavaScript引用类型之基本包装类型实例分析【Boolean、Number和String】
  • JavaScript引用类型Date常见用法实例分析
  • JavaScript引用类型Object常见用法实例分析
  • JavaScript引用类型Array实例分析
  • js类型转换与引用类型详解(Boolean_Number_String)
  • javascript中基本类型和引用类型的区别分析
  • JavaScript基本数据类型及值类型和引用类型
  • 浅析JavaScript基本类型与引用类型
  • JavaScript引用类型Function实例详解

本文由王中王开奖结果发布于网络应用,转载请注明出处:引用类型,Function等引用类型

关键词: