
对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。
对象的分类内建对象:由ES标准定义的对象,在任何ES的实现中都可以使用,比如Math、String、Number……
宿主对象:由JS运行环境提供的对象,主要指由浏览器提供的对象,比如BOM、DOM……
自定义对象:由开发人员自己创建的对象
创建一个对象:var obj = new Object();
向对象添加属性:obj.属性名 = 属性值;
读取对象的属性:obj.属性名;
删除对象的属性:delete obj.属性名;
如果读取对象中没有的属性,不会报错,而是会返回undefined。
对象['属性名'] = 属性值;,读取时也要采用这种方式。使用[]去 *** 作属性更加灵活,在[]中可以直接传递一个变量,这样,变量值是多少,就会读取那个属性。比如:
var obj = new Object();
obj["123"] = 789;
var n = "123";
console.log(obj[n]);
JS的属性值可以是任意的数据类型,可以是基本数据类型,可以是对象,可以是函数。检查一个对象中是否含有指定的属性:"属性名" in 对象,返回值 true 或 false
基本数据类型和引用数据类型
JS中的变量都保存在栈内存中:
基本数据类型的值直接在栈内存中存储,值与值之间独立存在,修改一个变量不会影响其他的变量;对于引用数据类型,变量保存的是对象的地址,对象保存在堆内存中,每创建一个新的对象,就会在堆内存中开辟出一个新的空间。如果两个变量保存的是同一个地址,那么修改一个变量之后,另一个会跟着改变。 对象字面量 {} 使用对象字面量来创建一个对象:var obj = {};在创建时指定属性:var obj = { 属性名:属性值, 属性名:属性值, ……};
对象字面量的属性名可以加引号也可以不加,建议不加;如果要使用一些特殊的名字,则必须加引号。
属性名和属性值是一组一组的名值对结构,名和值之间用 : 连接,多个名值对之间用 , 隔开。
函数也是一个对象,可以封装一些功能,在需要时执行这些功能。函数对象也可以有属性。
创建一个函数对象:var func = new Function(); 此时 typeof func 返回值为 function。可以将要封装的代码以字符串的形式传递给构造函数,封装到函数中的代码不会立即执行,而是在函数调用的时候执行。调用函数:func(); 此时函数中封装的代码会按顺序执行。函数声明:
function 函数名([形参1, 形参2, ..., 形参N]){
函数语句...
}
函数表达式:创建一个匿名函数,再将这个匿名函数赋值给一个对象。
var 函数名 = function([形参1, 形参2, ..., 形参N]){
语句...
}
参数
举例:
function sum(a,b){
return a + b;
}
\qquad
调用函数时解析器不会检查实参的类型,所以要注意是否会接收到非法的参数,如果有可能,则需要对参数进行类型检查。
\qquad
调用函数时解析器也不会检查实参的数量,多余实参不会被赋值。如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined。
实参可以是任意的数据类型。
\qquad
如果return后面不跟任何值或者函数中不写return,都会返回一个undefined。
\qquad 返回值可以是任意数据类型,当然可以是一个对象,也可以是一个函数。
立即执行函数\qquad 函数定义完后立即被调用,这种函数往往只会执行一次。举例:
(function(a,b){return a+b;})(123,456);
函数的方法 call() 和 apply()
\qquad
对于一个函数fun(),可以调用上述两个方法:fun.call(); fun.apply();
\qquad
调用时可以指定一个对象作为第一个参数,此时这个对象就会成为函数执行时的 this;后面传入的参数都会作为实参传递给函数fun(); 注意:call() 方法可以将实参在对象之后依次传递,apply()方法需要将实参封装到一个数组中统一传递。
\qquad 在调用函数时,浏览器每次会传递进两个隐含的参数,第一个是函数的上下文对象this,第二个是封装实参的对象arguments。
arguments 是一个类数组对象,也可以通过索引来 *** 作数据,可以获取长度;调用函数时,所有的实参都会在 arguments 中保存,arguments.length就是实参的数量;即使不定义形参,也可以通过arguments来使用实参;属性callee对应了当前正在执行的函数对象;
方法
\qquad 如果一个函数作为一个对象的属性保存,那么这个函数称为对象的方法,调用这个函数称为“调用对象的方法”。
枚举对象中的属性语法:for(var 变量 in 对象){ *** 作变量的语句 }
\qquad
对象中有几个属性,循环体就会执行几次;每次执行时,会将对象中的一个属性的名字赋值给变量,可以用obj[变量]取出该属性的值。
var obj = {
name:"kirlant";
age:18;
gender:"female",
address:"empire"
};
for(var n in obj){
console.log(obj[n]);
}
作用域
作用域指定一个变量的作用范围。
变量的声明提前 使用 var 关键字声明的变量会在所有代码执行之前被声明;如果不使用 var 关键字,就不会被声明提前。
函数的声明提前 使用函数声明形式 function 函数名(){} 创建的函数会在所有代码执行之前被创建,所以可以在函数声明之前调用函数;使用函数表达式创建的函数则不会被声明提前。
直接编写在script标签中的代码都在全局作用域中;
全局作用域在页面打开时创建,在页面关闭时销毁;
在全局作用域中,有一个全局对象window,代表浏览器的窗口,由浏览器创建,可以直接使用;
在全局作用域中,创建的变量都会作为window对象的属性保存,创建的函数都会作为window对象的方法保存;
全局作用域中的变量都是全局变量,在页面的任意部分都可以访问到。
调用函数时创建函数作用域,函数执行完毕后作用域销毁;
每调用一次函数,就会创建一个新的函数作用域,它们之间是互相独立的;
函数作用域中可以访问到全局作用域的变量,而全局作用域中无法访问到函数作用域的变量;
当在函数作用域中 *** 作一个变量时,它会先在自身作用域中寻找,如果有就直接使用,没有就向上一级作用域中寻找;如果直到全局作用域都没有找到,才会报错;
在函数中如果想访问全局变量,可以使用window对象;
在函数作用域中也有声明提前的特性,只是被提前声明,不会一起提前赋值;
函数声明也会在所有代码执行之前被声明;
在函数中,不使用var声明的变量都会成为全局变量;
定义形参就相当于在函数作用域中声明了变量,不传参就相当于变量是undefined。
浏览器在调用函数时,每次都会向函数内部传递一个隐含的参数this;
this指向一个对象,称为函数执行的上下文对象,根据函数的调用方式不同,this会指向不同的对象:
定义一个方法,大批量创建对象:
创建一个新的对象;向对象中添加属性和方法;将新的对象返回;function creatNewObject(name, age, gender, ads){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.address = ads;
obj.sayName = function(){
alert(this.name);
}
return obj;
}
使用的构造函数都是Object,所以创建的对象都是Object类型,不方便区分对象 ⟶ \longrightarrow ⟶ 创建一个构造函数,专门用来创建一类对象,函数首字母大写。
构造函数构造函数要通过 new 关键字调用。执行流程:
使用同一个构造函数创建的对象称为一类对象,也将构造函数称为一个类。将通过一个构造函数创建的对象称为该构造函数(或者该类)的实例。
function Person(name, age, gender, ads){
this.name = name;
this.age = age;
this.gender = gender;
this.address = ads;
this.sayName = function(){
alert(this.name);
}
}
var pers = new Person("kirlant", 16, "female", "empire");
console.log(typeof pers);
console.log(pers);
pers.sayName();
运行结果:
object
Person {
name: 'kirlant',
age: 16,
gender: 'female',
address: 'empire',
sayName: [Function (anonymous)]
}
kirlant
检查一个对象是否是一个类的实例:对象 instanceof 构造函数;返回值为 true 或 false。
所有的对象都是Object的后代,所有任何对象进行 instanceof Object 时,返回的都是 true。
将函数定义在全局作用域中会污染全局作用域的命名空间,而且不安全。
自行创建的每一个函数中,都会被解析器添加一个属性 prototype,对应着一个对象,即原型对象。prototype保存了原型对象的地址,是唯一的。当函数作为普通函数调用prototype时,没有任何作用;当函数以构造函数形式调用时,它创建的对象中都会有一个属性prototype,指向该构造函数的原型对象,可以通过__proto__来访问该属性。
原型对象相当于一个公共区域,所有同一个类的实例都可以访问到这个原型对象,因此,可以将所有对象中共有的内容统一设置到原型对象中。
当我们访问一个对象的一个属性或方法时,先在对象自身中查找,如果有就直接使用,如果没有就去原型对象中寻找,找到了就直接使用。
function Person(name, age, gender, ads){
this.name = name;
this.age = age;
this.gender = gender;
this.address = ads;
}
//向原型中添加公共方法
Person.prototype.sayName = function(){
console.log(this.name);
}
var pers = new Person("kirlant", 16, "female", "empire");
console.log(typeof pers);
console.log(pers);
pers.sayName();
运行结果:
object
Person {
name: 'kirlant',
age: 16,
gender: 'female',
address: 'empire'
}
kirlant
检查对象自身(而不是原型对象)中是否含有某个属性:对象.hasOwnProperty(属性);返回值为 true 或 false。
原型对象也是对象,所以原型对象中也有__proto__
⟶
\longrightarrow
⟶ 调用一个对象的属性或方法时,先在自身中寻找,找不到就去原型对象中寻找,再找不到则去原型对象的原型对象中寻找,直到找到Object对象的原型。Object对象的原型没有原型,其__proto__属性值对应的是null,Object对象的原型中依然找不到就返回undefined。
console.log(pers.toString());
运行结果:
[object Object]
可以根据需要重写该函数。
垃圾回收程序运行过程中会产生垃圾,垃圾积攒过多会导致程序运行时间变慢
⟶
\longrightarrow
⟶ 需要一个垃圾回收机制处理程序运行过程中产生的垃圾。
当一个对象没有任何变量或属性对它进行引用,它就变成了垃圾,这种对象过多会占用大量内存导致程序运行变慢,所以需要对它进行清理。JS中有自动的垃圾回收机制,会自动将它们从内存中销毁,我们不需要也不能进行垃圾回收的 *** 作。我们需要做的只是将不再使用的对象设置为null。
创建数组对象:var arr = new Array();可以在创建时指定数组元素var arr = new Array(1, 2, 3);
添加元素:数组[索引] = 值;
读取元素:数组[索引];如果读取不存在的索引,不会报错而会返回一个undefined。
获取数组长度:数组.length;可以修改数组的长度数组.length = 值;如果修改的长度大于原来的长度,那么多余部分会空出来;如果小于原来的长度,那么多余部分会被删除。向数组的最后一个位置添加元素:arr[arr.length] = 值;
使用字面量创建数组:var arr = [];可以在创建时指定数组元素var arr = [1, 2, 3];
数组中的元素可以是任意数据类型,可以是对象,可以是函数。
数组的常用方法:
push() 向数组末尾添加一个或多个元素,并返回数组新的长度;pop() 删除并返回数组的最后一个元素;unshift() 向数组开头添加一个或多个元素,并返回数组新的长度;shift() 删除并返回数组的第一个元素;slice() 从数组中提取指定位置的元素,切片:var get = arr.slice(0,2);索引前闭后开;如果第二个参数不写,那么会截取从start索引开始往后的全部元素;索引如果传递一个负值,则从后往前计算;splice() 删除指定位置的元素,并将被删除的元素作为返回值返回:var del = arr.slice(startIdx, delNums, [addElement1, addElement2, ...]);从startIdx开始,删除delNums个元素,然后在startIdx前插入addElement1, addElement2,…;concat() 连接两个或多个数组,并将新的数组返回;join() 将数组转换为一个字符串,不会对原数组产生影响,而是将转换后的字符串作为结果返回;可以指定一个字符串作为数组中元素的连接符:var result = arr.join(mystr);默认用","连接;reverse() 反转数组,直接修改原数组;sort() 对数组中的元素进行排序,直接修改原数组;默认按照Unicode编码进行排序,因此对数字排序可能得到错误的结果;
⟶
\longrightarrow
⟶ 添加回调函数指定排序规则:arr.sort( function(a,b){return a-b;} );注意:数组中,a要在b之前;浏览器根据回调函数的返回值决定元素的顺序,如果返回值小于等于0,那么不交换元素位置,如果返回值大于0,那么交换元素位置;
遍历数组
方法一:for
for(var i=0; i<arr.length; i++){
console.log(arr[i]);
}
方法二:forEach()
\qquad
forEach()方法需要一个函数作为参数,该函数由我们创建但不由我们调用,称为回调函数。数组中有几个元素函数就会执行几次,每次都将遍历到的元素以实参的形式传入函数中,因此可以定义形参来读取这些内容。
\qquad
浏览器会向回调函数中传入三个参数:当前遍历到的元素,当前元素的索引,当前正在遍历的数组。
// IE8及以下的浏览器均不支持该方法
arr.forEach(function(value, index, obj){
console.log(value);
console.log(index);
console.log(obj);
});
日期 Date
JS中使用Date对象来表示一个时间。
创建对象:var d = new Date(); 此时默认值为当前代码执行的时间;
创建指定时间对象:var d = new Date("12/03/2016 11:10:30"); 字符串格式:月/日/年 时:分:秒
获取当前日期对象的时间戳:getTime(),从格林威治标准时间1970.01.01 00:00:00 到当前日期花费的毫秒数;计算机底层保存时间时使用的都是时间戳;
获取当前的时间戳:Date.now();
工具类,封装了数学运算相关的属性和方法。
向上取整:Math.ceil()
向下取整:Math.floor()
四舍五入:Math.round()
生成一个0~1之间的随机数:Math.random(),不包括0和1
计算x的y次幂:Math.pow(x,y)
包装类将基本数据类型转换为对象:String、Number、Boolean。当对一些基本数据类型调用属性和方法时,浏览器会临时使用包装类将其转换为对象,然后调用对象的属性和方法,调用完以后,再将其转换回基本数据类型。
字符串 String字符串在底层以字符数组的形式保存,因此 *** 作方法和 *** 作数组类似。
属性:length,用来获取字符串的长度;
方法:charAt() 返回字符串中指定位置的字符;
\qquad \,
charCodeAt() 获取指定位置字符的Unicode编码;
\qquad \,
String.fromCharCode() 根据字符编码获取字符;
\qquad \,
indexOf() 检索字符串中是否含有指定内容,返回值为该内容第一次出现的索引,没有则返回-1;可以指定第二个参数为开始查找的位置;
\qquad \,
lastIndexOf() 从后向前检索字符串中是否含有指定内容;
\qquad \,
slice(startIdx, endIdx) 截取指定位置字符串的内容(前闭后开),返回截取的内容,不影响原字符串;endIdx可省略,此时截取从startIdx开始的所有内容;索引若为负数,则从后向前数;
\qquad \,
substring(startIdx, endIdx) 和slice()类似;参数不能传负数,如果传入了负值则默认使用0;会自动调整参数的位置,如果startIdx>endIdx,会自动交换两个参数;
\qquad \,
substr(startIdx, nums) 从startIdx开始截取nums个字符;
\qquad \,
split(str) 以str为拆分位置,拆分字符串为字符串数组;如果传入空串,则会将每个字符都拆分开;
\qquad \,
toUpperCase() 将字符串转换为大写并返回;
\qquad \,
toLowerCase() 将字符串转换为小写并返回;
\qquad
正则表达式定义了一些字符串的规则,计算机根据正则表达式来检查一个字符串是否符合规则,或提取字符串中符合规则的内容。
创建正则表达式对象:var reg = new RegExp("正则表达式", "匹配模式");使用typeof检查正则对象会返回object;匹配模式有两种:i 忽略大小写,g 全局匹配模式;
使用字面量创建正则表达式:var reg = /正则表达式/匹配模式;
举例:
var reg = new RegExp("a", "i");
var reg = /a/i;
正则表达式中的一些逻辑符:
| [] 或;
[a-z] 任意小写字母;
[A-Z] 任意大写字母;
[A-z] 任意字母;
[^ ] 除了括号里的xxx;
[0-9] 任意数字;
[^0-9] 除了数字;
方法:reg.test(str) 检查字符串str是否符合正则表达式reg的规则,返回true或false;
字符串和正则表达式
var str = "1a2b3c4d5e";
方法:str.split();将一个字符串拆分为数组,可以传递一个正则表达式作为参数,方法就会根据正则表达式拆分字符串;不需要设置全局匹配也会全部拆分;
\qquad \,
str.search();搜索字符串中是否含有指定内容,如果找到了就返回第一次出现的位置,如果没有返回-1;可以接收正则表达式;即使设置了全局匹配也只搜索第一个;
\qquad \,
str.match();根据正则表达式将字符串中符合条件内容提取出来;默认情况下只找第一个符合条件的内容,可以设置正则表达式为全局匹配,就能找到所有内容;可以设置多个匹配模式,顺序无所谓;匹配到的内容被封装到一个数组中返回;
\qquad \,
str.replace(被替换内容(可以用正则表达式),新内容); 将字符串中的指定内容替换为新的内容;默认只替换第一个;
正则表达式的语法
量词: 设置一个内容出现的次数
\qquad \,
{n}花括号前的内容恰好出现n次,只对它前面的一个内容起作用;
\qquad \,
{n1,n2}出现n1~n2次;
\qquad \,
{n1, }出现n1次以上;
\qquad \,
(){n}小括号中的内容恰好出现n次;
\qquad \,
+ 前面的内容出现至少一次;
\qquad \,
* 前面的内容出现0次或多次,等同于{0, };
\qquad \,
? 前面的内容出现0次或1次,等同于{0, 1};
\qquad \,
^ 开头;
\qquad \,
$ 结尾;
如果在正则表达式中同时使用^和$,则要求字符串必须完全符合正则表达式。
元字符: 具有特殊意义的字符
\qquad \,
. 任意字符
\qquad \,
\ 转义字符;使用构造函数时,由于它的参数是字符串,而\是一个转义字符,因此在字符串中使用\转义其他字符时需要写\;
\qquad \,
\w 任意字母、数字、_;等同于[A-z0-9_];
\qquad \,
\W 除了字母、数字、_;等同于[^A-z0-9_];
\qquad \,
\d 任意数字;等同于[0-9];
\qquad \,
\D 除了数字;等同于[^0-9];
\qquad \,
\s 空格;
\qquad \,
\S 除了空格;
\qquad \,
\b 单词边界;
\qquad \,
\B 除了单词边界;
单词边界举例:检查是否含有某个单词时,在这个单词前后加上 \b,就不会查到以这个单词为组成部分的更长的单词。即两个\b中间是一个独立的单词。
var reg = /\bchild\b/g;
var find = "hello child";
console.log(reg.test(find)); // true
find = "hello children";
console.log(reg.test(find)); // false
练习:
创建一个正则表达式,检查字符串是否是手机号
// 以1开头,第二位数字只能是3~9,然后跟着9位任意数字,结束
var reg = /^1[3-9][0-9]{9}$/g;
var phone = "18763370911";
console.log(reg.test(phone));
接收一个用户的输入:
var userName = prompt("请输入用户名:");
console.log(userName);
去除字符串前后的空格:
\qquad \,
使用空串替换空格,注意中间位置的空格不应该去掉。
\qquad \,
思路:全局匹配开头的一个或多个空格,或结尾的一个或多个空格,都用空串替换。
var userName = " Garcia Kirlant ";
userName = userName.replace(/^\s*|\s*$/g,"");
console.log(userName); // Garcia Kirlant
邮件的正则:
\qquad \,
以任意字母、数字、下划线开头(^),5位以上;
\qquad \,
一个@;
\qquad \,
网站名称,一次以上的数字或字母;
\qquad \,
一到两次域名(.com, .cn什么的);每个域名长度为2~5,包括一个.和后面的字母;
\qquad \,
一个结束符$;
var reg = /^\w{5,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;
console.log(reg.test("2427369255@qq.com")); // true
console.log(reg.test("2427369255@qq.com.3")); // false
文档对象模型 Document Object Model ( DOM )
JS中通过DOM来对HTML文档进行 *** 作。
文档:整个的HTML网页文档;
对象:将网页中的每个部分都转换为了一个对象;之后就可以以面向对象的形式 *** 作网页;
模型:使用模型来表示对象之间的关系,方便我们获取对象;
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)