Js的引用类型介绍

来源:转载

什么是引用类型?

引用类型的值(对象)是引用类型的一个实例。

是一种数据结构,用于将数据和功能组织在一起。

也称对象定义。它描述的是一类对象所具有的属性和方法。

引用类型有

Object类型,Array类型,Function三种

Object类型

概述

包含一系列属性,这些属性是无序的,每个属性都有一个字符串key和对应的value。如下
var obj = {x:1,y:2};obj.x; // 1obj.y; //2

注:键名不符合标识名的条件(比如第一个字符为数字,或者含有空格或运算符),则必须加上引号。

创建Object的方式

New操作符      var obj =  new Object();

对象字面量    varobj = {};

读取对象的方式

点表示法 和方括号表示法,如下:
var o = { p: 'Hello World' }; o.p // "Hello World" o['p'] // "Hello World"

写入对象的方式

同上,点表示法和方括号表示法,如下:
o.p = 'abc';o['p'] = 'abc';

注:使用方括号可以通过变量来访问属性。如果属性名中包含会导致语法错误的字符(空格 非字母非数字)。

属性的操作

Object.keys(object)方法:

查看对象本身的所有属性,返回一个字符串数组
var o = { key1: 1, key2: 2}; console.log(Object.keys(o)); // ['key1', 'key2']

使用delete:

属性的删除
var o = {p: 1}; Object.keys(o) // ["p"] delete o.p // true console.log(o.p); // undefined console.log(Object.keys(o)); // []

存在的问题:如果删除一个不存在的属性,delete不报错,而且返回true;delete命令只能用来保证某个属性的值为undefined,而无法保证该属性是否真的存在。只有一种情况,delete命令会返回false,那就是该属性存在,且不得删除。delete命令也不能删除var命令声明的变量,只能用来删除属性

in运算符:

用于检查对象是否包含某个属性(注意,检查的是键名,不是键值),如果包含就返回true,否则返回false。
var o = { p: 1 };'p' in o // true
存在的问题:它不能识别对象继承的属性。所以可以用以下方法:

var o = new Object(); o.hasOwnProperty('toString') // false 'toString' in o // true

for...in循环:

用来遍历一个对象的所有可enumberable(枚举)的属性

var o={ a:1, b:2, c:function(){ console.log(123); }}for (i in o) { console.log(o[i]);}; //1,2,function c()

对象的引用

如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量
var o1 = {};var o2 = o1;o1.a = 1;console.log(o2.a) // 1 o2.b = 2;console.log (o1.b) // 2
如果取消某一个变量对于原对象的引用,不会影响到另一个变量

var o1 = {};var o2 = o1;o1 = 1;console.log(o2) // {}

这种引用只局限于对象,对于原始类型的数据则是传值引用,也就是说,都是值的拷贝
var x = 1;var y = x;x = 2;console.log(y) // 1

Array类型

概述

数组中的每一项可以保存任何类型的数据,
var arr = [ {a: 1}, [1, 2, 3], function() { return true; } ];console.log(arr[0]);// Object {a: 1} console.log(arr[1]);// [1, 2, 3] console.log(arr[2]);// function (){return true;}
数组的大小可以动态调整等
var arr = new Array(10);

Array创建方式

new 操作符   var arr = new Array();数组字面量   var arr =[];

数组检测

instanceof操作符:

可用于确定某个对象是不是数组
var a = [1, 2, 3];a instanceof Array// true
存在问题:它假定只有一个全局执行环境

Array.isArray(color)方法:

检测变量是否为数组,不管其在那个全局执行环境中。
Array.isArray(a) // true

转换方法

valueOf()方法返回数组本身。toString()方法返回数组的字符串形式。join()方法:接收一个参数,用作分隔符的字符串,返回包含所有数组项的字符串
var a = [1, 2, 3];a.valueOf() // [1, 2, 3]a.toString() // "1,2,3"console.log(a.join(" , ")); // red,green,blue

处理方法

push()方法:

