重学JS-第五章引用类型

144 阅读11分钟

1Object类型

创建:Object构造函数,对象字面量,函数封装

对象字面量定义对象时,不会调用Object构造函数

var obj = {}  
obj.__proto__ = Object.prototype
obj instanceof  Object    //true

Js 引擎把{}解析为对像(并不是构建函数), 并把这个对像的 __proto__ 指向 Object.prototype;

原型对象上的属性:

constructor

原型对象上的方法:

hasOwnProperty

isPrototypeOf

propertyIsEnumerable

toLocaleString

var sd=new Date()console.log(sd)  //Wed Feb 15 2017 11:21:31 GMT+0800 (CST)console.log(sd.toLocaleString())  //"2017/2/15 上午11:21:31"console.log(sd.toString())   //"Wed Feb 15 2017 11:21:31 GMT+0800 (CST)"

toString
valueOf

js对象中的valueOf()方法和toString()方法非常类似,但是,当需要返回对象的原始值(重点)而非字符串的时候才调用它,尤其是转换为数字的时候。如果在需要使用原始值的上下文中使用了对象,JavaScript就会自动调用valueOf()方法。
valueOf()方法是Object的原型方法,每个对象都具有该方法,但是各对象返回的值有一定的区别。
String.prototype.valueOf()
语法:strObj.valueOf() 返回值:表示给定String对象的原始值
说明:valueOf()方法返回一个String对象的原始值,该值等同于String.prototype.toString()
该方法通常在JavaScript内部被调用,而不是在代码里显示调用。
Date.prototype.valueOf()
语法:dataObj.valueOf() 返回值:表示给定Date对象的原始值
说明:valueOf()方法返回以数值格式表示的一个Date对象的原始值。该值从1970年1月1日0时0分0秒(UTC,即协调世界时)到该日期对象所代表时间的
毫秒数。

Boolean.prototype.valueOf()

返回布尔对象原始值

2Array类型

数组每一项都可以保存任何类型的数据

数组大小是可以动态调整的

创建数组

两种方式

new Array()
数组字面量

注意:避免以下写法

let arr = [1,2,]   //在IE8及以前,会创建1,2,undefined长度为3的数组;其他浏览器创建长度为2的数组

length

length属性不是只读的,可以通过改变length,增减数组元素(新增默认undefined)

通过length在数组末尾添加新项

arr[arr.length] = 'newarr'

检测数组

instanceof

缺点:项目中由于使用多框架,会有多个全局环境(多个Object基类),检测会出现问题

ES5新增:Array.isArray(value)

数组转换

toLocalString()

toString()

valueOf()

join(分割字符)   不给join传参,默认用逗号拼接数组

数组的栈方法(后进先出)

push()压栈   pop()弹栈

数组的队列方法(先进先出)

shift()出队  unshift()入队

数组重排序

sort() reverse()

修改compare函数,升序
function compare(value1,value2){
    retutrn value1-value2
}

操作数组

concat()  数组拷贝,添加;返回一个数组,深拷贝(不改变原数组)

var arr = [4,6,8,2,10]
var arr2 = arr.concat()
// var arr3 = arr.concat('a',[1,'6'])   // [4,  6,   8, 2, 10, 'a', 1, '6']
console.log(arr2 === arr)  // false

slice()  数组截取;返回一个数组,(不改变原数组)

含左不含右

var arr = [4,6,8,2,10]console.log(arr.slice(3,4))   //[2]
console.log(arr.slice(-2,-1))  //[2]

splice() 数组删除、插入、替换;返回一个数组,(改变原数组)

删除(删除前两项)

arr.splice(0,2)

插入(起始位置,0,要插入的若干项)

var arr = [4,6,8,2,10]
arr.splice(2,0,'aaa','bbb')  //从数组第二位开始,插入两项
console.log(arr)    //[ 4, 6, 'aaa', 'bbb', 8, 2, 10 ] 

修改(起始位置,修改项数,若干项)

数组位置方法

indexOf()

lastIndexOf()

在查找时,要求严格相等

没找到返回-1

可以指定从哪个位置开始查找

迭代方法

every()

some()

var arr = [4,6,8,2,10,12,4]
var everyResult = arr.every(function (item,index,array) {    
    return item>1})
console.log(everyResult)   //数组中每个数都大于1,true
var someResult = arr.some((item,index,array)=>{   
 return item>11})
console.log(someResult) //数组中有12>11,返回true

filter()  不改变原数组

语法:array.filter(function(currentValue,index,arr), thisValue)

数组去重

let arr = [1, 2, 3, 2, 3, 4]
let arrFilter = [...new Set(arr)]
console.log(arrFilter)
let arr = [1, 2, 3, 2, 3, 4]
let arrFilter = arr.filter((ele, index, arr) => {  
    return arr.indexOf(ele) === index
})
console.log(arrFIlter)

