《JavaScript高级程序设计》引用类型(学习笔记C05)


各引用类型的使用,创建与操作数组,理解基本的JavaScript类型,使用基本类型和基本包装类型。

一、各引用类型

  1. 各引用类型:

    • Object
    • Array
    • Date
    • RegExp
    • Function
      引用类型也被称为对象定义,因为它们描述的是一类对象所具有的属性和方法。
  2. Object类型

    • 创建对象两种方法:
    	// new
    	var person = new Object()
    	person.name = 'Nike'
    	// 对象字面量
    	var person = {
    		name: 'Nike'
    	}
    	// 注意:数值属性名会自动转为字符串
    
    	// 最好是对那些必需值使用命名参数
    	// 而使用对象字面量来封装多个可选参数
    	function displayInfo(args) {
    		var output = ''
    		
    		if (typeof args.name == 'string') {
    			output += 'Name: ' + args.name + '\n'
    		}
    		
    		if (typeof args.age == 'number') {
    			output += 'Age: ' + args.age + '\n'
    		}
    		
    		alert(output)
    	}
    	
    	displayInfo({
    		name: 'Nike',
    		age: 29
    	})
    	
    	displayInfo({
    		name: 'Greg'
    	})
    
    
    • 访问的方法
      • 点表示法
      • 方括号表示法
        方括号表示法好处在于:
    	// 1.可通过变量访问属性
    	var proName = 'name'
    	alert(person[proName])
    	
    	// 2.属性名可用关键词或保留字
    	person['first name'] = 'Nike'
    	
    	// 3.一般情况常用点表示法
    
  3. Array类型

    • 数组:
      1.数据的有序列表
      2.ECMAScript数组的每一项可以保存任何类型的数据
      3.ECMAScript数组的大小可动态调节

    • 创建数组的方式:

      	// 1.Array构造函数
      	var colors = new Array()
      	
      	// 预先设定数量
      	var colors = new Array(20)
      	
      	// 包含指定项
      	var colors = new Array('red', 'blue', 'green')
      	
      	// 可省略new操作符
      	var colors = Array(20)
      	
      	// 2.数组字面量表示法
      	var colors = ['red', 'blue']
      	
      
    • 需要注意的地方:

      	// 1.length属性可读可写
      	
      	// 截断
      	var colors = ['red', 'green', 'blue']
      	colors.length = 2
      	alert(colors[2]) // undefined
      	
      	// 增加
      	var colors = ['red', 'green', 'blue']
      	colors.length = 4
      	alert(colors[3]) // undefined
      	
      	// 经常这样用到
      	var colors = ['red', 'green', 'blue']
      	colors[colors.length] = 'black' // 添加一个颜色
      	colors[colors.length] = 'brown' // 再添加一个颜色
      	
      	// 中间的值是undefined
      	var colors = ['red', 'green', 'blue']
      	colors[99] = 'black'
      	alert(colors.length) // 100
      
      

      数组最多可包含 4 294 967 295 个项

    • 检测数组:

      	// 1.假定只有一个全局作用域
      	if (value instanceof Array) {}
      	
      	// 2.不论在哪个全局环境中创建
      	if (Array.isArray(value)) {}
      
    • 转换方法:

      toLocaleString()

      toString()

      valueOf()

      join()

      	var colors = ['red', 'green', 'blue']
      	
      	// 在某些情况下返回值与toString()不同
      	console.log(colors.toLocaleString()) 
      	
      	 // red,blue,green
      	console.log(colors.toString())
      	
      	// ["red", "blue", "green"]
      	console.log(colors.valueOf()) 
      	
      	// red,blue,green
      	console.log(colors.join(,)) 
      	
      
    • 栈方法
      1.栈是一种LIFO(Last-In-First-Out,后进先出)的数据结构
      2.栈的顶部 相当于数组的末尾

      push()

      pop()

      	// push()可接收任意数量参数,逐个添加至末尾
      	// 返回修改后数组长度
      	var colors = new Array()
      	var count = colors.push('red', 'green')
      	console.log(count) // 2
      	
      	count = colors.push('black')
      	console.log(count) // 3
      	
      	// pop()从数组末尾移除最后一项,返回移除的项
      	var item = colors.pop()
      	console.log(item) // 'black'
      	console.log(colors.length) // 2
      	
      
    • 队列方法
      1.队列是一种FIFO(First-In-First-Out, 先进先出)的数据结构

      shift()

      push()

      unshift()

      pop()

      	// 使用shift()和push()方法模拟队列
      	// 在数组前端移除项,从数组末尾添加项
      
      	var colors = new Array()
      	var count = colors.push('red', 'green')
      	console.log(count) // 2
      	
      	count = colors.push('black')
      	console.log(count) // 3
      	
      	// shift()从数组开头移除第一项,并返回移除的值
      	var item = colors.shift()
      	console.log(item) // 'red'
      	console.log(colors.length) // 2
      
      	// 使用unshift()和pop()方法模拟队列
      	// 在数组前端添加项,从数组末尾移除项
      
      	// unshift()可接收任意数量参数,逐个添加至前端
      	// 返回修改后数组长度
      	var colors = new Array()
      	var count = colors.unshift('red', 'green')
      	console.log(count) // 2
      	
      	count = colors.unshift('black')
      	console.log(count) // 3
      	
      	var item = colors.pop()
      	console.log(item) // 'green'
      	console.log(colors.length) // 2
      
    • 重排序方法

      reverse()

      sort()

      	// 1.sort()默认比较字符串
      	
      	// 2.比较大多数数据类型
      	
      	// 正序
      	function compare(value1, value2) {
      		if (value1 < value2) {
      			return -1
      		} else if (value1 > value2) {
      			return 1
      		} else {
      			return 0
      		}
      	}
      	
      	var values = [0, 1, 5, 10, 15]
      	values.sort(compare)
      	console.log(values) // [0, 1, 5, 10, 15]
      	
      	// 倒序
      	function compare(value1, value2) {
      		if (value1 < value2) {
      			return 1
      		} else if (value1 > value2) {
      			return -1
      		} else {
      			return 0
      		}
      	}
      	
      	var values = [0, 1, 5, 10, 15]
      	values.sort(compare)
      	console.log(values) // [15, 10, 5, 1, 0]
      	
      	// 3.只比较数值类型
      	
      	// 升叙
      	function compare(value1, value2) {
      		return value2 - value1
      	}
      	// 实践中大多这么写
      	var arr = [3,4,5,1,2]
      	arr.sort((a, b) => {
      		return a-b
      	})
      	console.log(arr)
      	
      	// 倒叙
      	function compare(value1, value2) {
      		return value1 - value2
      	}
      	// 实践中大多这么写
      	var arr = [3,4,5,1,2]
      	arr.sort((a, b) => {
      		return b-a
      	})
      	console.log(arr)
      	
      
    • 操作方法

      concat() (原数组不变)

      slice() (原数组不变)

      splice() (原数组改变)

      	// concat()
      	var colors = ['red', 'green', 'blue']
      	var colors2 = colors.concat('yellow', ['black', 'brown'])
      	
      	// ['red', 'green', 'blue']
      	console.log(colors) 
      	// ['red', 'green', 'blue', 'yellow', 'black', 'brown']
      	console.log(colors2) 
      
      	// slice()
      	var colors = ['red', 'green', 'blue', 'yellow', 'purple']
      	var colors2 = colors.slice(1)
      	var colors3 = colors.slice(1, 4)
      	
      	// ['green', 'blue', 'yellow', 'purple']
      	console.log(colors) 
      	// ['green', 'blue', 'yellow']	
      	console.log(colors2) 		
      
      	// slice() 如果参数为负数相当于加上数组长度后的序数;
      	// 结束位置小于起始位置则返回空数组
      
      	// splice()
      	
      	var colors = ['red', 'green', 'blue']
      	// 删除 splice(要删除的第一项的位置, 要删除的项数)
      	var removed = colors.splice(0, 1)
      	console.log(colors) // ['green', 'blue']
      	console.log(removed) // ['red']
      	
      	// 插入 splice(起始位置, 0, 要插入的项)
      	removed = colors.splice(1, 0, 'yellow', 'orange')
      	// ['green', 'yellow', 'orange', 'blue']
      	console.log(colors) 
      	// ['red']
      	console.log(removed) 
      	
      	// 替换 splice(起始位置, 要删除的项数, 要插入的任意数量的项)
      	removed = colors.splice(1, 1, 'red', 'purple')
      	 // ['green', 'red', 'purple', 'orange', 'blue']
      	console.log(colors)
      	 // ['yellow']
      	console.log(removed)
      
    • 位置方法

      indexOf()
      (要查找的项,(可选的)从前往后,查找起点位置的索引)

      lastIndexOf()
      (要查找的项,(可选的)从后往前,查找起点位置的索引)

      	var numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1]
      	console.log(numbers.lastIndexOf(4, 4)) // 3
      	console.log(numbers.indexOf(4)) // 3
      	
      	console.log(numbers.lastIndexOf(4)) // 5
      	console.log(numbers.indexOf(4, 4)) // 5
      	
      	var person = {name: 'Nike'}
      	var people = [{name: 'Nile'}]
      	
      	var morePeople = [person]
      	
      	console.log(people.indexOf(person)) // -1
      	console.log(morePeople.indexOf(person)) // 0
      
    • 迭代方法

      以下共同:
      参数:(在每一项运行的函数(数组项的值,该项在数组中的位置,数组对象本身), (可选的)运行该函数的作用域对象–影响this的值)
      args: (function(item, index, array){}, (not must)scopeObj)

      对数组中的每一项运行给定参数

      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)
      })
      console.log(everyResult) // false
      
      var someResult = numbers.some(function(item, index, array){
      	return (item > 2)
      })
      console.log(someResult) // true
      
      var filterResult = numbers.filter(function(item, index, array){
      	return (item > 2)
      })
      console.log(filterResult) // [3, 4, 5, 4, 3]
      
      var mapResult = numbers.map(function(item, index, array){
      	return item * 2
      })
      console.log(mapResult) // [2, 4, 6, 8, 10, 8, 6, 4, 2]
      
      numbers.forEach(function(item, index, array){
      	// 执行操作
      })
      	
      
    • 缩小方法

      以下共同:
      参数:(每一项上调用的函数(前一个值,当前值,项的索引,数组对象),(可选的)作为缩小基础的初始值)
      args: (function(prev, cur, index, array){}, (not must)origin)
      迭代数组所有项,然后构建一个最终返回的值

      reduce()

      reduceRight()

      	var values = [1, 2, 3, 4, 5]
      	var sum = values.reduce(function(prev, cur, index, array){
      		// 上一项的结果作为prev参与本次操作
      		return prev + cur
      	})
      	console.log(sum) // 15
      
  4. Date类型

    Date类型保存的日期能够精确到 1970年1月1日之前或之后的285 616

    • 创建方法与内置函数

      	// 不传递参数时,新创建对象自动获取当前日期和时间
      	// 传入表示该日期的毫秒数时,根据特定日期和时间创建日期对象
      	var now = new Date()
      	
      	// 1.Date.parse()
      	/**参数几种日期格式:
      	
      	 * 月/日/年: 6/13/2004
      	 * 
      	 * 英文月 日,年: January 12,2004
      	 * 
      	 * 英文星期几 英文月 日 年 时:分:秒 
      	 * 时区: Tue May 25 2004 00:00:00 GMT-0700
      	 * 
      	 * ISO 8610 扩展格式 YYYY-MM-DDTHH:mm:ss:sssZ 
      	 * 如2004-05-25T00:00:00
      	 * **/
      	
      	// 为2004年5月25日创建一个日期对象
      	
      	var someDate = new Date(Date.parse('May 25, 2004'))
      	
      	// 如果不用Date.parse()后台会调用函数直接转
      	
      	var someDate = new Date('May 25, 2004')
      
      	// 2.Date.UTC()
      	// 参数:((必需)年份,(必需)月份(0-11),日(1-31),
      	// 小时(0-23),分钟,秒,毫秒)
      	
      	// 基于GMT格林威治标准时间
      	// GMT时间 2000年1月1日0时
      	var y2k = new Date(Date.UTC(2000, 0))
      	
      	// GMT时间 2005年5月5日17时55分55秒
      	var allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55))
      	
      	// 基于系统设置的本地时间
      	// 本地时间 2000年1月1日0时
      	var y2k = new Date(2000, 0)
      	
      	// 本地时间 2005年5月5日17时55分55秒
      	var allFives = new Date(2005, 4, 5, 17, 55, 55)
      	
      	// 3.Date.now()
      	// 返回表示调用该方法的日期和时间的毫秒数
      	
      	var start = Date.now()
      	doSomething()
      	var stop = Date.now(),
      		result = stop - start
      		
      	// 使用+操作符将Date对象转换成字符串与上结果相同
      	var start = +new Date()
      	doSomething()
      	var stop = +new Date(),
      		result = stop - start
      	
      
    • 继承方法

      Date类型重写了toLocalString(),toString(),valueOf()方法

      	// 1.toLocalString()与toString()在不同浏览器中得到的时间格式大相径庭
      	// 2.valueof()返回日期的毫秒表示,可用来比较日期
      	
      	var date1 = new Date(2007, 0, 1)
      	var date2 = new Date(2007, 1, 1)
      	
      	console.log(date1 < date2) // true
      
    • 其他方法

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GyLAMW3K-1591014360290)(./img/日期格式化方法.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FX2W5eoe-1591014360294)(./img/日期时间组件方法.png)]

  5. RegExp类型

    • 创建语法(Perl)

      1. 字面量形式
      	var expression = /pattern/flags
      

      flags: g(全局)/i(不区分大小写)/m(多行)

    • 实例

      	/*
      	 * 匹配字符串中所有'at'
      	 */
      	var pattern1 = /at/g
      	
      	/*
      	 * 匹配第一个'bat'或'cat',不区分大小写 
      	 */
      	var pattern2 = /[bc]at/i
      	
      	/** 模式中使用的元字符必须转义
      	 *  元字符包括:
      	 *  ( ) [ ] { } \ ^ $ | ? * + .
      	 **/
      	 
      	 /*
      	  * 匹配第一个'[bc]at',不区分大小写
      	  */
      	 var pattern3 = /\[bc\]at/i
      	 
      	 /*
      	  * 匹配所有以'at'结尾的3个字符的组合,不区分大小写
      	  */
      	 var pattern4 = /.at/gi
      	 
      	 /*
      	  * 匹配所有'.at',不区分大小写
      	  */
      	 var pattern5 = /\.at/gi
      
    1. 构造函数形式
      参数:(要匹配的字符串模式,可选的标志字符串)

      	var pattern = new RegExp('[bc]at', 'i')
      	
      	// 等价于
      	var pattern = /[bc]at/i
      	
      	/**示例
      	 * 字面量形式
      	 * /\[bc\]at/
      	 * 等价的字符串(所有元字符需要双重转义)
      	 * '\\[bc\\]at'
      	 *
      	 * /\.at/
      	 * '\\.at'
      	 *
      	 * /name\/age/
      	 * 'name\\/age'
      	 *
      	 * /\d.\d(1, 2)/
      	 * '\\d.\\d(1, 2)'
      	 *
      	 * /\w\\hello\\123/
      	 * '\\w\\\\hello\\\\123'
      	 *
      	 * */
      
      	// **字面量与构造函数创建正则的不同:**
      	// ECMAScript3中,正则表达式字面量始终会共享同一个RegExp实例,而使用构造函数创建的每个新RegExp都是一个新实例
      	// ECMAScript5明确规定,使用正则表达式字面量必须像直接调用RehExp构造函数一样,每次都创建新的实例
      	var re = null
      		i
      	for(i = 0; i < 10; i++){
      		re = /cat/g
      		re.test('catastrophe')
      	}
      	
      	for(i = 0; i < 10; i++){
      		re = new RegExp('cat', 'g')
      		re.test('catastrophe')
      	}
      	
      	
      
    2. RegExp实例属性

      RegExp的每个实例都具有下列属性,通过这些属性可以取得有关模式的各种信息

      global: 布尔值,表示是否设置了g标志
      ignoreCase: 布尔值,表示是否设置了i标志
      lastIndex: 整数,表示开始搜索下一个匹配项的字符位置,从0算起
      multiline: 布尔值,表示是否设置了m标志
      source: 正则表达式的字符串表示,按照字面量的字符串模式返回

      	var pat = /\[bc\]at/i
      	
      	console.log(pat.global) // false
      	console.log(pat.ignoreCase) // true
      	console.log(pat.multiline) // false
      	console.log(pat.lastIndex) // 0
      	console.log(pat.source) // '\[bc]\at'
      	
      	var pat2 = new RegExp('\\[bc\\]at', 'i')
      	
      	console.log(pat2.global) // false
      	console.log(pat2.ignoreCase) // true
      	console.log(pat2.multiline) // false
      	console.log(pat2.lastIndex) // 0
      	console.log(pat2.source) // '\[bc]\at'
      
    3. RegExp实例方法

      exec()
      参数:(要应用模式的字符串)
      返回的数组是Array实例,包含index(表示匹配项在字符串中的位置)和input(表示应用正则表达式的字符串)属性

      test()
      参数:字符串

      				// 1.exec()
      		
      		var text = 'mom and dad and baby'
      		var pattern = /mon( and dad( and baby)?)?/gi
      		
      		var matches = pattern.exec(text)
      		console.log(matches.index) // 0
      		console.log(matches.input) // 'mon and dad and baby'
      		console.log(matches[0]) // 'mon and dad and baby'
      		console.log(matches[1]) // 'and dad and baby'
      		console.log(matches[2]) // 'and baby'
      		
      		// 对于exec()而言
      		// 即使在模式中设置了全局标志(g)它每次也只会返回一个匹配项
      		var text = 'cat, bat, sat, fat'
      		var pattern1 = /.at/
      		
      		var matches = pattern1.exec(text)
      		console.log(matches.index) // 0
      		console.log(matches.[0]]) // cat
      		console.log(pattern1.lastIndex) // 0
      		
      		matches = pattern1.exec(text)
      		console.log(matches.index) // 0
      		console.log(matches.[0]]) // cat
      		console.log(pattern1.lastIndex) // 0
      		
      		var pattern2 = /.at/g
      		
      		var matches = pattern2.exec(text)
      		console.log(matches.index) // 0
      		console.log(matches.[0]]) // cat
      		console.log(pattern2.lastIndex) // 0
      		
      		matches = pattern2.exec(text)
      		console.log(matches.index) // 5
      		console.log(matches.[0]]) // bat
      		console.log(pattern2.lastIndex) // 8
      		
      		// 2.test()
      		
      		var text = '000-00-0000'
      		var pattern = /\d{3}-\d{2}-\d{4}/
      		
      		if (pattern.test(text)) {
      			console.log('The pattern was matched.')
      		}
      		
      		// RegExp实例继承的toLocalString()和toString()方法
      		// 都会返回正则表达式字面量与创建正则表达式方式无关
      		var psttern = new RegExp('\\[bc\\]at', 'gi')
      		console.log(pattern.toString()) // /\[bc\]at/gi 
      		console.log(pattern.toLocalString()) /\[bc\]at/gi
      		// 正则表达式的valueOf()方法返回正则表达式本身
      
      1. RegExp构造函数属性
        • RegExp构造函数属性
