一、介绍

  • 没错,这是第五篇,到了引用类型,这次要分成两次博文了,太多内容了,这是前篇,篇幅很长也很多代码,主要讲引用类型和常用的引用类型,代码试验过的,老铁没毛病。
  • 坚持看坚持写,不容易不容易,希望大家能在这博客中学到东西。能和大家分享,不错不错。而且啊,我想通过自己的认识,思考来得到一些个人见解,以便能大家能容易理解,书中那枯燥的文字。如果大家在看后有种感觉说这家伙写得不错,那我就满足了。嘿嘿嘿

不废话了,进入正题...

二、引用类型

引用类型?如果有学过java一类的语言的,可以把它看成类,书中又说这种描述不准确。。。什么也别说了,我们把引用类型理解为对象定义

有时发现语言这种东西,真的神奇,说引用类型你可能不理解,我说对象定义,就可能理解了。

引用类型(对象定义):描述了一类对象所具有的属性和方法。

听我娓娓道来:

1.引用类型(对象定义): 人类就是引用类型,它描述了人类对象所共有的属性和方法。人的属性比如,有眼睛,有头,手等;人的方法(可以说是行为):走路,吃饭等等。每个引用类型只有一种定义,即它是集体性的指向。

2.引用类型的值:就是每一个new出来的对象(引用类型的实例),对象有很多,就像我们亿万人民一样。同一个引用类型的对象们有共同的属性和方法,但我们可以动态添改属性,就像每个人都有不同的地方。

3.js中内置的引用类型:object类型,Array类型,Function类型,Date类型,RegExp类型等等,当然我们也可以自定义引用类型。

看了图的创建对象,我们看看代码中创建对象:

//这里创建了一个对象叫obj,它是object类型的,那么它就有object类型共有的属性和方法
var obj = new Object();
//这里创建了一个对象叫arr,它是Array类型的,那么它就有Array类型共有的属性和方法
var arr = new Array();
//我们可以创建很多对象
var arr1 = new Array();
var arr2 = new Array();

通俗的讲:如果我说人类,在你的大脑中就有个大概的人的模型,对,我说数组,你大脑就有个数组的大概样子,但是你不知道它具体的样子。具体的东西是对象才能展现出来的,比如我说小明(如果你认识小明),那你就知道小明是个怎样的人了。

到这里应该把引用类型理解得差不多了,下面就说js中的内置的引用类型吧。

三、Js内置的引用类型

为什么需要介绍js的内置引用类型,主要是我们用得多。我们就像从小去认识一种事物一样,比如鱼类,一开始我们不知道这东西,后来妈妈老是跟我们说这是鱼啊宝贝,告诉你鱼是怎样怎样的,然后对这种类型有了基本认识。

在js的世界里我们没世上那么多的东西,内置的引用类型我们就先理解Object,Array,Date,RegExp,Function这几个常用的。

1.Object类型

Object 类型是使用得最多得类型,虽然Object得实例不具备多少功能,但对于应用程序存储和传输数据而言,是好的选择。

1.1创建Object对象:

先出生了再说,创建Obeject的对象的2种方法:

**1.直接new。 **

语法:new操作符跟Obeject构造函数

//new操作符后面加Obejct的构造函数
var o = new Obeject();
//添加属性
o.name = "yuan";

**2.对象字面量 **

语法:花括号,里面的属性用键值对形式,每个属性用逗号隔开,最后一个属性不用逗号。

//对象字面量(有种封装数据的感觉)
var p = {
data:13,
name:'yuan',
age:11
}
//两者对比
var x = {}; //创建一个空对象和new Object() 相同

1.2访问属性

1.通过点表示法

var p = new Object();
p.name = '渊源远愿';
console.log(p.name); //渊源远愿

2.通过方括号法

var o = new Object();
o.age = 22;
console.log(o["age"]); //22
//方括号可以用变量来访问属性
var otherAge = "age";
console.log(o[otherAge]); //22

