JavaScript对象
1.Function对象
- 函数的创建
//方法一:自定义函数 function 函数名([参数]) { 函数体 [return 表达式] } //方法二:匿名函数 (function([参数]) { 函数体 [return 表达式] }); **使用场景一:定义后直接调用使用(只使用一次) (function(a,b){ return a + b; })(1,2); **使用场景二:作为其他对象的方法 document.getElementById("p1").onclick = (function(){ console.log("鼠标单击了..."); }); //方法三:箭头函数 (参数) => { // 函数体 return 结果; } * 如果只有一个参数,() 可以省略,如果没有参数,() 还是要保留 * 如果函数体内只有一行代码,{} 可以省略 * 如果这一行代码就是结果,return 可以省略 document.getElementById("p1").onclick = () => { console.log("鼠标单击了..."); } //方法四:默认参数的函数 function 函数名(参数1 = 参数值1, 参数2 = 参数值2) {} 此时,传递参数有默认值,如果传递参数会覆盖默认值,不传递则会使用默认值(或者传递undefined)
- 函数的特点
1.在定义函数的时候无需指定函数的返回值和函数的参数类型 2.函数是一个对象,如果定义同名函数会覆盖函数 3.在JS中,方法的调用只与方法的名称有关,和参数列表无关(即可以选择是否有参数列表,调用函数时传入参数个数随便) 4.在方法声明中有一个隐藏的内置对象(数组),arguments,封装所有的实际参数 function add() { let sum = 0; for (let index = 0; index < arguments.length; index++) { sum += arguments[index]; } return sum; }
- 函数对象的概述
- 可以参与赋值(将对象值赋值给一个变量)
function abc() { console.log("bb"); } document.getElementById("p1").onclick = abc;
- 有属性、有方法,执行
console.dir(abc)
,输出结果如下
ƒ abc() arguments: null caller: null length: 0 name: "abc" ➡prototype: {constructor: ƒ} [[FunctionLocation]]: VM1962:1 ➡[[Prototype]]: ƒ () ➡[[Scopes]]: Scopes[1]
- 可以作为方法参数
function a() { console.log('a') } function b(f) { console.log('b') f(); // 调用函数对象 } b(a)
- 可以作为方法返回值
function c() { console.log("c"); function d() { console.log("d"); } return d; } c()()
- 函数的属性
length:表示定义的形参列表的参数个数 如:function add(a, b, c) {} alert(a.length) 结果:3
- 函数的作用域
* 以函数为分界线划定作用域,所有函数之外是全局作用域 * 查找变量时,由内向外查找 * 在内层作用域找到变量,就会停止查找,不会再找外层 * 所有作用域都找不到变量,报错 * 作用域本质上是函数对象的属性,可以通过 console.dir 来查看调试
函数的闭包:函数定义时,它的作用域已经确定好了,因此无论函数将来去了哪,都能从它的作用域中找到当时那些变量。闭包就是指函数能够访问自己的作用域中变量
- let 与 var作用域
如果函数外层引用的是 let 变量,那么外层普通的 {} 也会作为作用域边界,最外层的 let 也占一个 script 作用域
如果函数外层引用的是 var 变量,外层普通的 {} 不会视为边界
如果 var 变量出现了重名,则他俩会被视为同一作用域中的同一个变量
var e = 10; if(true) { var e = 20; console.log(e); // 打印 20 } console.log(e); // 因为是同一个变量,还是打印 20
如果是 let,则视为两个作用域中的两个变量
let e = 10; if(true) { let e = 20; console.log(e); // 打印 20 } console.log(e); // 打印 10
要想里面的 e 和外面的 e 能区分开来,最简单的办法是改成 let,或者用函数来界定作用域范围
var e = 10; if(true) { function b() { var e = 20; console.log(e); } b(); } console.log(e);
2.字符串对象
- 字符串对象的定义
方法一: var 变量名 = "字符串"/'字符串'/`字符串` 方法二: var 变量名 = new String("字符串")
constructor:字符串对象的函数模型 length:字符串的长度 prototype:添加字符串对象的属性
- 字符串对象的方法
方法 | 描述 |
---|---|
charAt(索引) | 返回索引字符 |
indexOf(要查找的字符串,[起始索引]) | 返回要查找的字符串的首个位置 |
lastIndexOf() | 返回要查找的字符串的最终位置 |
substr(开始位置,[长度]) | 截取字符串的长度 |
substring(开始位置,结束位置) | 截取字符串的长度 |
split(分隔符) | 分割字符串 |
replace(要查找的字符串,新字符串) | 在字符串对象中,将指定的字符串替换为新字符串 |
toLowerCase() | 字符串对象转换为小写 |
toUpperCase() | 字符串对象转换为大写 |
//区分三种字符串截取函数 slice: slice(a,b)的作用是截取a位置(含)到b位置(不含)之间的字符串,被截取的字符串不变,返回截取后获得的子字符串。比如a是0,b是3,则截取0、1、2三个位置的字符。b为可选参数,不填则表示截取到字符串的尾部。a或b为负数时表示从右往左排,即-1表示最右侧的位置,依次类推。 substring() a或b为负数时,自动转换为0;a大于b时,编译器会自动对调两者。 substr() a表示开始位置(包含);b表示截取的长度,可选。不填则截取到字符串结尾处; a为负数时表示从右往左排,即-1表示最右侧的位置,依次类推。
//字符串拼接的两种方法 let name = "张三"; let age = 18; 方法一:使用加号进行拼接 let url = "/text?name=" + name +"&age=" + age; 方法二:使用模板占位进行拼接(使用反引号进行引用) let url = `/test?name=${name}&age=${age}`;
3.数学对象
- 数学对象的属性
E/LN2/LN10/PI/SORT2
- 数学对象的方法
- 保留小数
数学.toFixed(x)//保留x位小数 数字.toPrecision(x)//保留x位数字
4.日期对象
- 日期对象的创建
方法一: var date1 = new Date()//获取本地时间 方法二: var date2 = new Date(日期字符串)//创建指定的时间对象 方法三: var date3 = new Date(年,月,日,[时,分,秒,毫秒])//多参数创建指定的时间对象 方法四: var date4 = new Date(100000000)//通过毫秒创建时间(1970:00:00)
- 日期对象的相关方法
常用日期和时间的获取
设置日期及时间
window对象中和时间有关的方法
①SetTimeout:用于设置一个计时器,在指定的时间间隔后调用函数或计算表达式,且仅执行一次。 setTimeout(函数名,间隔的毫秒数) ② clearTimeOut:清除由setTimeout()方法所设置的计时器。 clearTimeout(setTimeout返回的id值)
- 时间对象格式化
5.数组对象
数组对象是一个有序的数据集合,使用单独的变量名来存储 一系列的数据。在JavaScript中,定义数组时不需要指定数组的数据类型,而且可以将不同类型的数据存放到一个数组中
- 数组对象的创建
//空数组: var a = new Array(); //声明长度为n的数组: var b = new Array(n); //通过参数列表赋值,创建数组 var c = new Array(元素1,元素2,元素3...) var d = [1,2,3,4]
- 数组对象的属性
arr.length//获得数组的长度
- Js数组特点
1.Js中的数组类型可以变 2.Js中的数组长度可以变
- 数组的操作
操作1:遍历数组元素
//方法一:返回的i是数组中非undefind的 for (i in arr) { document.write(arr[i] + "<br/>") } //方法二:返回数组中非undefind的值 arr.forEach(function(e){ document.write(e) }) arr.forEach((e) => document.write(e)}) 原理: let arr = [1,2,3,4]; //函数规则 function print(e) { documnet.write(e); } //forEach函数 function forEach(fn) {//forEach:高阶函数 fn:回调函数 for (let i = 0; i < arr.length; i++) { fn(i); } } //调用forEach函数 forEach(print); //方法三:返回数组中所有的元素 for (let i = 0; i < arr.length; i++) { console.log(arr[i]); }
操作2:添加数组元素
1.直接修改数组的长度 myArray.length = n 2.通过索引添加 a[index] = n
操作3:删除元素的值
1.直接修改数组的长度 myArray.length = n 2.通过delete删除 delete myArray[1]
- 数组对象的方法
方法 | 描述 |
---|---|
concat() | 连接两个或多个数组,并返回已连接数组的副本。 |
copyWithin() | 将数组中的数组元素复制到指定位置或从指定位置复制。 |
entries() | 返回键/值对数组迭代对象。 |
every() | 检查数组中的每个元素是否通过测试。 |
fill() | 用静态值填充数组中的元素。 |
filter() | 使用数组中通过测试的每个元素创建新数组。 |
find() | 返回数组中第一个通过测试的元素的值。 |
findIndex() | 返回数组中通过测试的第一个元素的索引。 |
forEach() | 为每个数组元素调用函数。 |
from() | 从对象创建数组。 |
includes() | 检查数组是否包含指定的元素。 |
indexOf() | 在数组中搜索元素并返回其位置。 |
isArray() | 检查对象是否为数组。 |
join() | 将数组的所有元素连接成一个字符串。 |
keys() | 返回 Array Iteration 对象,包含原始数组的键. |
lastIndexOf() | 在数组中搜索元素,从末尾开始,并返回其位置。 |
map() | 使用为每个数组元素调用函数的结果创建新数组。 |
pop() | 删除数组的最后一个元素,并返回该元素。 |
push() | 将新元素添加到数组的末尾,并返回新的长度。 |
reduce() | 将数组的值减为单个值(从左到右)。 |
reduceRight() | 将数组的值减为单个值(从右到左)。 |
reverse() | 反转数组中元素的顺序。 |
shift() | 删除数组的第一个元素,并返回该元素。 |
slice() | 选择数组的一部分,并返回新数组。 |
some() | 检查数组中的任何元素是否通过测试。 |
sort() | 对数组的元素进行排序。 |
splice() | 从数组中添加/删除元素。 |
toString() | 将数组转换为字符串,并返回结果。 |
unshift() | 将新元素添加到数组的开头,并返回新的长度。 |
valueOf() | 返回数组的原始值。 |
6.RegExp正则表达式对象
**正则表达式:**定义字符串的组成规则
- 单个字符规则
[规则]:表示对单个字符的限制 [a]//表示字符串必须是a [ab]//表示字符串为a或b [a-bA-Z0-9_]//表示单个字符可以是a~b A~Z 0~9 _ * 特殊符号代表特殊含义的单个字符: \d:单个数字字符 [0-9] \w:单个单词字符[a-zA-Z0-9_]
- 量词的规则
?:表示出现0次或1次 *:表示出现0次或多次 +:出现1次或多次 {m,n}:表示 m<= 数量 <= n * m如果缺省: {,n}:最多n次 * n如果缺省:{m,} 最少m次
- 开始与结束
以^开始,以$结束
- 正则对象的创建
//方法一: let reg = new RegExp("正则表达式"); //方法二: let reg = /正则表达式/ 例子: let regExp = new RegExp("\\w{6,12}"); let regExp2 = /^\w{6,12}$/;
- 正则对象的方法
正则对象.text(字符串);//用于检验正则表达式是否合法,返回true或者false
8.Global全局对象
全局对象,这个Global中封装的方法不需要对象就可以直接调用: 方法名()
eval(“字符串”)函数
功能:将eval中的字符串参数作为脚本代码去执行
isFinite(数字)函数
检查某个值是否为有穷大的数。 ➢参数为有限值,返回值为ture。 ➢参数为非数字或者正、负无穷大,返回值为false。
isNaN()函数
检查某个值是否为数字(NaN与任何数逻辑运算均为NaN) ➢参数为数字,返回值为false 。 ➢参数为非数字,返回值为ture 。
parseInt(任意参数,[转换的进制])函数
➢参数第一个字符为数字字符串,返回值为number 。 ➢参数为非数字,返回值为NAN ➢将参数为非数字前的数字转成NaN返回
encodeURI():url编码
decodeURI():url解码
encodeURIComponent():url编码,编码的字符更多
decodeURIComponent():url解码
根据meta标签中charset编码方式对文字进行编码 decodeURI对服务器发送的内容进行解码
9.Object对象
- 定义格式
//方法一:在对象内部定义方法和属性 let 对象名 = { //定义属性 属性名1:属性值1, 属性名2:属性值2, //定义方法 /*1.可以采用匿名函数定义方法*/ 函数名称:function(形参列表){} /*2.简化的定义方式*/ 函数名称(形参列表){} } //方法二:在对象外部定义属性和方法 let 属性名1 = 属性值; let 属性名2 = 属性值; let 方法名 = function(形参列表){}; let 对象名 = {属性名1,属性名2,方法名};
- get和set方法
let stu = { name: null, get name() { console.log("进入了get"); return this._name; }, set name(name) { console.log("进入了set"); this._name = name; } } //在定义get和set方法的,在修改name属性的时候会自动调用get和set方法 stu.name = "yhw" console.log(stu.name) //在实践中,开发者经常使用_开头来表示某个属性是私有的,以便区分公共属性。这是一种约定俗成的做法,并没有强制规定。将name改为_name也可正常运行
- 属性的增删改
js 的对象,它的属性和方法可以随时加减
let stu = {name:'张三'}; // 添加属性 stu.age = 18; // 删除属性 delete stu.age; // 添加方法 stu.study = function() { console.log(this.name + "在学习"); } // 添加get和set方法:需要借助 Object.definePropery Object.defineProperty(对象名, "属性名", { //因为Object.definePropery方法已经定义了属性名,所以,无需再次在get和set方法定义属性名 get(){ return this.属性名; }, set(a){ this.属性名 = a; } });
- this关键字
js 中的 this 也是隐式参数,但它与函数运行时上下文相关
//情况一:当单独定义一个函数,使用this关键字全局对象 window被当作了this function study() { console.log(this.name); }//此时this.name为空字符串(==window.name) //情况二:如果作为对象的方法,this表示的是对象本身 let stu = { name:"lisi"; study() { console.log(this.name); } }//此时this.name为lisi(==stu.name) //情况三:动态指定this let stu = {name:"zhangsan"}; study.call(stu);//通过call指定study函数内的this为stu对象,因此会输出zhangsan
this关键字的一种易错情况
但是可以通过箭头函数解决这一问题,在**箭头函数**内出现的 this和它外层 this相同 let stu = { name: "小花", friends: ["小白","小黑","小明"], play() { this.friends.forEach(e => { console.log(this.name + "与" + e + "在玩耍"); }) } }
- 继承:原型继承
let father = { f1: '父属性', m1: function() { console.log("父方法"); } } let son = Object.create(father); console.log(son.f1); // 打印 父属性 son.m1(); // 打印 父方法
- father 是父对象,son 去调用 .m1 或 .f1 时,自身对象没有,就到父对象找
- son 自己可以添加自己的属性和方法
- son 里有特殊属性
__proto__
代表它的父对象,js 术语: son 的原型对象 - 不同浏览器对打印 son 的
__proto__
属性时显示不同- Edge 打印 console.dir(son) 显示
[[Prototype]]
- Firefox 打印 console.dir(son) 显示
<prototype>
- Edge 打印 console.dir(son) 显示
出于方便的原因,js 又提供了一种基于函数的原型继承
函数职责
负责创建子对象,给子对象提供属性、方法,功能上相当于构造方法
函数有个特殊的属性 prototype,它就是函数创建的子对象的父对象
**注意!**名字有差异,这个属性的作用就是为新对象提供原型
function cons(f2) { // 创建子对象(this), 给子对象提供属性和方法 this.f2 = f2; this.m2 = function () { console.log("子方法"); } } // cons.prototype 就是父对象 cons.prototype.f1 = "父属性"; cons.prototype.m1 = function() { console.log("父方法"); }
配合 new 关键字,创建子对象
let son = new cons("子属性")
子对象的 __proto__
就是函数的 prototype
属性
10.JSON对象
概念:JavaScript Object Notation, Javascript 对象标记法,是通过JavsScript对象标记法书写的文本
**作用:**多用于数据载体,在网络中进行数据传输
格式:
var 变量名 = ‘{"key1":value1, "key2":value2}'; value的数据类型为: 数字(整数或浮点数) 字符串(在双引号中) 逻辑值(true or false) 数组(在方括号中) 对象(在花括号中) null
方法:
- 将JSON转换为JS对象
var obj = JSON.parse(userString);
- 将JS对象转换为JSON字符串
var jsonStr = JSON.stringify(jsObject);
- json 中只能有 null、true|false、数字、字符串(只有双引号)、对象、数组
- json 中不能有除以上的其它 js 对象的特性,如方法等
- json 中的属性必须用双引号引起来