长属性名短属性名说明
input$_最近一次要匹配的字符串
lastMatch$&最近一次的匹配项
lastParen$+最近一次匹配的捕获组
leftContext$`input字符串中lastMatch之前的文本
multiline$*布尔值,表示是否所有表达式都使用多行模式
rightContext$’input字符串中lastMatch之后的文本

捕获组是用()圈起来的

		var text = 'this has been a short summer'
		var pattern = /(.)hort/g
		
		/* *
		 * 注意:
		 * Opera不支持 input lastMatch lastParen multiline 属性
		 * IE不支持multiline属性
		 * 
		 * */
		 if (pattern.test(text)) {
			console.log(RegExp.input) // this has been a short summer
			console.log(RegExp.leftContext) // this has been a
			console.log(RegExp.rightContext) // summer
			console.log(RegExp.lastMatch) // short
			console.log(RegExp.lastParen) // s
			console.log(RegExp.multiline) // false
		 }
		 
		 // 这些短属性名大多不是有效ECMAScript标识符
		 // 因此必须通过方括号语法来访问它们 
		 var text = 'this has been a short summer'
		 var pattern = /(.)hort/g
		 
		/* *
		 * 注意:
		 * Opera不支持 input lastMatch lastParen multiline 属性
		 * IE不支持multiline属性
		 * 
		 * */
		 if (pattern.test(text)) {
			 console.log(RegExp.$_)
			 console.log(RegExp["$`"]) // (input)
			 console.log(RegExp["$'"]) // (leftContext)
			 console.log(RegExp["$&"]) // (rightContext)
			 console.log(RegExp["$+"]) // (lastMatch)
			 console.log(RegExp["$*"]) // (multiline)
		 }
  • 捕获组的构造函数属性
    RegExp.$1、RegExp.$2……RegExp.$9分别存储第一、第二……第九个匹配的捕获组

    	// 包含两个捕获组
    	var text = 'this has been a short summer'
    	var pattern = /(..)or(.)/g
    	
    	if (pattern.test(text)) {
    		console.log(RegExp.$1) // sh
    		console.log(RegExp.$2) // t
    	}
    
      	补充:
      	1. 支持以插入符号(^)来匹配字符串的开始
      	2. 支持以插入符号($)来匹配字符串的结尾
      	3. 完全支持向前查找
      	4. 支持编号的捕获组
    
  1. Function类型
    1. 函数实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法

      	// 1.使用函数声明语法定义
      	function sum(num1, num2) {
      		return num1 + num2
      	}
      	// 2.使用函数表达式定义
      	var sum = function(num1, num2) {
      		return num1 + num2
      	}
      	// 3.使用Function构造函数定义(不推荐)
      	// 参数:(参数一,参数二……参数N,函数体)
      	// 可以用来理解“函数是对象,函数名是指针”
      	var sum = new Function('num1', 'num2', 'return num1 + num2')
      	
      	// 因为函数名仅仅是指向函数的指针,一个函数可能会有多个名字
      	function sum(num1, num2) {
      		return num1 + num2
      	}
      	console.log(sum(10, 10))        // 20
      	
      	// 使用不带圆括号的函数名是访问函数指针
      	var anotherSum = sum 
      	console.log(anotherSum(10, 10)) // 20
      	
      	sum = null
      	console.log(anotherSum(10, 10)) // 20
      
    2. 函数覆盖

      	function addSomeNumber(num) {
      		return num + 100
      	}
      	function addSomeNumber(num) {
      		return num + 200
      	}
      	console.log(addSomeNumber(100)) // 300
      	
      	// 相当于
      	var addSomeNumber = function(num) {
      		return num + 100
      	}
          addSomeNumber = function(num) {
      		return num + 200
      	}
      	console.log(addSomeNumber(100)) // 300
      	
      
    3. 函数声明和函数表达式的区别

      解析器会率先读取函数声明,并使其在执行任何代码之前可以访问;

      函数表达式要等到解析器执行到它所在的代码行,才会被真正执行。

      	// 可以正常执行
      	// 因为在执行sum(10, 10)这条语句之前,
      	// 解析器就已经通过一个名为函数声明提升的过程,
      	// 读取并将函数声明添加到执行环境中。
      	
      	console.log(sum(10, 10))
      	function sum(num1, num2){
      		return num1 + num2
      	}
      	
      	// 报错 
      	console.log(sum(10, 10))
      	var sum = function(num1, num2) {
      		return num1 + num2
      	}
      	
      	// 除此之外,函数声明与函数表达式的语法是等价的
      
    4. 作为值的函数

      函数名本身就是变量,所以函数也可以作为值使用:

      1.当作参数把一个函数传递给另一个函数

      2.将一个函数作为另一个函数的结果返回

      当作参数把一个函数传递给另一个函数

      	// 通用的callSomeFunction()函数
      	function callSomeFunction(someFunction, someArgument){
      		return someFunction(someArgument)
      	}
      	
      	function add10(num) {
      		return num + 10
      	}
      	
      	// add10 而不是 add10() 因为要访问函数的指针而不执行函数add10
      	var result1 = callSomeFunction(add10, 10)
      	console.log(result1) // 20
      	
      	function getGreeting(name) {
      		return 'Hello, ' + name
      	}
      	
      	var result2 = callSomeFunction(getGreeting, 'Nike')
      	console.log(result2) // 'Hello, Nike'
      

      将一个函数作为另一个函数的结果返回
      这个实例可以多看一下,有点复杂

      	function createComparisonFunction(propertyName){
      		
      		return function(object1, object2){
      			var value1 = object1[propertyName]
      			var value2 = object2[propertyName]
      			
      			if (value1 < value2) {
      				return -1
      			} else if (value1 > value2) {
      				return 1
      			} else {
      				return 0
      			}
      		};
      	}
      	
      	var data = [{
      		name: 'zara',
      		age: 28
      	},{
      		name: 'Nike',
      		age: 29
      	}]
      	
      	data.sort(createComparisonFunction('name'))
      	console.log(data[0].name) // Nike
      	
      	data.sort(createComparisonFunction('age'))
      	console.log(data[0].name) // Zara
      
    5. 函数内部属性

      arguments
      1.是一个类数组对象,包含传入函数中的所有参数
      2.该对象有一个叫做callee的属性,是一个指针,指向拥有这个arguments对象的函数
      this
      1.引用的是函数据以执行的环境对象
      caller
      1.这个属性保存着调用当前函数的函数的引用
      2.如果是在全局作用域中调用当前函数,它的值为null

      arguments

      	function factorial(num) {
      		if (num <= 1) {
      			return 1
      		} else {
      			return num * factorial(num-1)
      		}
      	}
      	
      	// 函数的执行与函数名factorial紧紧耦合在了一起
      	// 为了消除耦合用到arguments.callee
      
      	function factorial(num) {
      		if (num <= 1) {
      			return 1
      		} else {
      			return num * arguments.callee(num-1)
      		}
      	}
      	
      	// 这样无论引用函数时使用什么名字,都可以保证正常完成递归调用
      	// 例如
      	function trueFactorial = factorial
      	
      	factorial = function(){
      		return 0
      	}
      	
      	console.log(trueFactorial(5)) // 120
      	console.log(factorial(5)) // 0
      	// 这样即使函数名变了,递归时调用的是函数的指针,
      	// 而不会像 factorial 函数 return 0 那样被覆盖
      

      this

      	window.color = 'red'
      	var o = {color: 'blue'}
      	
      	function sayColor() {
      		console.log(this.color)
      	}
      	
      	sayColor() // 'red'
      	
      	o.sayColor = sayColor
      	o.sayColor() // 'blue'
      

      caller

      	function outer() {
      		inner()
      	}
      	
      	function inner() {
      		console.log(inner.caller)
      	}
      	
      	outer() // 显示outer()函数的源代码
      	
      	// 实现更松散的耦合
      	function outer() {
      		inner()
      	}
      	
      	function inner() {
      		// ECMAScript5定义arguments.callee在严格模式下报错,
      		// 非严格模式下为undefined
      		console.log(arguments.callee.caller)
      	}
      	
      	outer()
      
    6. 函数属性和方法

      1.ECMAScript中函数是对象因此也有其属性和方法

      2.每个函数都包含两个属性:
      length(表示函数希望接收的命名参数的个数)
      prototype

      3.每个函数都包含两个非继承而来的方法
      他们的用途:传递参数/扩充函数赖以运行的作用域
      在特定作用域中调用函数(实际上等于设置函数体内this对象的值)
      apply()
      参数:(在其中运行函数的作用域,参数数组)参数数组可以是Array实例也可以是arguments对象
      call()
      参数:逐个传
      bind()
      会创建一个函数实例,其this值会被绑定到传给bind()函数的值

      length

      	function sayName(name) {
      		console.log(name)
      	}
      	function sum(num1, num2) {
      		return num1 + num2
      	}
      	function sayHi() {
      		console.log('hi')
      	}
      	
      	console.log(dayName.length) // 1
      	console.log(sum.length) // 2
      	console.log(sayHi.length) // 0
      

      当它们的作用是传递参数时:
      apply()

      	function sum(num1, num2) {
      		return num1 + num2
      	}
      	
      	function callSum1 (num1, num2) {
      		// this在其中运行环境的作用域
      		return sum.apply(this, arguments)
      	}
      	
      	function callSum2 (num1, num2) {
      		return sum.apply(this, [num1, num2])
      	}
      	
      	console.log(callSum1(10, 10)) // 20
      	console.log(callSum2(10, 10)) // 20
      	// 严格模式下未指定环境对象调用函数,this不会自动转型为window
      

      call()

      	// call()与apply()不同的地方在于传递给函数的参数必须逐个列举出来
      	function sum(num1, num2) {
      		return num1 + num2
      	}
      	function callSum(num1, num2) {
      		return sum.call(this, num1, num2)
      	}
      	console.log(callSum(10, 10)) // 20
      

      当它们的作用是扩充赖以运行的作用域时:
      好处是对象与对象不需要与方法有任何耦合关系

      	window.color = 'red'
      	var o = {color: 'blue'}
      	
      	function sayColor() {
      		console.log(this.color)
      	}
      	
      	sayColor() // red
      	
      	sayColor.call(this) // red
      	sayColor.call(window) // red
      	sayColor.call(o) // blue
      

      bind()

      	window.color = 'red'
      	var o = {color: 'blue'}
      	
      	function sayColor() {
      		console.log(this.color)
      	}
      	
      	var objectSayColor = sayColor.bind(o)
      	objectSayColor() // blue
      	
      

