JS编写位置
- 可以将JS代码编写到标签的onclick属性中,当点击按钮(button)时,JS代码执行
<button onclick="alert('点我干嘛')">点我一下</button>
- JS代码可以写在a元素的href属性中,当点击超链接时执行
<a href="javascript:alert('好')">点我一下</a>
虽然可以直接写在标签的属性中,但是他们属于结构与行为耦合,不推荐使用
- 写在head中的script标签中
<script>
alert("这是我的第一行JS代码");
</script>
- 可以将JS写到外部js文件,然后通过script标签引入(src属性)。这种方式可以在不同的页面中同时引用,也利于浏览器的缓存机制。推荐使用。script标签一旦用于引入外部文件了,就不能再编写内部的代码了,即使写了,浏览器也会忽略。如果实在有需要,可以再心间一个script标签进行书写。
JS基本语法
-
多行注释/* */
-
//单行注释
-
JS中严格区分大小写
-
JS中每一条语句以分号结尾(如果不写分号,浏览器会自动添加,但是会消耗一些系统资源,而且有时候浏览器会加错分号,所以在开发中,分号必须写)
-
JS中会忽略多个空格和换行
字面量和变量
-
字面量是一些不可改变的量(常量)
-
变量可以用来保存字面量,更加方便我们使用,所以在开发中都是用变量来保存字面量,而很少直接使用字面量。
-
声明变量:使用var关键字来声明一个变量,还要为变量赋值var a=100; alert(a);
标识符
-
在JS中所有的可以由我们自主命名的都可以称为是标识符。例如变量名、函数名、属性名。
-
在命名标识符时需要遵守:
- 标识符中可以含有字母、数字、下划线_、$
- 不能以数字开头
- 标识符不能是JS中的关键字或者保留字
- 标识符一般都采用驼峰命名法:首字母小写,每个单词的开头字母大写,其余小写(helloWorld)
- JS底层保存标识符时,实际上是采用的Unicode编码,所以理论上讲,所有的utf-8中含有的内容都可以作为标识符。
数据类型
在JS中一共有六种数据类型
- String 字符串
-
在JS中字符串需要使用引号引起来 var str=“hello”;
-
使用双引号单引号都可以,但是不要混着用
-
引号不能嵌套,双引号里面不能放双引号,单引号里面不能放单引号。但可以双引号里面可以放单,单里面也可以放双。
-
在字符串中可以使用\作为转义字符,当表示一些特殊符号时可以使用\进行转义
"表示双引号
\n换行
'单引号
\t制表符
\表示\
var str = "我说:\"今天天气真不错\"";
- Number 数值
-
在JS中所有的数值都是Number类型,包括整数、浮点数
-
可以使用一个运算符typeof来检查一个变量的类型
语法 typeof 变量 console.log(typeof a) 返回数据类型 -
JS中表示数字的最大值 Number.MAX_VALUE (1.7976931348623157e+308)
如果使用Number表示的数字超过了最大值,会返回Infinity(字面量,类型是Number)表示正无穷
Number.MIN_VALUE(5e-324) 大于0的最小值 -
NaN 是一个特殊的数字(字面量,类型是Number),表示Not A Number
a="abc"*"dcf"
console.log(a);
输出NaN
- 在JS中整数的运算基本可以保证精准,如果进行浮点数的运算可能得到一个不精准的结果,所以不要使用JS进行对精确度较高的运算
- Boolean 布尔值
true/false,主要用来做逻辑判断
var bool=true ;
- Null 空值
NUll类型的值只有一个,就是null,专门用来表示一个为空的对象
var a=null;
使用typeof检查一个null值时,会返回object
- Undefined 未定义
Undefined类型的值只有一个,undefined,当声明一个变量但不给它赋值的时候时,它的值就是undefined
使用typeof检查,返回undefined
- Object 对象
1~5属于基本数据类型,6属于引用数据类型
强制类型转换
主要是将其他的数据类型转换为String,Number,Boolean
- 转String
方式一:
- 调用被转换数据类型的toString()方法
- 该方法不会改变原变量的数据类型,他会将转换的结果返回
- 但是null和undefined这两个值没有toString()方法,如果调用会报错。
var a=123;
var b=a.toString();//调用a的toString()方法
方式二:
- 调用String()函数,并将被转换的数据作为参数传递给函数
- 对于null和undefined不会报错。
var a=123;
var b=String(a);
- 转Number
方式一:
- 使用Number()函数,用法同上
- 字符串转数值的时候如果有非数字内容,转换为NaN;如果是空串或者全是空格,转为0
- 布尔转数字,true——1 ,false——0
- Null转数字,结果为0
- undefined转数字,结果为NaN
方式二:
- 专门用来对字符串
- parseInt()函数把一个字符串中有效的整数内容转换为Number(从前往后,遇到不是数字的就不继续读了,比如123a345——>123)
- parseFloat()函数 把一个字符串中有效的浮点数转换为浮点数
- 如果对非String使用两个函数,它会将其转换为String,然后再操作(可以利用parseInt(),将浮点数取整)
var a="123px";
var b=a.parseInt(a);
->
b=123
- 转换为Boolean
使用Boolean()函数
- Number转Boolean:0、NaN转换为false,其余的转换为true
- String转Boolean:除了空串为false,其余都是true
- null和undefined转Boolean,值为false
- 对象转换为true
其他进制的数字
- 16进制数字:以0x开头(a=0x123),输出的时候会以十进制输出
- 8进制,以0开头
- 2进制0b开头,但不是所有浏览器都支持
- 像"070"这种字符串,有些浏览器会当成8进制解析,有些会当成10进制解析。要使它转换为固定的进制,可以在函数后面传递第二参数,传递进制
var a="070";
a=parseInt(a,10);
算数运算符
当对非Number类型的值进行运算的时候,会将这些值转换为Number再运算
- 任何值和NaN做运算值都为NaN
- 任何值和字符串相加,都会转换为字符串,再运算
- 可以为任何数据类型+上一个空串,使该数据类型转换为String类型
逻辑运算符
- 非布尔值进行与或运算,先将其转换为布尔值,再运算
- 非布尔值进行与运算,如果第一个是true,则返回第二个(var a=1&&2 -> a=2),如果第一个是false,则直接返回第一个
- 非布尔值进行或运算,如果第一个是true,返回第一个,如果第一个是false,直接返回第二个
对象
属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性(类似结构体)
对象的分类
- 内建对象:由ES标准中文定义的对象,在任何的ES的实现中都可以使用
- 宿主对象:由JS的运行环境提供的对象,目前来讲主要指由浏览区提供的对象
- 自定义对象:由开发人员自己创建的对象
对象的基本操作
- 创建对象
var obj=new Object();
使用new关键字调用的函数,是构造函数constructor,构造函数是用来创建对象的函数
- 向对象中添加属性
在对象中保存的值称为属性,向对象添加属性语法:对象.属性名=属性值;
var obj=new Object();
obj.name="小明";
obj.gender="男";
obj.age=18;
console.log(obj);
- 读取对象中的属性
语法:对象.属性名
console.log(obj.name);
- 修改对象属性值
语法:对象.属性名=新值
- 删除对象的属性
语法:delete 对象.属性名
属性名和属性值
属性名:不强制要求遵循标识符的规范,什么都可以使用
如果要使用特殊的属性名,不能用.的方式来操作,要使用另一种方式,语法: 对象[“属性名”]=属性值,读取时也要采用这种方式
obj["123"]=789;
console.log(obj["123"]);
使用中括号中去操作属性,更加的灵活,在[]中可以直接传递一个变量
obj["123"]=789;
var n="123";
console.log(obj["123"]);
console.log(obj[n]);
// 两种方式是一样的
属性值:可以是任意数据类型(对象也可以)
var obj2=new Object();
obj2.name="小红";
obj.test=obj2;
console.log(obj.test.name);
// 取出obj中的test中的name,就是obj2的name小红
in运算符:通过该运算符来检查一个对象中是否含有指定的属性,有返回true,没有返回false
语法:“属性名” in 对象
console.log("test2" in obj);
// 检查obj里面有没有test2
方法
对象的属性值可以是任何的数据类型,也可以是函数,一个函数作为一个对象的属性值保存,那么我们称这个函数是这个对象的方法,调用这个函数就说是调用函数的方法。
var obj=new Objective;
obj.name="小明";
obj.age=18;
obj.sayname=function(){
console.log(obj.name);
};
function fun(){
console.log(obj.name);
};
// 调用方法(有一个.)
obj.sayname();
// 调用函数
fun();
// 只是名称上的区别,其实是一样
枚举对象中的属性
使用for··· in语句
语法:
for(var 变量 in 对象){
}
for in 语句中,对象有几个属性就会循环几次,每次执行时会将对象中的一个属性名赋值给变量
var obj={
name:"小明",
age:18,
gender:"男",
address:"小学路"
}
for(var n in obj){
console.log(n);
// 属性名
console.log([n]);
// 属性值,[]可以传变量
}
基本数据类型和引用数据类型
基本数据类型:String Number Boolean Null Undefined
引用数据类型:Object
JS中的变量都是保存到栈内存中的。
基本数据类型直接在栈内存中存储,值与值之间是独立存在,修改一个变量不会影响其他的变量
对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(类似指针)。
对象字面量
使用对象字面量来创建一个对象
var obj={};
使用对象字面量可以在创建对象时直接指定对象中的属性,语法:{属性名:属性值,属性名:属性值···}
var obj={
name:"小明",
age:18
};
对象字面量的属性名可以加引号也可以不加,建议不加。如果使用一些特殊的名字就必须加引号。
函数function
函数也是一个对象,函数中可以封装一些功能,需要时可以执行这些功能
创建函数对象
- 将要封装的代码以字符串的形式传递给构造函数。(很少用这种方法)
var fun = new Function("console.log('hello !')");
// 调用函数,语法:函数对象()
fun();
- 使用函数声明来创建一个函数
语法: function 函数名(形参1,形参2···){
语句
}
function fun2(){
console.log("第二行");
alert("123456");
}
// 调用
fun2();
- 使用函数表达式
语法: var 函数名=function(形参1···){
语句
}
立即执行函数
立即执行函数往往只会执行一次
(function(){
alert("我是一个匿名函数");
})();
(function(a,b){
console.log("a="+a);
console.log("b="+b);
})(123,456);
作用域
指一个变量作用的范围,在js中一共有两种作用域:全局作用域和函数作用域(局部作用域)
- 全局作用域
- 直接编写在script标签中的JS代码,都在全局作用域中
- 全局作用域在页面打开时创建,在页面关闭时销毁
- 在全局作用域中有一个全局对象window,他代表的是浏览器的一个窗口,他由浏览器创建,我们可以直接使用
- 在全局作用域中,创建的变量都会作为window对象的属性保存,创建的函数都会作为window对象的方法保存
- 全局作用域中的变量都是全局变量,在页面的任意部分都可以访问到
变量的声明提前:使用var关键字声明的变量,会在所有代码执行之前被声明(但不会被赋值),但是如果声明变量时不用var关键字,则变量不会被声明提前
console.log("a="+a);
var a=123;
// 会输出a=undefined 不会报错
// 相当于
var a;
console.log("a="+a);
a=123;
// 但是如果这样写就会报错
console.log("a="+a);
a=123;
函数的声明提前:
- 使用函数声明形式创建的函数function 函数(){},他会在所有代码执行之前就被创建,所以可以在函数声明前调用函数。
- 使用函数表达式 var fun=function(){}创建的函数不会被声明提前,所以不能在函数声明前调用函数。
- 函数作用域
- 调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
- 每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的
- 当函数作用域中操作变量时,他会先在自身作用域中找,如果有就直接使用,如果没有就在上一级中找
- 在函数里面想要访问全局中的变量,可以使用window对象
- 在函数作用域中也有声明提前的特性,使用var关键字声明的变量,会在函数中所有代码执行之前被声明,函数声明也会在函数中所有的代码执行之前声明
- 在函数中不使用var声明的变量都会成为全局变量
- 定义形参就相当于在函数作用域中声明了变量
this
解析器在调用函数的时候每次都会向函数内部传递进一个隐含的参数,这个隐含的参数就是this,this指向的是一个对象,这个对象我们成为函数执行的上下文对象。根据函数的调用方式的不同,this会指向不同的对象。
- 以函数的形式调用时,this永远都是window
- 以方法的形式调用时,this就是调用方法的对象
function fun(){
console.log(this.name);
}
var obj={
name:"小明",
sayName:fun
};
//两种调用方式一样,都会输出小明
fun();//this指向的是window,相当于window.fun()
obj.sayName();//this指向的是obj
var name="全局变量name";
fun();//相当于window.fun(),输出的是“全局变量name”
obj.sayName();//输出的是“小明”
使用工厂方法创建对象
通过该方法可以大批量创建对象
function createPerson(name,age,gender){
//创建一个新的对象
var obj=new Object();
//向对象中添加属性
obj.name=name;
obj.age=age;
obj.gender=gender;
obj.sayName=function(){
alert(this.name);
};
//将新的对象返回
return obj;
}
var obj2=createPerson("小明",18,"男");
使用工厂方法创建对象,使用的构造函数都是object,所以创建的对象都是object这个类型,就导致我们无法区分出多种不同类型的对象。
构造函数
创建一个构造函数,构造函数习惯上首字母大写,构造函数和普通函数的区别就是调用方式的不同,普通函数是直接调用,而构造函数需要使用new关键字来调用。
构造函数的执行流程
- 立刻创建一个新的对象
- 将新建的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象
- 逐行执行函数中的代码
- 将新建的对象作为返回值返回
使用同一个构造函数创建的对象称为一类对象,江南通过一个构造函数创建的对象称为该类的实例
function Person(name,age,gender){
this.name=name;//this就是新建的对象per
this.age=age;
this.gender=gender;
this.sayName=function(){
alert("hello,大家好,我是:"+this.name);
}
};
var per=new Person("小明",18,"男");
使用instanceof可以检查一个对象是否是一个类的实例,语法: 对象 instanceof 构造函数;
所有的对象都是object的后代,所以任何对象和object做instanceof返回值都是true
console.log(per instanceof Person);
//检查per是否是Person的实例,如果是返回true,否则返回false
this的情况
- 当以函数的形式调用时,this是window
- 当以方法的形式调用时,谁调用方法this是谁
- 当以构造函数形式调用时,this就是新创建的对象
在Person构造函数中,为每一个对象都添加了一个sayName方法,目前我们的方法是在构造函数内部创建的,也即是构造函数每执行一次就会创建一个新的sayName方法,执行1000次就会创建1000个新的方法,而1000个方法都是一样的,这是完全没有必要的,可以使用所有的对象共享同一个方法。
function Person(name,age,gender){
this.name=name;//this就是新建的对象per
this.age=age;
this.gender=gender;
this.sayName=fun();
};
//将sayName方法在全局作用域中定义
//但是将函数定义在全局作用域中会污染全局作用域的命名空间,而且也很不安全
function fun(){
alert("hello,大家好,我是:"+this.name);
};
var per=new Person("小明",18,"男");
var per=new Person("小红",18,"女");
原型
原型:prototype
我们所创建的每一个函数解析器都会向函数中添加一个属性prototype,这个属性对应着一个对象,这个对象就是我们所谓的原型对象。
如果函数作为普通函数调用,prototype没有任何作用;当函数以构造函数调用时他所创建的对象中都会有一个隐含的属性指向该构造函数的原型对象,我们可以通过__proto__来访问该属性。
function Myclass(){
}
var mc=new Myclass();
console.log(Myclass.prototype());
console.log(mc.__proto__);
console.log(Myclass.prototype()==mc.__proto__)//返回true
原型对象就相当于公共的区域,所有同一个类的实例都可以访问到这个原型对象。我们可以将对象中共有的内容统一设置到原型对象中
//向Myclass的原型中添加属性a
Myclass.prototype.a=123;
当我们访问对象的一个属性或方法时,会现在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找。
所以上面在全局作用域中定义函数sayName可以改成向原型中添加sayName方法
function Person(name,age,gender){
this.name=name;//this就是新建的对象per
this.age=age;
this.gender=gender;
this.sayName=fun();
}
Person.prototype.sayName= function(){
alert("hello,大家好,我是:"+this.name);
};
以后我们创建构造函数时,可以将这些对象共有的属性和方法统一添加到构造函数的原型对象中,这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法。
使用in检查对象中是否有某个属性时,如果对象中没有但是原型中有也会返回true。
检查是否有自己的属性:
function Myclass(){
}
Myclass.prototype.name="我是原型中的名字";
var mc=new Myclass();
//检查自身是否有某个属性时使用对象的hasOwnProperty来检查
console.log(mc.hasOwnProperty("name"));//返回false
//先在自身中找
console.log(mc.hasOwnProperty("hasOwnProperty"));//返回false
//再在原型中找
console.log(mc.__proto__.hasOwnProperty("hasOwnProperty"));//返回false
//在原型的原型中找
console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));//返回true
原型对象也是对象,所以他也有原型。
当我们在使用一个对象或方法
- 会先在自身中寻找,自身中如果有则直接使用;
- 如果没有则去原型对象中寻找,如果原型对象中有,则直接使用;
- 如果没有则去原型的原型中寻找,直到找到object对象的原型,object对象的原型没有原型,如果在object中仍然没有找到,则返回null
toString
当我们直接在页面中打印一个对象时,实际上是输出对象的toString()方法的返回值
如果我们希望在输出对象时,不输出[object,object],可以为对象添加一个toString()方法
function Person(name,age,gender){
this.name=name;
this.age=age;
this.gender=gender;
}
var per=new Person("小明",18,"男");
/*只能修改per的toString
per.toString=function(){
return "Person[name="+this.name+",age="+this.age+",gender="+this.gender+"]";
};
*/
//修改Person原型中的toString
Person.prototype.toString=f unction(){
return "Person[name="+this.name+",age="+this.age+",gender="+this.gender+"]";
};
//console.log(per)==console.log(per.toString)
console.log(per);//如果没有设置per.toString那么就是输出[object,object]
//设置之后就是输出对象具体信息
函数方法
- call()和apply():都需要通过函数对象来调用,当对函数调用call()和apply()都会调用函数执行
- 在调用call()和apply()可以将一个对象指定为第一个参数,此时这个对象会成为函数执行时的this
- call()方法可以将实参在对象之后依次传递 fun.call(obj,2,3); this是obj
- apply()需要将实参封装到数组中统一传递 fun.apply(abj,[2,3]);
this :
- 以函数形式调用,this是window
- 以方法形式调用,是调用方法的对象,谁调用的就是谁
- 以构造函数形式调用,this是新创建的对象
- 以call和apply调用时,this是指定的那个对象
arguments
在调用函数的时候,浏览器每次都会传递两个隐含参数
- 函数的上下文对象this
- 封装实参的对象arguments
- arguments是一个类数组对象,他也可以通过索引来操作数据,也可以获取长度
- 在调用函数时,我们所传递的实参都会在arguments中保存
- arguments.length可以用来获取实参的长度
- arguments[0]可以取出实参中第一个···
- 即使不定义形参,也可以通过arguments来使用实参
- arguments中有一个属性callee,这个属性对应一个函数对象,就是当前正在执行的函数对象
function fun(){
console.log(arguments.length);
console.log(arguments.callee==fun)//返回true
}
fun("hello",1,2);//输出3
垃圾回收GC
当一个对象没有任何的变量或属性对他进行引用,此时我们将永远无法操作该对象,此时这种对象是一个垃圾,这种对象过多会占用大量内存空间,导致程序运行变慢。所以这种垃圾必须进行清理。
在JS中拥有自动的垃圾回收机制,会自动将垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收的操作。
我们需要做的就是将不再使用的对象设置为null
var obj=new Object();
obj=null;//不需要这个对象了
数组array
数组也是一个对象,它和普通的对象功能类似,用来存储一些值的,不同的是普通对象是使用字符串作为属性名的,而数组是使用数字作为索引(index)操作元素的。
数组的存储性能比普通对象好,在开发中经常使用数组来存储一些数据。
//创建数组对象
var arr=new Array();
//向数组中添加元素,语法 数组[索引]=值
arr[0]=10;
//读取数组中元素,语法 数组[索引],如果读取不存在的索引,不会报错而是返回undefined
console.log(arr[0]);
//获取数组长度 语法 数组.length
console.log(arr.length);
//修改数组长度 语法 数组.length=
arr.length=10;
//向数组最后一个位置添加元素
arr[arr.length]=70;
使用字面量创建数组
//使用字面量创建数组
var arr=[];
//使用字面量创建数组的时候可以在创建时就指定数组中的元素
var arr=[1,2,3,4,5];
//使用构造函数创建数组时,也可以同时添加元素
var arr2=new Array(1,2,3);
arr=[10]; //创建一个数组,数组中只有一个元素10
arr2=new Array(10);//表示创建一个长度为10的数组
//数组中的元素可以是任意的数据类型,也可以是对象
arr=["hello",1,true];
var obj={name:"小明"};//或者直接arr=[{name:"小明"},{name:"小红"}];
arr[arr.length]=obj;
//也可以是函数
arr[function(){},function(){}];
数组的方法
- push()
- 向数组的末尾添加一个或多个元素,并返回数组的新的长度。
- 可以将要添加的元素作为方法的参数传递
var arr=["小明","小红","小粉"];
arr.push("小紫");//添加一个
var len=arr.push("小绿","小蓝");//添加多个
console.log(len);//len=6
- pop()
- 可以删除数组的最后一个元素,并返回被删除的元素
arr.pop();
- unshift()
- 向数组的开头添加一个或多个元素,并返回新的长度
- shift()
- 删除数组的第一个元素,并返回被删除的元素
- slice()
- 从某个已有的数组返回选定的元素
- 参数:start 截取开始的位置的索引;end截取结束的位置索引,包含开始不包括结束
- 该方法不会改变原数组,而是将截取到的元素封装到一个新数组返回
- 第二个参数可以省略不写,此时会截取从开始索引往后的所有元素
- 索引可以传递一个负值,表示从后往第前几个,-1倒数第一个,-2倒数第二个
var arr=["小明","小红","小蓝","小紫"];
var result=arr.slice(0,2);
console.log(result);
//返回小明和小红
//result=arr.slice(1,-1); 返回小红,小蓝
- splice()
- 删除数组中的指定元素并且添加元素
- 会影响到原数组,会将指定元素从原数组中删除,并返回删除的元素
- 参数 第一个start:开始位置索引;第二个end:表示表示删除的数量 第三个及以后:可以传递一些新的元素,这些元素将会自动插入到开始位置索引的前面
var arr=["小明","小红","小蓝","小紫"];
var result=arr.splice(0,2);
console.log(arr);//返回小蓝小紫
console.log(result);//返回小明小红
var result=arr.splice(0,1,"小绿");
- concat()
- 连接两个或多个数组,并将新的数组返回
- 该方法不会对原数组产生影响
var arr=["小明","小红","小蓝"];
var arr2=["小紫","小绿","小粉"];
var arr3=arr.concat(arr2);
console.log(arr3);
//还可以传多个数组 var arr4=arr.concat(arr2,arr3);
//还可以传元素 var arr4=arr.concat(arr2,arr3,"小黄");
- join()
- 将数组转换成字符串
- 该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回
- 在join()中可以指定一个字符串作为参数,这个字符串会成为数组元素中的连接符,默认是逗号
var arr=["小明","小红","小蓝"];
var result=arr.join("-");
console.log(result);//输出小明-小红-小蓝
- reverse()
- 颠倒数组顺序
- 该方法会改变原数组
var arr=["小明","小红","小蓝"];
arr.reverse();
console.log(arr);
- sort()
- 对数组中的元素进行排序
- 该方法会改变原数组
- 默认会按照Unicode编码进行排序(小的在前)
- 即使对于纯数字的数组,也会按照Unicode编码来排序,所以对数字进行排序时可能会得到错误的结果
var arr=["b","d","a","e","c"];
arr.sort();
console.log(arr);//输出abcde
- 可以自己制定排序规则,在sort()中添加一个回调函数,回调函数中需要定义两个形参,浏览器将会分别使用数组中的元素作为实参去调用回调函数(a一定是b前面的数)
- 浏览器会根据回调函数的返回值来决定元素的顺序
如果返回一个大于0的值,则元素会交换位置;
如果返回一个小于0的值,则元素位置不变;
如果返回0,则认为两个元素相等,不交换位置;
//从大到小
var arr=[5,4,7,9,11,1,3];
arr.sort(function(a,b){
if(a>b)
return -1;
else
return 1;
});
console.log(arr);
//简单代码
var arr=[5,4,7,9,11,1,3];
arr.sort(function(a,b){
return b-a;//降序
});
console.log(arr);
数组的遍历
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.toString=function(){
return "Person[name="+this.name+",age="+this.age+"]";
}
var per=new Person("小明",18);
var per2=new Person("小红",28);
var per3=new Person("小紫",8);
var per4=new Person("小粉",16);
var per5=new Person("小蓝",38);
var perArr=[per,per2,per3,per4,per5];
//创建一个函数将perArr中的满18岁的Person提取出来,封装到一个新的数组返回
//arr形参
function getAdult(arr){
var newArr=[];
for(var i=0;i<arr.length;i++){
if(arr[i].age>=18){
newArr.push(arr[i]);
}
}
return newArr;
}
var result=getAdult(perArr);
console.log(result);
forEach()方法遍历
- 用来遍历数组,这个方法只支持IE8以上的浏览器
- forEach()方法需要一个函数作为参数
- 像这种函数由我们创建但是不由我们调用(称为回调函数)
- 数组中有几个元素函数就会执行几次,每次执行时,浏览器将会遍历到的元素以实参的形式传进来,我们可以定义形参来读取这些内容
- 浏览器在回调函数中会传递三个参数:
value:当前正在遍历的元素;
index:当前正在遍历的元素的索引;
obj:正在遍历的数组;
var arr=["小明","小红","小蓝","小紫"];
arr.forEach(function(value,index,obj){
console.log(value);
});
Math
- Math和其他对象不同,他不是一个构造函数,它属于工具类,不同创建对象,它里面封装了数学运算相关的属性和方法
- Math.PI 表示圆周率 console.log(Math.PI);
- Math.ceil()向上取整
- Math.floor()向下取整
- Math.round()四舍五入
- Math.random()生成0-1之间的随机数,生成x-y之间的随机数Math.round(Math.random()*(y-x)+x);
包装类
- 在JS中为我们提供了三个包装类,通过这三个包装类可以将基本数据类型转换为对象
- String()
可以将基本数据类型字符串转换为String对象 - Number()
可以将基本数据类型数值转换为Number对象 - Boolean()
可以将基本数据类型布尔值转换为Boolean对象
//创建一个Number类型的对象
var num=new Number(3);
console.log(num);
注意:在实际应用中不会使用基本数据类型的对象,如果使用基本数据类型的对象在做一些比较时可能带来一些不可预料的结果。
方法和属性只能添加给对象,不能添加给基本数据类型
var s=123;
//当我们对一些基本数据类型的值去调用属性和方法时,浏览器会临时使用包装类将其转换为对象,然后再调用对象的属性和方法。在调用完后,再将其转换为基本数据类型。
s=s.toString();
console.log(s);//输出123
console.log(typeof s);//输出string
s.hello="你好";//给s添加属性,这时候会临时将s转换为对象,在这个临时的对象中添加属性,因为对象是临时的,添加完之后,这个对象就销毁了。
console.log(s.hello);//不会报错,会输出undefined,调用s的hello属性时临时将s转换为对象,在这个临时新建的对象中去找hello属性,这个临时的对象中没有这个属性,所以输出undefined
所以平时是可以直接调用基本数据类型的方法的,因为浏览器会自己临时将基本数据类型转换为对象,再调用
字符串的方法
-
大部分不会对原字符串产生影响
-
在底层字符串是以字符数组的形式保存的
-
charAt()返回字符串中指定位置的字符,根据索引获取指定字符 str.charAt(0)
-
charCodeAt()返回字符串指定位置字符的Unicode编码
-
fromCharCode()根据字符编码获取字符,要通过构造函数来调用String.fromCharCode()
-
concat()连接两个或多个字符串
-
indexOf()检索一个字符串中是否含有指定内容,返回其第一次出现的索引位置,如果没有指定内容返回-1
```JavaScript var str="hello h2020"; var result=str.indexOf("l"); console.log(result);//输出2 var result=str.indexOf("h",1);//可以指定第二个参数表示从索引为1的位置开始查找 console.log(result);//返回6 ```
-
lastIndexOf() 和indexOf用法一样,不同的是,indexOf是从前往后,lastIndexOf是从后往前找
-
slice()截取指定字符串,第一个参数:开始位置的索引,包括;第二个参数:结束位置的索引,不包括,第二个参数可以省略,如省略,则会截取从开始位置到最后。如果为负数,表示倒数第几个位置
```JavaScript var str="hello h2020"; var result=str.slice(0,3);//从0位置开始,截取3位置之前的 console.log(result);//输出hel ```
-
substring()和slice类似,不同的是substring不接受负值,如果使用默认为0,而且会自动调整参数位置,如果第二个参数小于第一个会交换位置。
-
split() 将字符串拆分为数组
```JavaScript var str="abc,bac,feg,sgh"; res=str.split(",");//根据,来拆分 console.log(res);//长度为4的数组 ```
-
toUpperCase()和toLowerCase()将字符串中的小写字母转换为大写;将大写转换为小写