一步步学习javascript基础篇(3):Object、Function等引用类型
我们在《一步步学习javascript基础篇(1):基本概念》中简单的介绍了五种基本数据类型Undefined、Null、Boolean、Number和String。今天我们主要介绍下复杂数据类型(即引用数据类型)
Object类型
我们用的最多的引用类型就属object类型了,一般用来存储和传输数据是再好不过的。然,它的两种创建方式我们是否了解呢?
1、通过构造函数来创建
如: var obj = new Object();
在js中的引用类型有个非常灵活的用法,可以动态的附加属性和赋值。
如:
- var obj = new Object();
- obj.name = "张三";//动态添加属性并赋值
- obj.age = 23;
- alert(obj.name);
2、通过字面量表示法来创建对象
现在大家用得比较多的就是字面量表示法来创建对象了。
如:
- var obj = {
- name: "张三",
- age: 23
- };
- alert(obj.age);
和上面的效果是等效的。通过这样方式创建感觉结构更加的清晰,更加有封装的感觉。:)
我们还可以这样用
如:
- var obj = {};
- obj.name = "张三";
- obj.age = 23;
- alert(obj.age);
如:
- var obj = {
- "name": "张三",//给属性加上双引号
- age: 23
- };
- alert(obj.name);
是不是感觉很强大很灵活呢?我在访问属性的时候一般都是点出来,但是还有另外的方式。
如:(我们可以使用中括号的形式来访问属性值)
- var obj = {
- "name tow": "张三",
- age: 23
- };
- //alert(obj.name tow);//这里会报错,属性不能有空格
- alert(obj["name tow"]);//这里可以正常弹出
例:
var obj = {
"name tow": "张三",
age: 23
};
//alert(obj.name tow);//这里会报错,属性不能有空格
alert(obj["name tow"]);//这里可以正常弹出
Array类型
除了object之外,应该属数组用的最多了。下面来罗列下常见用法。
同样Array也有两种创建方式:
- var arr = new Array(1, 2, 3, 4, 5);//通过构造函数创建
- var arr2 = [5, 4, 3, 2, 1];//通过字面量表达式来创建
上面两种方式是等效的,我们可以直接通过下标的方式来访问数组: alert(arr[2]); 。
如果我们想要打印数组中所有的值,直接打印数组的变量名就可以:
- 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方法)
例:
var arr2 = [5, 4, 3, 2, 1];//通过字面量表达式来创建
var str2 = "";
for (var i = 0; i < arr2.length; i++) {
str2 += arr2[i] + ","
}
alert(str2);//打印拼接的字符串
例:
var arr2 = [5, 4, 3, 2, 1];//通过字面量表达式来创建
alert(arr2);//直接打印变量名(实际上会自动调用数组的toString方法)
上面直接打印arr2,我们发现默认都是以逗号分隔的。那么有时候,我们不想用逗号怎么办呢。那你可能可以用到join方法
var arr2 = [5, 4, 3, 2, 1];//通过字面量表达式来创建
alert(arr2.join('_'));//直接打印变量名(实际上会自动调用数组的toString方法)
往数组添值:
我们可以直接: arr2[4] = 7; arr2[5] = 8;
还有一种更加巧妙地添值方式: arr2[arr2.length] = 9; arr2[arr2.length] = 10; ,下标length刚好是数组最大长度的下一个,添加值后length再次动态自动累计。
栈方法、队列方法:
什么是栈?(后进先出)。什么是队列?(先进先出),我们怎样用数组来模仿这种数据结构的访问方式?下面通过一张图来解释下数组对象提供的四个方法。
从图可以看出:shift和push、unshift和pop的组合可以实现栈的数据结构访问,shitf和pop、shift和unshift的组合可以实现队列的数据机构访问方式。 这里需要注意:pop和shift取数据的同时,数组中对于的值也同时移除了。
例:
var arr2 = [5, 4, 3, 2, 1];
alert("arr2.pop:" + arr2.pop() + " arr2:" + arr2);
关于数组的排序:
关于数组的排序有sort(正)reverse(反)。
先看个例子,大家猜想下结果:
- var arr2 = [5, 14, 23, 12, 1];
- alert(arr2.sort());
然结果并不是我们想要的:
var arr2 = [5, 14, 23, 12, 1];
alert(arr2.sort());
为什么会这样呢?因为sort不会直接比较数字类型,而已转为string了再做的比较。那么我们想要比较数字怎办?我们可以往sort传函数,例:
function mycompare(o1, o2)
{
return o1 - o2;//如果为正数则o1大,负数则o2大,零则相等。
}
var arr2 = [5, 14, 23, 12, 1];
alert(arr2.sort(mycompare));
有人会问o1和o2是怎么来的?这是sort函数规定的。这样说大家可能不好接受。下面,我们自己来模拟下sort的排序,大家就明白了。
- 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));
当然,我们模拟的并不是那么的好,大概就是这么个意思。
反序就简单了:(直接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创建一个新的副本,并合并传进来的参数
- 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
slice创建一个新的副本,取数组的位置数据
- 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
splice会改变原数组数据,可实现对数组的删、插和替换
- 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 开始插入两项(从下标1开始,删除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,返回的数组中只包含一项
查找位置方法
indexOf()和 lastIndexOf(),就是查找在数组中的位置,和string中的对应方法差不多。
迭代方法
every():对数组中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 true。
filter():对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组。
forEach():对数组中的每一项运行给定函数。这个方法没有返回值。
map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
some():对数组中的每一项运行给定函数,如果该函数对任一项返回 true,则返回 true。
以上方法都不会修改数组中的包含的值。
如:
- 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
其中。forEach和map区别不大,只是一个有返回值,一个没有。实际中我们用forEach比较多,下面我们模拟forEach的实现。
- 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);
归并方法
reduce()和 reduceRight(),这两个方法是比较有意思的,以前还真没接触过。先看例子,再解释:
- var values = [1,2,3,4,5];
- var sum = values.reduce(function(prev, cur, index, array){
- return prev + cur;
- });
- alert(sum); //
也是个循环,第一次执行 prev 是 1, cur 是 2。第二次, prev 是 3(1 加 2 的结果), cur 是 3(数组的第三项)。这个过程会持续到把数组中的每一项都访问一遍,最后返回结果。reduceRight只是方向相反。
下面我们来模拟:
- 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); //
Date类型
我们很多时候需要测试一个函数的性能,可以取它的执行进过时间:
- //取得开始时间
- var start = Date.now();
- //调用函数
- doSomething();
- //取得停止时间
- var stop = Date.now(),
- result = stop – start;
下面列出一些常用方法
- 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。在某地进入夏令时的情况下,这个值会有所变化
RegExp类型
两种表示法:
1. var pattern1 = /at/g;
2. var re = new RegExp("cat", "g");
后面的参数代表模式,如:g:表示全局(global)模式、i:表示不区分大小写(case-insensitive)模式、m:表示多行(multiline)模式
关于正则了解不是很清楚,后期有机会在单独学习整理正则这块。
Function类型
三种表示法:
1. function sum (num1, num2) { return num1 + num2; }
2. var sum = function(num1, num2){ return num1 + num2; };
3. var sum = new Function("num1", "num2", "return num1 + num2");
以上三种都是可行的,不过我们平时用得比较多的是第一种,第二种也有用,第三种用得比较少,但是最能看出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中函数的形参我们是不确定类型的)
例:
function sum1(num1, num2) {
return num1 + num2;
}
function sum1(num1, num2, num3) {
return num1 + num2 + num3;
}
alert(sum1(1, 2));
上面并没有出现我们预料中的结果,因为第二次定义的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 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));
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));//这里弹出什么?
不过,并没有同学去解答,有人可能觉得太简单,或是不乐意懒得去解答。这题的答案是:
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));//这里弹出什么?
为什么会是这个答案呢?好像和我们预料中的不一样。下面我们图解:
我们可能发现了一个问题,那就是第4步调用的已经不是所在的这个函数本身了(也就是没有递归了),这不是我们想要的。我们要的是,不管外面怎么改变,4处都代表所在的函数指针。那么我们可以用到arguments的callee方法,例:
var fun = function (num1) {
if (num1 <= 1) {
return 1;
}
else {
return num1 * arguments.callee(num1 - 1);
}
}
var fun2 = fun;
fun = function () {
return 1;
}
alert(fun2(5));//这里弹出什么?
函数的另一个内部属性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:
var o = { color: "blue" };
var o2 = { color: "red" };
function sayColor() {
alert(this.color);
}
//sayColor.call(o);
sayColor.call(o2);
传如的第一个参数,直接赋值给函数里面的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);
//四、
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: 80%;height:220px; max-height: 200px;">
- //。。。。这里面写js代码
- var obj1 = {}; obj1.name2 = "张三";
- var str1 = "test"; str1.name2 = "李四";
- alert(obj1.name2 + " " + str1.name2);
- </textarea>
- <input type="button" class="test_code_but" onclick="eval($(this).prev().val());" value="运行" />
效果图:
当然,你还的引入jqeruy问题,博客园中默认就已经引入了。所以,你不需要再次引入,你测试的话是看不到alert弹框的,因为博客园禁掉了。我的是用的jquery ui中的Dialog对话框做的。
总结
码字真累,不知不觉已经从中午十二点已经到了晚上八点了,没想到一篇这样的文章断断续续尽然花了我七八个小时的时间。感觉越到后面越没有耐心,还好现在终于写完了。
这是学习记录,不是教程。文中错误难免,您可以指出错误,但请不要言辞刻薄。
原文链接:http://haojima.net/zhaopei/515.html
本文已同步至目录索引:一步步学习javascript
欢迎上海“程序猿/媛”、"攻城狮"入群:【沪猿】229082941 入群须知
如果您觉得文章对您有那么一点点帮助,那么麻烦您轻轻的点个赞,以资鼓励。
一步步学习javascript基础篇(3):Object、Function等引用类型的更多相关文章
- 一步步学习javascript基础篇(0):开篇索引
索引: 一步步学习javascript基础篇(1):基本概念 一步步学习javascript基础篇(2):作用域和作用域链 一步步学习javascript基础篇(3):Object.Function等 ...
- 一步步学习javascript基础篇(5):面向对象设计之对象继承(原型链继承)
上一篇介绍了对象创建的几种基本方式,今天我们看分析下对象的继承. 一.原型链继承 1.通过设置prototype指向“父类”的实例来实现继承. function Obj1() { this.name1 ...
- 一步步学习javascript基础篇(4):面向对象设计之创建对象(工厂、原型和构造函数等模式)
前面我们介绍了可以通过Object构造函数或对象字面量都可以用来创建单个对象,但是如果需要创建多个对象的话,显然很多冗余代码. 接下来介绍几种模式来创建对象.不过在此之前,我们还是先来了解下 type ...
- 一步步学习javascript基础篇(1):基本概念
一.数据类型 数据类型 基本数据类型(五种) Undefined Null Boolean Number String 复杂数据类型(一种) Object Undefined:只有一个值undefin ...
- 一步步学习javascript基础篇(8):细说事件
终于学到事件了,不知道为何听到“事件”就有一种莫名的兴奋.可能是之前的那些知识点过于枯燥无味吧,说起事件感觉顿时高大上了.今天我们就来好好分析下这个高大上的东西. 可以说,如果没有事件我们的页面就只能 ...
- 一步步学习javascript基础篇(7):BOM和DOM
一.什么是BOM.什么是DOM BOM即浏览器对象模型,主要用了访问一些和网页无关的浏览器功能.如:window.location.navigator.screen.history等对象. DOM即文 ...
- 一步步学习javascript基础篇(6):函数表达式之【闭包】
回顾前面介绍过的三种定义函数方式 1. function sum (num1, num2) { return num1 + num2; } //函数声明语法定义 2. var sum = funct ...
- 一步步学习javascript基础篇(2):作用域和作用域链
作用域和作用域链 js的语法用法非常的灵活,且稍不注意就踩坑.这集来分析下作用域和作用域链.我们且从几道题目入手,您可以试着在心里猜想着答案. 问题一. if (true) { var str = & ...
- 一步步学习javascript基础篇(9):ajax请求的回退
需求1: ajax异步请求 url标识请求参数(也就是说复制url在新页面打开也会是ajax后的效果) ajax异步请求没问题,问题一般出在刷新url后请求的数据没了,这就是因为url没有记录参数.如 ...
随机推荐
- [Java 8] (10) 使用Lambda完成函数组合,Map-Reduce以及并行化
好文推荐!!!!! 原文见:http://blog.csdn.net/dm_vincent/article/details/40856569 Java 8中同时存在面向对象编程(OOP)和函数式编程( ...
- swift - 字典和集合
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #4dbf56 } p.p2 { margin: 0.0px 0. ...
- JavaScript isNaN() 函数
定义与用法: isNaN() 函数用于检查其参数是否是非数字值. 语法: isNaN(x) 描述: x是要检测的值. 返回值: 如果 x 是特殊的非数字值 NaN(或者能被转换为这样的值),返 ...
- LINQ 左右连接
LINQ 左右连接:DefaultIfEmpty() incomeList = (from p in db.Incomes join m in db.Items on p.ItemID equals ...
- Spring MVC MultipartFile实现图片上传
<!--Spring MVC xml 中配置 --><!-- defaultEncoding 默认编码;maxUploadSize 限制大小--><!-- 配置Multi ...
- DateTable利用NPOI导出Excel 公共方法
protected void Export_Excel(DataTable dt) { string filename = "学生基本信息.xls"; ) { filename = ...
- python 编码问题
参考原文:http://www.crifan.com/eclipse_pydev_console_messy_char_for_console_is_utf8/ 通用 rq = urllib.urlo ...
- Exchange管理界面
Exchange有三种管理方式,一个是通过Powershell命令行操作进行管理.Exchange自带的Powershell是在其基础上建的,加入了Exchange管理操作的函数,能够进行另外两种方式 ...
- 命名困惑系列之一:关于state和status的粗浅研究
牛津高阶词汇的解释 state: CONDITION OF SB/STH 状态:the mental,emotional or physical condition that a person or ...
- Logback_日志使用详解(转)
概述 Logback建立于三个主要类之上:日志记录器(Logger),输出端(Appender)和日志格式化器(Layout).这三种组件协同工作,使开发者可以按照消息类型和级别来记录消息,还可以在程 ...