二、基本包装类型

  1. Boolean类型
    注意:布尔表达式中所有对象都会被转换为true
    建议:永远不要使用Boolean对象
    基本类型与引用类型的布尔值区别一:

    	// 创建布尔对象
    	var booleanObject = new Boolean(true)
    	/**
    	 * 重写valueOf()方法,返回基本类型值 true 或 false
    	 * 重写toString()方法,返回字符串 "true" 或 "false" 
    	 */
    	// 不推荐用Boolean因为会造成误解
    	var falseObject = new Boolean(false)
    	// 这行代码是对falseObject而不是它的值(false)进行求值
    	var result = falseObject && true 
    	console.log(result) // true
    	
    	var falseValue = false
    	result = falseValue && true
    	console.log(result) // false
    	
    

    基本类型与引用类型的布尔值区别二:

    	/* *
    	 * typeof操作符对基本类型返回'boolean'
    	 * 对引用类型返回'object'
    	 * 
    	 * instanceof操作符测试Boolean对象返回 true
    	 * 对基本类型的布尔值返回false
    	 * */
    	console.log(typeof falseObject) // object
    	console.log(typeof falseValue) // boolean
    	console.log(falseObject instanceof Boolean) // true
    	console.log(falseValue instanceof Boolean) // false
    
  2. Number类型
    建议:不要直接实例化Number类型

    	// 	创建Number对象
    	var numberObject = new Number(10)
    	
    	/* *
    	 * 重写 valueOf() 方法返回对象表示的基本类型的数值
    	 * toLocaleString() 和 toString() 方法返回字符串形式的数值
    	 * */
    	 
    	 // 为toString()方法传递一个基数,返回该基数进制的字符串形式
    	 var num = 10
    	 console.log(num.toString()) // '10'
    	 console.log(num.toString(2)) // '1010'
    	 console.log(num.toString(8)) // '12'
    	 console.log(num.toString(10)) // '10'
    	 console.log(num.toString(16)) // 'a'
    	 
    	 // 将数值格式化为字符串
    	 
    	 // toFixed()方法
    	 // 按照指定的小数位返回数值的字符串表示
    	 var num = 10
    	 console.log(num.toFixed(2)) // '10.00'
    	 
    	 var num = 10.005
    	 console.log(num.toFixed(2)) // '10.01' (自动舍入)
    	 
    	 // toExponential()方法
    	 // 返回以指数表示法表示的数值的字符串形式,其他同toFixed()
    	 var num = 10
    	 console.log(num.toExponential(1)) // '1.0e+1'
    	 
    	 // toPrecision()方法
    	 // 相当于,根据传入参数数值判断用toFixed()还是toExponential()
    	 // 可以表现1到21位小数
    	 var num = 99
    	 console.log(num.toPrecision(1)) // '1e+2'
    	 console.log(num.toPrecision(2)) // '99'
    	 console.log(num.toPrecision(3)) // '99.0'
    	 
    

    typeof 和 instanceof 操作符测试基本类型数值和引用类型数值时,会得到不同结果

    	var numberObject = new Number(10)
    	var numberValue = 10
    	// typeof是判断引用类型的
    	// instanceof是判断引用类型中指定类型的
    	console.log(typeof numberObject) // 'object'
    	console.log(typeof numberValue)  // 'number'
    	console.log(numberObject instanceof Number) // true
    	console.log(numberValue instanceof Number) // false
    
  3. String类型

    	// 创建
    	var stringObject = new String('hello world')
    	
    	// 同样继承了valueOf(),toLocaleString()和toString()方法
    	
    	// length属性
    	var stringValue = 'hello world'
    	// 即使字符串中包含双字节字符(不是占一个字节的ASCII字符),
    	// 每个字符也仍算一个字符
    	console.log(stringValue.length) // '11'
    
    • 字符方法:

    访问字符串中的特定字符:
    参数:都为基于0的字符位置

    charAt()

    charCodeAt()

    	// 得到字符
    	var stringValue = 'hello world'
    	console.log(stringValue.charAt(1)) // 'e'
    	
    	// 得到字符编码
    	var stringValue = 'hello world'
    	console.log(stringValue.charCodeAt(1)) // '101'
    	
    	// 大部分浏览器可以用方括号语法(包括Chrome)
    	var stringValue = 'hello world'
    	console.log(stringValue[1]) // 'e'
    
    • 字符串操作方法:

    1.拼接:(不修改原值)
    可接受任意多个参数
    concat()

    2.三个基于子字符串创建新字符串的方法:(不修改原值)

    slice(指定子字符串开始位置,子字符串到哪里结束)

    substr(指定子字符串开始位置,返回的字符个数)

    substring(指定子字符串开始位置,子字符串到哪里结束)

    	// concat()
    	// 一般直接用+拼接
    	var stringValue = 'hello '
    	var result = stringValue.concat('world')
    	console.log(result) // 'hello world'
    	console.log(stringValue) // 'hello'
    	
    	var stringValue = 'hello'
    	var result = stringValue.concat('world', '!')
    	
    	console.log(result) // 'hello world!'
    	console.log(stringValue) // 'hello'
    	
    	// slice() substr() substring()
    	// slice() substring() 第二个参数是序号,substr()第二个参数是个数
    	var stringValue = 'hello world'
    	
    	console.log(stringValue.slice(3)) // 'lo world'
    	console.log(stringValue.substring(3)) // 'lo world'
    	console.log(stringValue.substr(3)) // 'lo world'
    	console.log(stringValue.slice(3, 7)) // 'lo w'
    	console.log(stringValue.substring(3, 7)) // 'lo w'
    	console.log(stringValue.substr(3, 7)) // 'lo worl'
    	
    	// 当参数为负数时:
    	// 当参数为负数,slice() substr() 一样
    	// 相当于加上字符串长度 substring()变成0
    	var stringValue = 'hello world'
    	
    	console.log(stringValue.slice(-3)) // 'rld'
    	console.log(stringValue.substring(-3)) // 'hello world'
    	console.log(stringValue.substr(-3)) // 'rld'
    	console.log(stringValue.slice(3, -4)) // 'lo w' 
    	// (相当于substring(0, 3))
    	console.log(stringValue.substring(3, -4)) // 'hel' 
    	console.log(stringValue.substr(3, -4)) // ''
    
    • 字符串位置方法

    参数:(指定字符,从哪个位置开始搜索)

    indexOf()

    lastIndexOf()

    	var stringValue = 'hello world'
    	console.log(stringValue.indexOf('o')) // 4
    	console.log(stringValue.lastIndexOf('o')) // 7
    	
    	console.log(stringValue.indexOf('o', 6)) // 7
    	console.log(stringValue.lastIndexOf('o', 6)) // 4
    	
    	// 将找到的序号全部推进数组
    	var stringValue = 'Lorem ipsum dolor ait amet, consectetur adipisicing elit'
    	var positions = new Array()
    	var pos = stringValue.indexOf('e')
    	
    	while (pos > -1) {
    		positions.push(pos)
    		pos = stringValue.indexOf('e', pos + 1)
    	}
    	console.log(positions) // '3, 24, 32, 35, 52'
    
    • 删除空格

    trim()

    trimLeft()

    trimRight()

    	var stringValue = '   helo world   '
    	var trimmedStringValue = stringValue.trim()
    	console.log(stringValue) // '   helo world   '
    	console.log(trimmedStringValue) // 'helo world'
    
    • 大小写转化方法

    toLowerCase()
    toLocaleLowerCase()
    toUpperCase()
    toLocaleUpperCase()
    使用:
    string.toLowerCase()

    • 模式匹配方法

    match()
    本质上与RegExp的exec()
    P 127