接收任意数量的参数,把他们逐个添加到数组的末尾,返回修改后数组的长度(原数组已经改变,生成了新的数组)
var a = [];console.log(a.push(1)); // 1 console.log(a.push('a') );// 2 console.log(a.push(true, {})); // 4 console.log(a); // [1, 'a', true, {}]

pop()方法:

从数组末尾移除最后一项,返回移除的项(原数组已改变,形成新的删除元素后的数组)
var a = ['a', 'b', 'c'];console.log(a.pop()); // 'c' console.log(a); // ['a', 'b']

unshift()方法:

在数组开头添加一个元素 返回新数组的长度,原数组已改变
var a = ['a', 'b', 'c'];console.log(a.unshift('x')); // 4 console.log(a); // ['x', 'a', 'b', 'c'] 

shift()方法:

删除数组开头的第一个元素,返回删除的元素,原数组已改变
var a = ['a', 'b', 'c'];console.log(a.shift() );// 'a' console.log(a); // ['b', 'c']

排序方法

reverse()方法:

反转数组项的顺序,原数组发生变化
var a = ['a', 'b', 'c'];a.reverse() ;a // ["c", "b", "a"]

sort()方法:

按升序排列数组项(sort()方法调用每个数组的toString()方法,然后比较得到的字符串,以确定如何排序,即使每一项都是数值,sort比较的也是字符串)
var values = [1,0,5,10,15];values.sort();console.log (values); //0,1,10,15,5
接下来是一个数组排序的例子:
function compare(value1, value2){ if(value1 > value2){return 1; }else if(value1 < value2){return -1; }else {return 0; }}var values = [1,0,5,10,15];values.sort(compare);console.log(values);//0,1,5,10,15

操作方法

concat()方法:

合并数组(创建了一个新数组,原数组不变)
[1, 2, 3].concat(4, 5, 6) // [1, 2, 3, 4, 5, 6]

如果不提供参数,concat方法返回当前数组的一个浅拷贝。指的是如果数组成员包括复合类型的值(比如对象),则新数组拷贝的是该值的引用。

var obj = { a:1 };var oldArray = [obj];var newArray = oldArray.concat();obj.a = 2;console.log(newArray[0].a); // 2

concat方法也可以用于将对象合并为数组,但是必须借助call方法。

[].concat.call({ a: 1 }, { b: 2 }) ; // [{ a: 1 }, { b: 2 }]

slice()方法:

用于提取原数组的一部分,返回一个新数组,原数组不变。•第一个参数为起始位置(从0开始),•第二个参数为终止位置(但该位置的元素本身不包括在内)。•如果省略第二个参数,则一直返回到原数组的最后一个成员。•如果接收的参数为负数,则用数组长度加上该参数来确定相应的位置•第二个参数小于第一个参数,则返回空数组。
var a = ['a', 'b', 'c'];a.slice(1,2) // ["b"]a.slice(1) // ["b", "c"]a.slice(-2) // ["b", "c"]a.slice(4) // []a.slice(2, 6) // ["c"]a.slice(2, 1) // []

splice()方法:

用于删除原数组的一部分成员,并可以在被删除的位置添加入新的数组成员。它的返回值是被删除的元素。该方法会改变原数组。•删除•参数一、从指定位置(下标)开始删除元素  •参数二、删除元素的个数
var a = ["a","b","c","d","e","f"];console.log(a.splice(4,2)) ;// ["e", "f"] console.log(a);//["a", "b", "c", "d"] 
•插入/替换•参数一、向指定位置插入  •参数二、要删除的项数  •参数三、要插入的元素(可以为多个项)
var a = ["a","b","c","d","e","f"]; console.log(a.splice(4,2,1,2) );// ["e", "f"] console.log(a); // ["a", "b", "c", "d", 1, 2]

位置方法

indexOf():

返回给定元素在数组中第一次出现的位置,如果没有出现则返回-1。•参数一、要查找的项•参数二、表示要查找的起点位置的索引(可选)
var a = ['a', 'b', 'c'];a.indexOf('b') // 1 a.indexOf('y') // -1a.indexOf('a', 1) // -1