通常来说都是用点方法比较多的。

1.3 Object的属性和方法:

不赘述了:看看同系列的第三篇吧

2.Array类型

2.1 创建数组

两种方式:

1.new Array();

//创建一个空数组
var arr1 = new Array();
//创建一个长度为10的空数组,
var arr2 = new Array(10);
//创建一个包含一个字符串good的数组
var arr3 = new Array("good");

特别说明:当传进去括号中的只有一个值,这个值是数值的话,就会创建长度为这个数值的数组;如果是其他值,那就是包含一个这个值的数组。

2.数组字面量,使用方括号:

// 创建空的
var fish = [];
//创建有值的,在括号里添加
var cars = ["BMW","BenZ","Ferrari"];
//注意,创建数组不要留空项。浏览器兼容性问题,IE8或以前版本会认为这是有3项,下面这种不建议。
var nums = [1,2,];

2.2 访问数组中的值

和其他语言一样下标访问(下标从0开始):

//创建数组
var cars = ["BMW","BenZ","Ferrari"];
console.log(cars[0]); //BMW
console.log(cars[2]); //Ferrari //修改数组某个值,对其重新赋值就像
cars[0] = "lala";

2.3 常用属性和方法

这里给出常用的属性和方法,更详细的在js的文档里面有。

1.length属性:返回数组的长度。

var num = [1,2,3,4,5]
console.log(num.length); //5
//妙用:通过改变数组的length可以改变数组长度
num.length = 10; //现在num 数组长度为10了
console.log(num); //[1,2,3,4,5,,,,,] 后面5个值是空的

2.Array.isArray()方法:判断对象是不是数组

//用了判断改对象是不是数组
var arr = [];
console.log(Array.isArray(arr)); //true
console.log(Array.isArray("s"); //false

3.join()方法:改变数组分隔方式,返回新的分隔符字符串

//原来是使用逗号连接的
var arr = [1,2,3,4,5];
//用|连接,注意只是返回字符串,不会改变数组里面的连接方式
console.log((arr.join("|")); //'1|2|3|4|5'
console.log(arr); //[1,2,3,4,5] 还是一样用逗号的

**4.栈方法:pop()和push()组合使用实现栈的先进后出 **

//引入这两方法是为了用数组实现栈的功能
//push() :从数组最后添加数据
var stack = new Array();
//添加一个10
stack.push(10);
//添加一个5
stack.push(5);
//添加一个100
stack.push(100);
//现在stack中有3个数值
console.log(stack); //[10,5,100] //pop() :从数组最后删除并返回该数据
stack.pop(); //100 100被删除
console.log(stack); //[10,5] 剩下两数

5.队列方法:shift()和push()组合使用实现先进先出

这里就不再举例了,类似与栈的操作,只是操作的函数不同,栈的pop是从后面删除,而队列的shift是从前面删除,这样就先进先出了。

6.重排序方法:sort()和reverse()

//sort()默认是按照ascii码表排序的,所以会出现下面这种情况
var arr = [5,12,18,1];
console.log(arr.sort()); //[1,12,18,5]
//为了可以对数字正常排序,为sort传入一个比较函数
function comp(a,b){
return a-b;
}
//再来排序
arr.sort(comp);
console.log(arr); //[1,5,12,18] 这次正确了 //reverse()是将数组完全颠倒
arr.reverse();
console.log(arr); //[18,12,5,1]

7.合并和剪切:concat() , slice()

//1.concat() 在该数组的基础上添加元素,返回一个新数组(不会改变原数组)
var arr1 = [1,2,3];
//在arr1基础添加4,5,6,并返回给arr2,不会改变arr
var arr2 = arr1.concat(4,5,6);
console.log(arr2); //[1,2,3,4,5,6] //2.slice() 通过传入开始和终点值来剪切数组,并返回新数组
var arr3 = arr2.slice(1,5);
console.log(arr3); //[2,3,4,5]

8.最强大的数组方法:splice()

删除:接受两个参数,第一个是开始删除位置,第二个是删除的个数,返回一个删除项的数组

//用来删除
var arr = [1,2,3,4,5,6,7];
var del_arr = arr.splice(0,4); //从0位开始删除4项,即前4项
console.log(del_arr); //[1,2,3,4]
console.log(arr); //[5,6,7] arr数组剩下后面3项了

插入:输入3个参数,起始位置,0(删除项数设为0),要插入的值

//用来插入
var arr1 = [1,2,3,4,5,6];
arr1.splice(3,0,100);//从位置3插入一个100值
console.log(arr1); //[1,2,3,100,4,5,6];

替换:指定3个参数,起始位置,要删除的项,插入的值

//替换
var arr2 = [1,2,3,4,5];
//我要替换3,替换成100
arr2.splice(2,1,100); //起始位是2,删除1项(就是3了),载插入100,ok
console.log(arr2); //[1,2,100,4,5]

9.位置函数:indexOf()和lastIndexOf():这两个方法用来找数值下标位置。都接受两个参数,第一个是要找的值,第二个是开始位置

//indexOf() 只传一个参数时默认从0开始找数值,找到返回这个数的数组位置,没有返回-1
var arr = [100,12,123,1234];
console.log(arr.indexOf(123)); //2 数组的位置2 //lastIndexOf() 和indexOf查找顺序正好相反,它从数组末尾开始找起
console.log(arr.lastIndexOf(100)); //0

10.forEach()方法,对每一项进行处理

//接受一个函数,函数传入2个参数表示当前数值和其下标位置
var arr = [1,2,3,4,5];
arr.forEach(function(item, index){
console.log(item + 1);
} //输出 2,3,4,5,6 每一项都加1了

3.Date类型

3.1 创建对象

//创建一个时间对象,保存着当前时间
var n = new Date();

3.2 常用方法

var now = new Date();
//getDate() 返回当前天数,一个月的某天(0-31)
console.log(now.getDate()); //20
//getMonth() //返回月份
console.log(now.getMonth()); //9,这里的9表示10月 (0-11)
//getFullYear(),返回当前年份
console.log(now.getFullYear()); //2017

更多方法在js文档中。

4.RegExg类型

ES通过RegExg类型来支持正则表达式,语法:var e = /pattern/flag

其中pattern表示正则表达式,flag表示标识,标识可以一个或多个。

flags有3个,这些flags可以组合使用

flags 说明
g 全局模式,该模式应用于所有的字符串
i 不区分大小写模式,确定匹配项时忽略模式与字符串的大小写
m 多行模式,一行文本到尾后还会查下一行的字符串,如果有的话

4.1 创建RegExg对象

1.字面量方式

//懒啊,直接书上的例子
var p1 = /at/g; //匹配所有"at" 的实例
var p2 = /[bc]at/i //匹配第一个bat或cat,不区分大小写
var p3 = /.at/gi //匹配所有at结尾的组合,不区分大小写 //正则中如果想在字符中包含元字符需要对其进行转义
//这里和p3不同的是对.这个元字符进行转义,用\符号转义
var p4 = /\.at/gi; //这里的意思是匹配所有的".at",不区分大小写。

2.使用new RegExg构造函数

//RegExg() 接受两个参数,一个是正则表达式,一个是标志
var pattern1 = new RegExg("at","gi");
//pattern1和pattern2完全等价
var pattern2 = /at/gi;

4.2 RegExp的实例属性

有5个实例属性:global,ignoreCase,multiline,lastIndex,source

//直接上例子,了解作用是什么就好了
//有一个正则对象
var p = /hello/i;
//global属性,返回布尔值,表示是否设置了g标志
console.log(p.global); //false
//ignoreCase属性,返回布尔值,表示是否设置了i标志
console.log(p.ignoreCase); //true
//multiline属性,返回布尔值,表示是否设置了m标志
console.log(p.multiline); //false
//lastIndex属性,返回整数,表示开始搜索下一个匹配字符的位置,从0开始
console.log(p.lastIndex); //0
//source属性,返回正则表达式的字符串形式
console.log(p.source); //"hello"

4.3 RegExp常用方法

1.exec()方法:接受一个参数,这参数是应用模式的字符串,然后返回包含第一个匹配项的数组

var p = /p/;
var str = "happy";
var arr = p.exec(str);
console.log(arr); // ["p",index:2,input:"happy"] 返回这个数组,第一个值表示匹配到的字符,index表示字符所在的位置,input表示应用的字符串

2. test() 方法:用于知道这个字符串与模式是否匹配,接受一个字符串参数,返回布尔值

var p1 = /ry/g;
console.log(p1.test("ryuan")); //true,字符串中有ry这字符串,所以返回true

5.Function类型

核心:函数即对象

5.1 定义函数

定义函数有下面3种方法,常用的是1,2种

//1.函数声明
function getName(){
var name = 'ry-yuan';
return name;
}
//2.函数表达式
var getAge = function(){
var age = 100;
return age;
}
//3.使用Function构造函数,前面1-n个是参数,最后一个参数的是函数体,这种不推荐使用。
var sum = new Function("num","return num");

5.2 函数声明和函数表达式的区别

上面的定义函数常用1,2中,分别是函数声明和函数表达式,那他们有什么区别?

如果听过声明提升的话就很容易理解下面的内容,js解析器执行时会先找到所有的声明,将其提升到顶部。有什么用?看例子:

//函数声明,我们先运行sayHello,但是不会报错,因为函数声明已经在解析时被提到顶部
sayHello(); //hello everyone
function sayHello(){
console.log("hello everyone");
} //函数表达式,用var定义函数名.用函数表达式,不会提升,所以先运行sayBye就会找不到函数体
sayBey(); //报错 TypeError: sayBye is not a function
var sayBye = function(){
console.log("bye bye");
}

5.3 函数名是指向函数的指针

一个函数在js种就是一个Function的实例,函数名就是对实例的引用,一个指针,前面的对象中也有说过。那么一个函数就可以有多个函数名了。

//定义一个函数,函数名是sum
var sum = funtion(num1,num2){
return num1+num2;
} //讲sum复制给otherSum,那么otherSum和sum都指向同一个function对象
otherSum = sum; otherSum(100,420); //520
sum(1300+14); //1314 //对sum设置为null,sum变量就不在指向function对象
sum = null; //otherSum依然能够使用
otherSum(1,9); //10

5.4 函数没有重载

上面说了,函数名只是函数的指针,函数名是变量一样,重复复制就会覆盖原来的。

在java语言来说,有不同的参数数量也称为重载,但是js中没这种操作

//函数声明,fn为函数名
function fn(num1, num2){
return num1+ num2;
}
//再来函数声明,fn为函数名
function fn(num){
return num;
} //fn只会指向最后一次声明的函数
fn(1,43); //1

5.5 函数像值一样传递

因为函数名本来就是一个变量,所以函数也可以像值一样被传递。说实话,函数能被当做值来传递确实是一件好玩的事,大家有兴趣可以去了解回调函数,这里先不介绍了。

//声明一个函数fn1,它可以接受两个参数,一个是函数,一个是值
function fn1(fn,value){
return (fn(value));
}
//声明一个fn2,接受一个参数
function fn2(val){
console.log(val+1000);
}
//fn2当成参数传递给fn1
fn1(fn2,24); //1024

5.6 函数内部对象

函数内部有两个特殊的对象arguments和this

1.arguments:包含传入函数的所有参数,主要用于保存函数参数,它可以看做是一个数组

function fn(num1,num2){
console.log(arguments);
}
fn(100,200); //{'0':100,'1':200} //arguments有一个callee的属性,它是一个指针,用来指向当前这个函数
//例如一个递归调用,阶乘函数,里面的arguments.callee就是等价于这个函数
function factorial(num){
if(num<=1){
return 1;
}
else{
return num*arguments.callee(num-1);
}
}

2.this:指向调用这个函数的对象

//全局作用域下
var hi = 'hi';
//一个普通object对象
var obj = { hi = "obj hi"};
function say(){
console.log(this.hi)
} //say函数在全局作用域下定义,直接执行,this将指向window对象,所以hi是windows对象的。
say(); //hi //将say赋予obj对象,并且obj来调用say,这次this将指向obj对象
obj.say = say;
obj.say(); //obj hi

5.7函数属性和方法

1.length属性:函数接受参数的个数

function fn(n,m){};
alert(fn.length); //2

2.prototype属性:后面博客再说,厉害嘞

3.apply()和call()方法:扩充函数依赖的运行环境。就像是把一个函数给一个个的对象使用。

var color = "red";
var obj = {color: "green"};
//先声明一个函数
function fn(){
console.log(this.color);
}
//给window对象用
fn.call(window); //red
//给obj对象用
fn.call(obj); //green

apply和call功能是一样的:不同就是接受参数不同,大家第一个参数都是作用域对象,后面的apply接收一个参数数组,call则是接收一个个参数。

//声明一个函数add
function add(num1,num2){
return num1+num2;
}
//在另一个函数调用,第一个是this,后面参数一个个输入
//这里用call
function otherAdd(n1,n2){
return add.call(this,n1,n2);
}
//这里用apply,第一都是this,后面接受参数变成数组形式
function otherAdd(n1,n2){
return add.apply(this,[n1,n2]);
}

四、说说

这篇东西挺长篇幅,适合慢慢看,也适合作为温故js的引用类型的知识,多看几遍。可以可以,如果觉得写得好,就点赞啊,还会继续更新哦。

同系列前几篇:

第一篇:JavaScript--我发现,原来你是这样的JS(一)(初识)

第二篇:JavaScript--我发现,原来你是这样的JS(二)(基础概念--躯壳篇)

第三篇:JavaScript--我发现,原来你是这样的JS(三)(基础概念--灵魂篇)

第四篇:JavaScript--我发现,原来你是这样的JS(四)(看看变量,作用域,垃圾回收是啥)

本文出自博客园:http://www.cnblogs.com/Ry-yuan/

作者:Ry(渊源远愿)

欢迎访问我的个人首页:我的首页

欢迎访问我的github:https://github.com/Ry-yuan/demoFiles

欢迎转载,转载请标明出处,保留该字段。

JS--我发现,原来你是这样的JS(引用类型不简单[上篇],且听我娓娓道来)的更多相关文章

  1. JavaScript--我发现,原来你是这样的JS(引用类型不简单,且听我娓娓道来)

    一.介绍 没错,这是第五篇,到了引用类型,这次要分成两次博文了,太多内容了,这是前篇,篇幅很长也很多代码,主要讲引用类型和常用的引用类型,代码试验过的,老铁没毛病. 坚持看坚持写,不容易不容易,希望大 ...

  2. JS--我发现,原来你是这样的JS(引用类型不简单[下篇],基本包装类型与个体内置对象)

    一.介绍 本篇是续上一篇的,引用类型的下篇,本篇主要是说基本包装类型和个体内置对象.如果你能收获一些知识,那我很高兴,很满足,哈哈哈,希望大家能愉快看完.如果你想学好一门技术,要不忘初心,方得始终. ...

  3. 爬虫模拟有道字典进行翻译,还发现了一条好玩的js

    08.14自我总结 爬虫模拟有道字典进行翻译 一.代码 import requests from lxml.html import etree # headers= { # 'User-Agent': ...

  4. gulp实现打包js/css/img/html文件,并对js/css/img文件加上版本号

    参考打包教程: http://www.cnblogs.com/tugenhua0707/p/4069769.html http://www.cnblogs.com/tugenhua0707/p/498 ...

  5. 深入浅出Node.js(一):什么是Node.js

    Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹.从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟Joyent获得企业资助,再到 ...

  6. 深入浅出Node.js(一):什么是Node.js(转贴)

    以下内容转自:http://www.infoq.com/cn/articles/what-is-nodejs/ 作者:崔康 [编者按]:Node.js从2009年诞生至今,已经发展了两年有余,其成长的 ...

  7. JS模块化:CommonJS和AMD(Require.js)

    早期的JS中,是没有模块化的概念的,这一情况直到09年的Node.js横空出世时有了好转,Node.js将JS作为服务端的编程语言,使得JS不得不寻求模块化的解决方案. 模块化概念 在JS中的模块是针 ...

  8. JS学习十四天----server端运行JS代码

    server端运行JS代码 话说,当今不在client使用JS代码才是稀罕事.因为web应用的体验越来越丰富,client用JS实现的逻辑也越来越多,这造成的结果就是某些差点儿一致的逻辑须要在clie ...

  9. js浮点数精度丢失问题及如何解决js中浮点数计算不精准

    js中进行数字计算时候,会出现精度误差的问题.先来看一个实例: console.log(0.1+0.2===0.3);//false console.log(0.1+0.1===0.2);//true ...

随机推荐

  1. UI的设计,适配器,以及RecyclerView无法加载的解决办法

    这本书里讲到的界面设计都是用最基本的方式实现的,即编写xml文件 所有的控件都具有宽度和高度属性,即android:layout_width和android:layout_height,这两个属性对应 ...

  2. 设置Jmeter默认为中文, 就是这么简单!

    Jmeter默认加载的全英文,想要看的更加明白,想到的就是汉化了. Jmeter汉化真的非常简单,意料之外的简单,只需要到配置文件 jmeter.properties ,将里面的 “#language ...

  3. sql必知必会

    1.根据条件查询数据库中数据,并返回数据条数 去掉count就会返回数据库中符合条件的所有数据 SELECT COUNT(*) FROM sentiment_info WHERE sentiment_ ...

  4. 06-01 Java 二维数组格式、二维数组内存图解、二维数组操作

    二维数组格式1 /* 二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的 ...

  5. [Umbraco] macro(宏)在umbraco中的作用

    macro在umbraco中是一个核心的应用,它是模板页中用于动态加载内容的标签(模板指令),宏可以是基于XSLT文件创建,亦可以是基于ASP.NET用户控件创建 在develop下的Macros中创 ...

  6. .NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇

    Linux守护进程是Linux的后台服务进程,相当于Windows服务,对于为Linux开发服务程序的朋友来说,Linux守护进程相关技术是必不可少的,因为这个技术不仅仅是为了开发守护进程,还可以拓展 ...

  7. 线程中消费者生产者的实例代码(synchronized关键字)

    http://www.cnblogs.com/DreamDrive/p/6204665.html  这个是用Lock类实现的. 场景: 厨师类: import java.util.List; impo ...

  8. CentOS 7.5 安装与配置 Percona Server 5.7

    个人比较喜欢 MYSQL 的轻量,今天花了一点时间把阿里云上的 MYSQL5.7 换成了 Percona-Server .Percona 是一个开源的 MySQL 衍生版,TokuDB 的数据库引擎使 ...

  9. StreamSets学习系列之StreamSets的Create New Pipeline(图文详解)

    不多说,直接上干货! 前期博客 StreamSets学习系列之StreamSets支持多种安装方式[Core Tarball.Cloudera Parcel .Full Tarball .Full R ...

  10. 前端组件化Polymer入门教程(1)——初识&&安装

    前端组件化Polymer入门教程目录: 前端组件化Polymer入门教程(1)--初识&&安装 前端组件化Polymer入门教程(2)--快速入门 前端组件化Polymer入门教程(3 ...