三、单体内置对象

  1. Global对象
  • URI编码方法

encodeURI(url)
decodeURI(url)
只转义空格

encodeURIComponent(url)
decodeURIComponent(url)
转义任何非标准字符

  • eval()方法
  • Global对象的属性

明确禁止给undefined,NaN和Infinity赋值

  • window对象
    1. 扮演ECMAScript规定的Global对象的角色等
    2. 获取Global对象的方法:
    	var global = function () {
    		return this
    	}
    
  1. Math对象
  • Math对象的属性(代表了很多计算用的特殊值)
  • min()和max()方法
   var max = Math.max(3, 54, 32, 16)
   console.log(max) // 54
   
   var values = [1, 2, 3, 4]
   var max = Math.max.spply(Math, values)
  • 舍入方法

Math.ceil() 向大舍入

Math.floor() 向小舍入

Math.round() 四舍五入

例:console.log(Math.ceil(25.9)) // 26

  • random()方法

公式:值 = Math.floor(Math.random()*可能值的个数 + 第一个可能的值)
例:随机颜色值

   function selectForm(lowerValue, upperValue) {
   	var chioes = upperValue = lowerValue + 1
   	return Math.floor(Math.random() * chioes + lowerValue)
   }
   
   var num = selectForm(2, 10)
   console.log(num) // (介于2和10之间的随机数)
   
   // 随机颜色
   var colors = ['red', 'green', 'blue']
   var color = colors[selectForm(0, colors.length-1)]
   console.log(color)
  • 其他方法

四、遇到过的实际问题

1.判断一个对象是否为空:

	// 方法一
	// ES6的 Object.keys() 方法
	// 返回值是对象中属性名组成的数组
	var obj1 = {}
	console.log(Object.keys(obj1).length) // 0(数字类型)
	// 方法二
	// 将对象转成json字符串
	// 当空对象的时候转换后的字符串长度为2
	var obj1 = {}
	console.log(JSON.stringify(obj1).length) // 2(字符串类型)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值