删除空串

1 var arr = ['A', '', 'B', null, undefined, 'C', '  '];
2 var r = arr.filter(function (s) {
3     return s && s.trim(); // 注意:IE9以下的版本没有trim()方法
4 });
5 r; // ['A', 'B', 'C']

过滤奇数偶数

1 var arr = [1, 2, 4, 5, 6, 9, 10, 15];
2 var r = arr.filter(function (x) {
3     return x % 2 !== 0;
4 });
5 r; // [1, 5, 9, 15]

forEach()   进行数组遍历

myArray.forEach(function (value,index,self) {
  console.log(value);
});

没有返回值

不能中断循环(使用break语句或使用return语句)

          for of

for (var value of myArray) {
  console.log(value);
}

          for in

var obj = {a:1, b:2, c:3};

for (var prop in obj) {
  console.log("obj." + prop + " = " + obj[prop]);
}

map()

var mapResult = arr.map(function (item,index,array) {    return item*2})console.log(mapResult)

归并方法

reduce()  reduceRight()

语法

arr.reduce(function(prev,cur,index,arr){...}, init);
**arr** 表示原数组; **prev** 表示上一次调用回调时的返回值,或者初始值 init; **cur** 表示当前正在处理的数组元素; **index** 表示当前正在处理的数组元素的索引,若提供 init 值,则索引为0,否则索引为1; **init** 表示初始值。

例子

var arr = [3,9,4,3,6,0,9];

**求数组多项和**
var sum = arr.reduce(function (prev, cur) {
    return prev + cur;
},0);

由于传入了初始值0,所以开始时prev的值为0,cur的值为数组第一项3,相加之后返回值为3作为下一轮回调的prev值,然后再继续与下一个数组项相加,以此类推,直至完成所有数组项的和并返回。

求数组项最大值

var max = arr.reduce(function (prev, cur) {
    return Math.max(prev,cur);
});

由于未传入初始值,所以开始时prev的值为数组第一项3,cur的值为数组第二项9,取两值最大值后继续进入下一轮回调。

数组去重

var newArr = arr.reduce(function (prev, cur) {
    prev.indexOf(cur) === -1 && prev.push(cur);
    return prev;
},[]);
**数组去重解析:**
① 初始化一个空数组 ② 将需要去重处理的数组中的第1项在初始化数组中查找,如果找不到(空数组中肯定找不到),就将该项添加到初始化数组中 ③ 将需要去重处理的数组中的第2项在初始化数组中查找,如果找不到,就将该项继续添加到初始化数组中 ④ …… ⑤ 将需要去重处理的数组中的第n项在初始化数组中查找,如果找不到,就将该项继续添加到初始化数组中 ⑥ 将这个初始化数组返回

3Date类型

var start = new Date()
console.log('hello')
var end = new Date()
console.log(end-start)  //5

now()   ES5新增

parse()

4RegExp类型

g全局模式,i不分大小写,m多行匹配

var pattern =  /[bc]at/i  // 匹配第一个bat或cat,不分大小写

构造函数

var pattern  = new RegExp("[bc]at","gi")

实例属性

global 布尔值,是否设置了g标志

ignoreCase 布尔值,是否设置i

multiline 布尔值,是否设置m

lastIndex 整数,表示从哪开始搜索,默认0

source 字符串,正则表达式的字符串表示

实例方法

exec()

test()

5Function类型

函数是对象,函数名是指针

var sum = new Function("num1","num2","return num1+num2")  //不推荐
这样写会解析两次代码,一次解析常规ES代码,一次解析传入构造函数中的字符串

5.1函数声明和函数表达式

函数声明:函数声明会有一个提升过程,并使其在执行任何代码之前可用

函数表达式:必须要等到解析器执行到所在的代码行,才能真正执行

5.2函数内部属性

arguments

    callee 该属性是一个指针,指向拥有该arguments的函数(可用于递归,严格模式禁用)

   caller  该属性非严格模式下始终是undefined,严格模式下报错

    类数组无法使用 forEach、splice、push 等数组原型链上的方法

this

    引用的是函数执行的环境对象

caller

function outer() {    
    inner()
}
function inner() {   
    console.log(inner.caller)  //[Function: outer]    
    console.log(arguments.callee.caller)  //[Function: outer]
}
outer()

5.3函数的外部属性和方法

属性

length 函数的参数个数

prototype 指向引用类型的原型

方法

apply()

   两个参数:一个是在其中运行的作用域(this,必传);一个是参数数组

call()

   不定参数:第一个是this(必传);其后是若干个参数,会传递给所调用者

上述两个函数的优点:扩充函数的执行作用域;对象不需要和方法有任何耦合关系;

IE9+开始支持bind()

   bind返回值是个函数,需要稍后调用;call和apply是立即调用

