Home > Article > Web Front-end > Introduction to JS reference types
Yes, this is the fifth article. When it comes to citation types, this time it will be divided into two blog posts. There is too much content. This is The first part is very long and contains a lot of code. It mainly talks about reference types and commonly used reference types. I have tested the code and found that there is nothing wrong with it.
Keep reading and writing. It’s not easy. I hope everyone can learn something from this blog. It’s great to be able to share it with everyone. Moreover, I want to gain some personal insights through my own understanding and thinking, so that everyone can easily understand the boring words in the book. If everyone feels that this guy wrote well after reading it, then I will be satisfied. Hey hey hey
No more nonsense, let’s get to the point...
Reference type? If you have studied languages such as Java, you can think of it as a class. The book also says that this description is inaccurate. . . Don't say anything else, we understand the reference type as object definition.
Sometimes I find that language is really magical. You may not understand reference types, but you may understand them when I talk about object definitions.
Reference type (object definition): describes the properties and methods of a type of object.
Listen to me:
##1. Reference type (object definition): Human It is a reference type, which describes the properties and methods common to human objects. Human attributes, such as having eyes, head, hands, etc.; human methods (can be said to be behaviors): walking, eating, etc. Each reference type has only one definition: it is a collective pointer.
2. Value of reference type: It is every new object (instance of reference type). There are many objects, just like hundreds of millions of us people. Objects of the same reference type have common properties and methods, but we can dynamically add and change properties, just like everyone has different places.
3.js built-in reference types: object type, Array type, Function type, Date type, RegExp type, etc. Of course, we can also customize reference types.
After looking at the created objects in the picture, let’s look at the objects created in the code:
//这里创建了一个对象叫obj,它是object类型的,那么它就有object类型共有的属性和方法 var obj = new Object(); //这里创建了一个对象叫arr,它是Array类型的,那么它就有Array类型共有的属性和方法 var arr = new Array(); //我们可以创建很多对象 var arr1 = new Array(); var arr2 = new Array();
In layman’s terms: If I talk about humans, in your brain There is a rough model of a person in it. Yes, I said an array. Your brain has a rough idea of what an array looks like, but you don’t know what it looks like specifically. Specific things can only be revealed by the object. For example, I said Xiao Ming (if you know Xiao Ming), then you know what kind of person Xiao Ming is.
You should have almost a complete understanding of reference types at this point. Let’s talk about the built-in reference types in js.
3. Js built-in reference typesWhy do we need to introduce the built-in reference types of js? The main reason is that we use them a lot. It’s like we learn about a thing from childhood, such as fish. We didn’t know this thing at first, but later our mother always told us that this is a fish, baby, and told you what a fish looks like, and then we have a certain understanding of this type. Basic understanding.In the world of js, we don’t have so many things in the world. Let’s first understand the commonly used built-in reference types: Object, Array, Date, RegExp, and Function. 1.Object type
The Object type is the most commonly used type. Although Object instances do not have many functions, they are good for applications to store and transmit data. s Choice.1.1 Create Object object: Let’s talk about it first. There are two ways to create an Object object:
1. Direct new. Syntax: new operator and Object constructor
//new操作符后面加Obejct的构造函数 var o = new Obeject(); //添加属性 o.name = "yuan";
2. Object literal Syntax: curly braces, the properties inside are in the form of key-value pairs, Each attribute is separated by a comma, and the last attribute is not comma-separated.
//对象字面量(有种封装数据的感觉) var p = { data:13, name:'yuan', age:11 } //两者对比 var x = {}; //创建一个空对象和new Object() 相同1.2 Access properties1. Through dot notation
var p = new Object(); p.name = '渊源远愿'; console.log(p.name); //渊源远愿2. Through square bracket method
var o = new Object(); o.age = 22; console.log(o["age"]); //22 //方括号可以用变量来访问属性 var otherAge = "age"; console.log(o[otherAge]); //22Generally speaking, the dot method is used More of them. 1.3 Properties and methods of Object: I won’t go into details: take a look at the third article in the same series2. Array type2.1 Creation ArrayTwo methods:
1.new Array();
//创建一个空数组 var arr1 = new Array(); //创建一个长度为10的空数组, var arr2 = new Array(10); //创建一个包含一个字符串good的数组 var arr3 = new Array("good");
Special note: When there is only one value passed in the brackets, and this value is a numeric value, An array with a length of this value will be created; if it is any other value, it will be an array containing an array of this value.2. Array literal, use square brackets:
// 创建空的 var fish = []; //创建有值的,在括号里添加 var cars = ["BMW","BenZ","Ferrari"]; //注意,创建数组不要留空项。浏览器兼容性问题,IE8或以前版本会认为这是有3项,下面这种不建议。 var nums = [1,2,];2.2 Access the values in the array Same as other languages for subscript access (subscript starts from 0 Start):
//创建数组 var cars = ["BMW","BenZ","Ferrari"]; console.log(cars[0]); //BMW console.log(cars[2]); //Ferrari //修改数组某个值,对其重新赋值就像 cars[0] = "lala";2.3 Commonly used attributes and methods
Commonly used attributes and methods are given here, and more details are in the js documentation.
1.length property: Returns the length of the array.
var num = [1,2,3,4,5] console.log(arr.length); //5 //妙用:通过改变数组的length可以改变数组长度 arr.length = 10; //现在num 数组长度为10了 console.log(num); //[1,2,3,4,5,,,,,] 后面5个值是空的
2.Array.isArray() method: Determine whether the object is an array
//用了判断改对象是不是数组 var arr = []; console.log(Array.isArray(arr)); //true console.log(Array.isArray("s"); //false
3.join() method: Change the array separation method, returns the new delimiter string
//原来是使用逗号连接的 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了
//创建一个时间对象,保存着当前时间 var n = new Date();
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文档中。
ES通过RegExg类型来支持正则表达式,语法:var e = /pattern/flag
其中pattern表示正则表达式,flag表示标识,标识可以一个或多个。
flags有3个,这些flags可以组合使用
flags | 说明 |
---|---|
g | 全局模式,该模式应用于所有的字符串 |
i | 不区分大小写模式,确定匹配项时忽略模式与字符串的大小写 |
m | 多行模式,一行文本到尾后还会查下一行的字符串,如果有的话 |
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;
有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"
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
核心:函数即对象
定义函数有下面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");
上面的定义函数常用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"); }
一个函数在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
上面说了,函数名只是函数的指针,函数名是变量一样,重复复制就会覆盖原来的。
在java语言来说,有不同的参数数量也称为重载,但是js中没这种操作
//函数声明,fn为函数名 function fn(num1, num2){ return num1+ num2; } //再来函数声明,fn为函数名 function fn(num){ return num; } //fn只会指向最后一次声明的函数 fn(1,43); //1
因为函数名本来就是一个变量,所以函数也可以像值一样被传递。说实话,函数能被当做值来传递确实是一件好玩的事,大家有兴趣可以去了解回调函数,这里先不介绍了。
//声明一个函数fn1,它可以接受两个参数,一个是函数,一个是值 function fn1(fn,value){ return (fn(value)); } //声明一个fn2,接受一个参数 function fn2(val){ console.log(val+1000); } //fn2当成参数传递给fn1 fn1(fn2,24); //1024
函数内部有两个特殊的对象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
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]); }
The above is the detailed content of Introduction to JS reference types. For more information, please follow other related articles on the PHP Chinese website!