はい、今回は5回目の記事になりますが、内容が多すぎます。長く、多くのコードが含まれています。主に参照型と一般的に使用される参照型について説明しています。コードはテストされており、何も問題はありません。
読み書きを続けることは簡単なことではありません。このブログから何かを学んでいただければ幸いです。それをみんなと共有できるのは素晴らしいことです。さらに、この本の中の退屈な言葉を誰でも簡単に理解できるように、私自身の理解と思考を通して個人的な洞察を得たいと思っています。皆さんが読んでこの人はよく書いたと思ってくれればそれで満足です。ふふふ
これ以上はナンセンスです、本題に入りましょう...
参照型? Java などの言語を学習したことがある場合は、それをクラスとして考えることができますが、この説明は不正確であると本にも書かれています。 。 。他に何も言う必要はありません。参照型は オブジェクト定義 として理解されます。
言語は本当に魔法だと思うことがあります。参照型について話すときは理解できないかもしれませんが、オブジェクト定義について話すときは理解できるかもしれません。
参照型 (オブジェクト定義): オブジェクトの型のプロパティとメソッドを記述します。
聞いてください:
1. 参照型 (オブジェクト定義): 人間は参照型であり、人間のオブジェクトに共通のプロパティとメソッドを記述します。人間の属性(目、頭、手など)、人間の方法(行動とも言えます):歩く、食べるなど。各参照型には定義が 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();
平たく言えば、私が人間と言ったら、あなたの脳の中に人間の大まかなモデルがあります。はい、私は配列と言います。配列が脳の中でどのように見えるかについては大まかに理解していますが、それが具体的にどのようなものであるかは知りません。たとえば、シャオミンと言いましたが、シャオミンがどのような人物であるかはわかります。
この時点で参照型についてはほぼ理解できたはずです。js の組み込み参照型について話しましょう。
なぜ JS の組み込み参照型を導入する必要があるのでしょうか?主な理由は、それらを頻繁に使用するためです。私たちが幼い頃に何かを知るようなものです。たとえば、私たちは最初はこれを知りませんでしたが、後から母親がいつも私たちに、これは魚だ、魚がどのようなものかを教えてくれました。そして、このタイプについてはある程度の理解が得られます。
js の世界には、それほど多くのものはありません。まず、一般的に使用される組み込み参照型である Object、Array、Date、RegExp、Function を理解しましょう。
オブジェクト型は最も一般的に使用される型ですが、オブジェクト インスタンスには多くの機能がありませんが、アプリケーションがデータを保存および送信するのに適しています。
まずオブジェクトを作成し、次に Object オブジェクトを作成するには 2 つの方法があります:
1. 直接新規。
構文: new 演算子とオブジェクト コンストラクター
//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
一般的には、ドットメソッドがよく使用されます。
詳細に入る必要はありません: 同じシリーズの 3 番目の記事をご覧ください
2 つの方法:
1.new Array();
//创建一个空数组 var arr1 = new Array(); //创建一个长度为10的空数组, var arr2 = new Array(10); //创建一个包含一个字符串good的数组 var arr3 = new Array("good");
特記事項: 括弧内に渡される値が 1 つだけで、その値が数値の場合は、その値の長さの配列が作成されます。他の値の場合は、その値の長さの配列が作成されます。はこの値を含む配列になります。
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 中国語 Web サイトの他の関連記事を参照してください。