上述三个函数的同:

1、都是用来改变函数的this对象的指向的。
2、第一个参数都是this要指向的对象。
3、都可以利用后续参数传参。

call和apply都会改变函数执行时的上下文,调用 call 和 apply 的对象,必须是一个函数 Function;他们两个的区别主要体现在参数上。

**         call应用于继承**

function Animal(name){      
    this.name = name;      
    this.showName = function(){      
        alert(this.name);      
    }      
}    
function Cat(name){        
    Animal.call(this, name);    
 }      
 var cat = new Cat("Black Cat");     
 cat.showName(); 

6基本包装类型

三个特殊引用类型:Boolean,Number,String(操作基本类型值)

每当读取一个基本类型值的时候,后台就会_自动创建一个对应的基本类型包装对象_,去调用一些方法操作数据。

引用类型和基本包装类型的区别:

使用new创建的引用类型实例,在执行流离开当前作用域之前一直保存于内存中

自动创建的基本包装类型的对象,只存在于代码执行的瞬间,转瞬即逝

var s1 = 'red'
s1.color = 'blue'
console.log(s1.color)  //undefined

Object构造函数会像工厂一样,根据传入值返回相应的基本包装类型的实例

var obj1 = new Object('aaa')
console.log(obj2 instanceof String)   //true 验证构造函数的原型对象是否在实例的原型链上
var obj2 = new Object(11)
console.log(obj2 instanceof Number)   //true

转型函数和构造函数

var value = 25
var number = Number(value)
console.log(typeof number)  //number
var obj = new Number(value)
console.log(typeof obj) //object

6.1Boolean

基本包装类型Boolean,重写了valueOf,重写了toString

6.2Number类型

基本包装类型Number,重写了valueOf,重写了toString

Number类型提供的将数字转化为字符串的方法:

toFixed 按照指定小数位返回数值的字符串表示

toExoonential 指数表示

toPercision 

6.3String类型

每个实例都有length属性

字符方法

charAt(position)  返回所在位置的字符

charCodeAt(position)  输出的是字符编码

字符串操作

concat() 字符串拼接,不改变原有字符串

slice(num1,num2) 不改变原有字符串

substr(num1,num2) 不改变原有字符串

substring(num1,num2) 不改变原有字符串

例子:

字符串位置方法

indexOf()

lastIndexOf()

去除首尾空格

trim() 不改变原有字符串

大小写转换

toLowerCase()

toUpperCase()

字符串匹配方法

match()

replace()

split()

字符串比较

localeCompare()

var s = 'yellow';
console.log(s.localeCompare('bbb'));  // 1
console.log(s.localeCompare('yyy'));  // -1
console.log(s.localeCompare('yellow'));  // 0
console.log(s.localeCompare('zzz'));  // -1

将字符串编码返回为字符串

fromCharCode
console.log(String.fromCharCode(104,101,108))  //hel

7单体内置对象

不依赖于宿主环境,在程序执行前就已经存在

Global

(没人要的,都是我的)

所有在全局作用域中定义的属性和函数,都是Global对象的属性

isNaN isFinite parseInt 等都是Global对象的方法

其他方法:

URI编码

统一资源标志符URI就是在某一规则下能把一个资源独一无二地标识出来。
拿人做例子,假设这个世界上所有人的名字都不能重复,那么名字就是URI的一个实例,通过名字这个字符串就可以标识出唯一的一个人。
现实当中名字当然是会重复的,所以身份证号才是URI,通过身份证号能让我们能且仅能确定一个人。
那统一资源定位符URL是什么呢。也拿人做例子然后跟HTTP的URL做类比,就可以有:
动物住址协议://地球/中国/浙江省/杭州市/西湖区/某大学/14号宿舍楼/525号寝/张三.人
可以看到,这个字符串同样标识出了唯一的一个人,起到了URI的作用,所以URL是URI的子集。URL是以描述人的位置来唯一确定一个人的。
在上文我们用身份证号也可以唯一确定一个人。对于这个在杭州的张三,我们也可以用:
身份证号:123456789 来标识他。
所以不论是用定位的方式还是用编号的方式,我们都可以唯一确定一个人,都是URl的一种实现,而URL就是用定位的方式实现的URI。

encodeURI  主要用于整个URI,不会对本身属于URI的特殊字符编码

encodeURIComponent  主要用于URI中的某一段,会对所有字符进行编码

decodeURI

decodeURIComponent  

对URI进行编码,解码

eval() 函数

用来执行一个字符串表达式,并返回表达式的值。

Global对象的属性

Global和window对象

在浏览器中,Global对象是window对象的一部分

Math

Math对象的属性

常用方法

min()

max()

获取数组的最大值

Math.max.apply(Math,arr)

ceil()

floor()

round()

四舍五入

random()