lastIndexOf方法:

返回给定元素在数组中最后一次出现的位置

迭代方法:

every():数组项的每一个元素都满足则返回true,否则返回falsesome():数组项有一个元素满足则返回truefilter():对查询符合条件的所有数组项,返回一个数组(符合条件的元素)map():返回一个数组,而返回的数组的每一项都是在原始数组中的对应项上运行的传入函数的结果forEach():只是对数组中的每一项运行传入的函数,没有返回值,与for循环迭代数组一样
var number=[1,2,3,4,5,6,7,8,9];var every = number.every(function(item,index,array){ return item>2; })var some = number.some(function(item,index,array){ return item>2; })var filter = number.filter(function(item,index,array){ return item>2; });var map = number.map(function(item,index,array){ return item*2; });console.log(every);console.log(some);console.log(filter);console.log(map);number.forEach(function(item,index,array){ if (item>2) { //依次遍历大于2的元素 console.log (item); }}) 

归并方法

reduce方法:

依次处理数组的每个元素,最终累计为一个值,从左到右
•传入这些方法中的函数会接收四个参数:前一个值、数组的当前元素、当前元素在数组中的序号(从0开始)、原数组
var arr = [1, 2, 3, 4, 5];var sum = arr .reduce(function(prev, cur, index, array){ return prev+cur;});console.log(sum);//15

reduceRight方法:

从右到左,所有用法同上

Function类型

概述

函数就是一段预先设置的代码块,可以反复调用,根据输入参数的不同,返回不同的值。

创建方式

函数声明:

function print() {//code}

函数表达式:

var print = function() {//code};

命名式函数表达式

varprint = function x(){ console.log(typeof x); }; 

print() ;//function

这种写法的用处有两个,一是可以在函数体内部调用自身,二是方便除错

Function构造函数

var add = new Function( 'x', 'y', 'return (x + y)' );

立即执行函数

(function() {//code})();

函数名实际上是一个指向函数对象的指针

function sum(num1, num2){return num1 + num2;}console.log(sum(10,10));//20var newSum = sum;console.log(newSum(10,10));//20sum = null;console.log(newSum(10,10));//20

函数名的提升

先来个例子1
f();function f() {alert(1);}//1 可正常执行
等价于
var f;function f() {alert(1)}f();
再看另一个例子2
f(); var f = function (){alert(1);}; // TypeError: f is not a function
等价于
var f;f();function f() {alert(1);}
继续看例子3
var f = function() { console.log('1'); } function f() { console.log('2'); } f(); // 1
等价于
var f;function f() { console.log('2');}f = function() { console.log('1');}f(); // 1

函数的属性和方法

name属性:

返回紧跟在function关键字之后的那个函数名。
function f1() {}console.log(f1.name) // 'f1' var f2 = function () {};console.log(f2.name) // ‘ ' var f3 = function myName() {};console.log(f3.name) // 'myName'

length属性:

函数定义之中的参数个数
function f(a, b) {} f.length // 2

非继承而来的方法

apply():

一个是运行在函数中的作用域,一个是参数数组。第二个参数可以是Array实例,也可以是arguments对象。
function sum(num1,num2) {return num1 + num2;}function callSum1(num1, num2){return sum.apply(this, [num1, num2]);}function callSum2(num1, num2){return sum.apply(this, arguments);}console.log(callSum1(10,10));//20console.log(callSum2(10,10));//20

call():

第一个参数this值,后面的参数是将传递给函数的参数是逐个列出来
function sum(num1,num2) {return num1 + num2; }function callSum(num1, num2){return sum.call(this, num1, num2);}console.log(callSum(10,10));

扩充函数作用域

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

小结

Object 是一个基础类型,其他所有类型都从object继承了基本行为Array类型是一组有序列表,同时还提供了操作和转换这些值的功能函数实际上是function类型的实例,因此函数也是对象,而正是这一点是js最有特色的地方。由于函数是对象,所以也拥有方法,可以用来增强其行为







































分享给朋友:
您可能感兴趣的文章:
随机阅读: