네, 이번 글은 5번째 글입니다. 이번에는 내용이 너무 많아서 두 개로 나누어서 포스팅하겠습니다. 길고 코드가 많습니다. 주로 참조 유형과 일반적으로 사용되는 참조 유형에 대해 설명하며 코드는 테스트되었으며 아무런 문제가 없습니다.
계속 읽고 쓰세요. 모두가 이 블로그에서 뭔가를 배울 수 있기를 바랍니다. 모두와 공유할 수 있어서 좋아요. 더욱이, 나는 책에 나오는 지루한 단어들을 누구나 쉽게 이해할 수 있도록 내 자신의 이해와 생각을 통해 개인적인 통찰력을 얻고 싶습니다. 이 사람이 글을 잘 썼다고 다들 느끼신다면 저는 만족하겠습니다. ㅋㅋㅋㅋㅋㅋ
더 이상 헛소리는 그만하고 본론으로 들어가죠...
참조형? 자바 등의 언어를 공부한 적이 있다면 일종의 수업이라고 생각하면 될 것 같다. 이 책에서도 이 설명은 정확하지 않다고 말한다. . . 다른 말은 하지 마세요. 우리는 참조 유형을 객체 정의로 이해합니다.
때때로 참조 유형에 대해 이야기하면 언어가 정말 마술적이라는 것을 알 수 있습니다. 그러나 객체 정의에 대해 이야기하면 이해할 수 있습니다.
참조 유형(객체 정의): 객체 유형의 속성과 메서드를 설명합니다.
내 말을 들어보세요:
1. 참조 유형(객체 정의): 인간은 인간 객체에 공통적인 속성과 방법을 설명하는 참조 유형입니다. 눈, 머리, 손 등 인간의 속성(행동이라고 할 수 있음): 걷기, 먹기 등 각 참조 유형에는 단 하나의 정의만 있습니다. 즉, 집합 포인터입니다.
2. 참조 유형의 가치: 우리 수억 명의 사람들처럼 많은 객체가 있습니다. 동일한 참조 유형의 개체에는 공통 속성과 메서드가 있지만 모든 사람이 서로 다른 위치를 갖고 있는 것처럼 속성을 동적으로 추가하고 변경할 수 있습니다.
3.js에 내장된 참조 유형: 객체 유형, 배열 유형, 함수 유형, 날짜 유형, RegExp 유형 등. 물론 참조 유형을 사용자 정의할 수도 있습니다.
사진 속 생성된 객체를 살펴본 후, 코드에서 생성된 객체를 살펴보겠습니다.
//这里创建了一个对象叫obj,它是object类型的,那么它就有object类型共有的属性和方法 var obj = new Object(); //这里创建了一个对象叫arr,它是Array类型的,那么它就有Array类型共有的属性和方法 var arr = new Array(); //我们可以创建很多对象 var arr1 = new Array(); var arr2 = new Array();
일반인의 관점에서 말하면, 인간이라고 하면 여러분의 뇌 속에는 대략적인 인간의 모델이 있습니다. , 예, 저는 배열이라고 말합니다. 여러분은 배열이 뇌에서 어떻게 보이는지 대략적으로 알고 있지만 구체적으로 어떻게 생겼는지는 모릅니다. 구체적인 것들은 사물에 의해서만 드러날 수 있습니다. 예를 들어 Xiao Ming (당신이 Xiao Ming을 안다면)이라고 말하면 Xiao Ming이 어떤 사람인지 알 수 있습니다.
이 시점에서 js에 내장된 참조 유형에 대해 이야기해 보겠습니다.
JS 내장 참조 유형을 도입해야 하는 이유는 우리가 많이 사용하기 때문입니다. 마치 우리가 어렸을 때 물고기 같은 것을 알게 되는 것과 같습니다. 처음에는 이것을 몰랐지만 나중에는 어머니가 항상 이것이 물고기라고 말하면서 물고기가 어떻게 생겼는지 알려 주셨습니다. 그리고 우리는 이러한 유형의 기본적인 이해를 갖고 있습니다.
JS의 세계에는 세상에 그렇게 많은 것이 없습니다. 먼저 일반적으로 사용되는 내장 참조 유형인 Object, Array, Date, RegExp 및 Function을 이해해 보겠습니다.
객체 유형은 가장 일반적으로 사용되는 유형입니다. 객체 인스턴스에는 많은 기능이 없지만 애플리케이션이 데이터를 저장하고 전송하는 데 적합합니다.
먼저 생성된 다음 객체 객체를 생성하는 두 가지 방법이 있습니다:
1 직접 새로 만들기.
구문: 새 연산자 및 개체 생성자
//new操作符后面加Obejct的构造函数 var o = new Obeject(); //添加属性 o.name = "yuan";
2. 개체 리터럴
구문: 중괄호, 내부 속성은 키-값 쌍 형식이며, 각 속성은 쉼표로 구분되며 마지막 속성은 쉼표는 필요하지 않습니다.
//对象字面量(有种封装数据的感觉) var p = { data:13, name:'yuan', age:11 } //两者对比 var x = {}; //创建一个空对象和new Object() 相同
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.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,];
다른 언어와 같은 하위 첨자 액세스(아래 첨자는 0부터 시작):
//创建数组 var cars = ["BMW","BenZ","Ferrari"]; console.log(cars[0]); //BMW console.log(cars[2]); //Ferrari //修改数组某个值,对其重新赋值就像 cars[0] = "lala";
일반적으로 사용되는 속성과 메서드는 여기에 제공되며 자세한 내용은 js 설명서에 나와 있습니다.
1.length 속성: 배열의 길이를 반환합니다.
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() 메서드: 객체가 배열인지 확인
//用了判断改对象是不是数组 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了
//创建一个时间对象,保存着当前时间 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]); }
위 내용은 JS 참조 유형 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!