JavaScript 学习笔记 02 (引用数据类型)
一、基本数据类型和引用数类型
基本数据类型:Undefined、Null、Boolean、Number和String
引用数据类型:Object
基本类型指的是简单的数据段、引用类型值的是可能由多个值构成的对象。
1、复制变量值
一个变量复制另一个变量的值,如果被复制的变量是基本类型的值,则会创建一个新的基本类型,然后把该值分配到新变量上。此时改变其中一个变量,不会影响另外一个变量。例如:
var num1 = 5 var num2 = num1
num1 = 6
alert(num2) // 5
一个变量复制另一个变量的值,如果被复制的变量是引用类型的值,则会把存储在变量对象中的值复制一份放到新分配的变量中。不同的是复制的其实是一个指针,指针指向的是存储在堆中的一个对象。复制结束后两个变量将指向同一个对象。因此改变其中一个变量,会影响另外一个变量。例如:
var obj1 = new Object() var obj2 = obj1 obj1.name = "Hi" alert(obj2.name) // 'Hi'
2、传递参数
ECMAScript 中所有函数的参数都是按照值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另外一个变量一样。基本类型会复制一份值赋值给函数的参数,引用类型会复制一份指针地址赋值给函数的参数。
基本类型:
function addTen( num ) { num += 10 return num } var count = 20 var result = addTen(count) alert(count) // 20 没有变化 alert(result) //30
引用类型:
function setName( obj ) { obj.name = "Hi" } var person = new Object() setName(person) alert(person.name) // "Hi"
二、引用类型
引用类型具体有哪些。
1、Object 类型
创建有两种基本方法
一是使用 new 操作符后跟 Object 构造函数
var person = new Object() person.name = "Hi" person.age = 29
二是使用对象字面量表示法。对象字面量是对象定义的一种简化形式,目的在于简化创建包含大量属性的对象的过程,更常用的是这种方法。
var person = { name : "Hi", age: 29 }
2、Array 类型
除了 Object 类型之外,最常用的就是 Array 类型。
创建有两种基本方法
一是使用 new 操作符后跟 Array 构造函数
var colors = new Array() var colors = new Array(20) // 创建一个长度为20的数组 var colors = new Array("red","blue","green") // 创建包含三个字符串值的数组
二是使用数组字面量表示法
var colors = [] var colors = ["red","blue","green"]
1、检测数组
使用 Array.isArray() 方法检测某个值到底是不是数组。
if ( Array.isArray( value) ){ // 对数组执行某些操作 }
2、常用方法
var colors = ["red","green","blue"] alert(colors.toSring()) // "red,green,blue" 转换成字符串输出 alert(colors.join("||") // "red||green||blue" 转换成字符串输出,并且指定分隔符 ,如果不传默认是逗号 // push() 方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并且返回修改后的数组长度 var count = colors.push("a","b") alert(count) // 5 因为现在colors数组是 ["red","green","blue","a","b"] // pop() 方法移除数组最后一项,并且返回该项 var item = colors.pop() alert(item) // "b" alert(colors.length) // 4 // shift() 方法移除数组的第一项,并且返回该项 var item2 = colors.shift() alert(item2) // "red" alert(colors.length) //3 // unshift() 方法可以从数组第一项添加值,并且返回数组的长度 var count2 = colors.unshift("red") alert(count2) // 4 alert(colors) // ["red","green","blue","a"]
var values = [1,2,3,4,5] // reverse() 方法可以翻转数组 values.reverse() // [5,4,3,2,1] var values = [0,1,5,10,15] // sort() 方法会根据字符串比较排序,字符串中“10”在“5”之前 values.sort() // [0, 1, 10, 15, 5] // sort() 方法会接收一个比较函数作为参数,方便自己定义某种排序方式。 // 比较函数接收两个参数,如果第一个参数应该位于第二个之前则应该返回一个负数,如果两个参数相等则返回0,如果第一个参数应该位于第二个之后则返回一个整数。 function compare(value1, value2 ) { if ( value1 < value2 ) { return -1 } else if ( value1 > value2 ) { return 1 } else { return 0 } } values.sort(compare) // [0,1,5,10,15]
var colors = ["a","b","c","d","e"] // slice() 方法可以基于当前数组创建一个新的数组。该方法接收一个或者两个参数。如果只有一个参数表示从指定的位置到数组末尾。如果有两个参数表示从起始和结束的位置。 var colors2 = colors.slice(1) // ["b","c","d","e"] var colors3 = colors.slice(1,3) // ["b","c"] var colors4 = colors.slice(2,-1) // ["c", "d"] // splice() 方法可以删除、插入、替换,第一个参数为开始变化的位置,第二个参数表示删除到某个位置,如果为0则表示不删除。之后的参数表示要添加的参数 var colors = ["a","b","c"] var removed = colors.splice(0,1) // 删除第一项 ["a"] 此时colors为 ["b","c"] var removed = colors.splice(1,0,"d","e") // 从位置1开始插入两项,此时colors为 ["b", "d", "e", "c"] var removed = colors.splice(1,1,"f","g") // 从位置1删除一项,插入两项 此时 colors 为 ["b", "f", "g", "e", "c"]
var numbers = [1,2,3,4,5,4,3,2,1] // indexOf() 方法接收两个参数:要查找的项和表示查找起点位置的索引(如果省略了则表示从头开始),如果未找到返回-1 // lastIndexOf() 和indexOf() 方法类似,但是是从末尾开始向前找。 numbers.indexOf(4) // 3 numbers.indexOf(4,4) // 5 numbers.lastIndexOf(4) //5 numbers.lastIndexOf(4,4) //3
几个迭代方法
// every():对数组中的每一项运行给定的函数,如果该函数对每一项都返回true,则返回 true // some():对数组中的每一项运行给定的函数,如果该函数对任一项返回true,则返回true // filter():对数组中的每一项运行给定的函数,返回该函数返回true的项组成的数组。 // forEach(): 对数组中的每一项运行给定的函数,这个方法没有返回值。 // map():对数组中的每一项运行给定的函数,返回每次函数调用的结果组成的数组。 // 每个方法都接受两个参数:要在每一项上运行的函数和运行该函数的作用域对象(影响this的值,可省略) 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 var someResult = numbers.some(function( item, index, array ){ return item > 2 }) alert(someResult) // true var filterResult = numbers.filter(function( item, index, array ){ return item > 2 }) alter(filterResult) // [3,4,5,4,3] var mapResult = numbers.map(function( item, index, array ){ return item * 2 }) alter(mapResult) // [2,4,6,8,10,8,6,4,2] numbers.forEach(function( item, index, array ){ // 执行某些操作 })
缩小方法
// reduce() 方法会迭代数组的所有项,然后构建一个最终的返回值 var values = [1,2,3,4,5] var sum = values.reduce(function(prev, cur, index, array){ return prev + cur }) alert(sum) // 15
3、Date 类型
Date 类型的数其实是毫秒级的时间戳
// 取得开始时间 var start = Date.now() // 调用函数做事情 doSomething() // 取得结束时间 var stop = Date.now() // 花费的时间 result = stop - start
4、RegExp 类型
通过 RegExp 类型来支持正则表达式。
主要有 exec() 和 test() 方法。以后会单独有一篇写一下正则表达式
var text = "cat bat sat fat" var pattern1 = /.at/ var matches = pattern1.exec(text) matches.index // 0 matches[0] // cat pattern1.lastInex //0 var text2 = "this has been a short summer" var pattern = /(.)hort/g pattern.test(text) // true
5、Function 类型
每个函数都是 Function 类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。
函数通常是使用函数声明语法定义的,和函数表达式定义函数的方式一样。
// 函数声明语法 function sum ( num1, num2 ) { return num1 + num2 } // 函数表达式 var sum = function ( num1, num2 ) { return num1 + num2 }
1、没有重载
声明两个同名函数,其实是后面的函数覆盖了前面的函数。
function addSomeNumber(num){ return num + 100 } function addSomeNumber(num){ return num + 200 } var result = addSomeNumber(100) // 300
2、函数声明与函数表达式
在定义一个函数的时候,使用函数声明和函数表达式还是会有细微的差别。
alert(sum(10,10)) function sum(num1, num2) { return num1 + num2 }
上面例子中的代码可以正常执行,因为在代码执行之前,已经通过一个名为函数声明提升的过程,读取并且将函数声明添加到执行环境中。下面函数表达式的写法就会报错。
alert(sum(10,10)) var sum = function (num1, num2) { return num1 + num2 }
6、基本包装类型
看下面一个例子
var s1 = "some text" var s2 = s1.substring(2) // "me text"
第二行调用了 s1 的 substring() 方法,并且将返回值赋值给了 s2。我们知道 s1 是一个字符串,字符串是基本类型,从逻辑上来讲它们是不应该有方法的。
其实为了让我们实现这种直观的操作,后台自动完成了创建包装类实例,调用方法,销毁实例的过程。类似于执行了下面的三个步骤
var s1 = new String("some text") var s2 = s1.substring(2) s1 = null
基本包装类有三种类型:Boolean、Number 和 String
7、单体内置对象
对内置对象的定义是:“由ECMAScript实现提供的、不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在了。”
前面已经介绍了大多数内置对象,例如 Object、Array 和 String
还有两个单体内置对象:Global 和 Math
后面会单独写一篇关于 Global 和 window 的介绍
列一下 Math 常用的方法和属性
// 属性 Math.E // 自然对数的底数,即常量e的值 Math.LN10 // 10的自然对数 Math.LN2 // 2的自然对数 Math.LOG2E // 以2为底e的对数 Math.LOG10E // 以10为底e的对数 Math.PI // π的值 Math.SQRT2 // 2的平方根 // 方法 Math.max() // 确定一组数中的最大值 Math.min() // 确定一组数中的最小值 Math.ceil() // 向上取整 Math.floor() // 向下取整 Math.round() // 四舍五入 Math.random() //取 0 和 1之间的一个随机数,不包括 0 和1 Math.abs(num) // 返回num的绝对值 Math.exp(num) //返回Math.E的num次幂 Math.log(num) //返回num的自然对数 Math.pow(nuw, power) //返回num的power次幂 Math.sqrt(num) // 返回num的平方根