JS基础语法
一、类型转换
很多时候,我们在进行数据运算或输出等操作时需要将数据在不同类型之间进行转换,
在
JS 数据类型转方法主要有三种: 利用 js 变量弱类型自动转换、
转换函数、强制类型转换。
1.自动类型转换
2、函数转换
parseInt()
1、parseInt()在转换之前,首先会分析该字符串,判断位置为 0
处的字符,判断它是否是个有效数字,如果不是,则直接返回
NaN,不再继续,如果是则继续,直到找到非字符
2、parseInt()方法还有基模式,可以把二进制、八进制、十六进制或其他任何进制的字符串转换成整数。基是由
parseInt()方法的第二个参数指定的
3、如果十进制数包含前导 0,那么最好采用基数
10,这样才不会意外地得到八进制的值
parseFloat()
parseFloat()方法与
parseInt()方法的处理方式相似,但是parseFloat()可以识别第一个小数点
3、显示转换
toString()函数将内容转换为字符串形式,其中 Number 提供的
toString()函数可以将数字以指定的进制转换为字符串,默认为十进制。
Number 还提供了
toFixed()函数将根据小数点后指定位数将数字转为字符串,四舍五入
4、强制转换
JS 为 Number、Boolean、String
对象提供了构造方法,用于强制转换其他类型的数据。
此时操作的是整个数据,而不是部分。
<script type="text/javascript">
// parseInt()
console.log(parseInt("123ab1c")); // 123
console.log(parseInt("123.4.5ab1c")); // 123
console.log(parseInt("0xA")); //returns 10
console.log(parseInt("22.5")); //returns 22
console.log(parseInt("blue111")); //returns NaN
console.log(parseInt("AF", 16)); //returns 175
console.log(parseInt("10", 2)); //returns 2
console.log(parseInt("10", 8)); //returns 8
console.log(parseInt("10", 10)); //returns 10
console.log(parseInt("010")); //returns 8
console.log(parseInt("010", 8)); //returns 8
console.log(parseInt("010", 10)); //returns 10
console.log("==========================");
// parseFloat()
console.log(parseFloat("123ab1c")); // 123
console.log(parseFloat("123.4ab1c")); // 123
console.log(parseFloat("0xA")); //returns 10
console.log(parseFloat("22.5")); //returns 22
console.log(parseFloat("blue111")); //returns NaN
console.log("====================显式转换==========");
var data = 10;
console.log(data.toString())
console.log(data.toString(2))
data = 1.4;
console.log(data.toFixed(0));
data = 1.49;
console.log(data.toFixed(1));
data = true;
console.log(data.toString());
console.log("===================强制转换==========");
console.log(Number("1"));
console.log(Number("1.4"));
console.log(Number("123aabc"));
console.log(Number("abc"));
console.log(Number(true));
console.log(Number(false));
console.log(Number(19));
console.log(Number(new Object()));
console.log(Number(new Array()));
</script>
二、数组
1.数组(array)是按次序排列的一组数据,每个值的位置都有编号(从 0
开始),整个数组
用方括号表示。 Js 中定义数组的三种方式如下(也可先声明再赋值) :
var arr=[值 1,值 2,值 3]; //隐式创建
var arr=new Array(值 1,值 2,值 3); //直接实例化
var array=new Array(size); //创建数组并指定长度
2.数组的特点:
1)、数组的长度是可变的
2)、数组的类型可以不一样
3)、不存在下标越界
3、数组的遍历
数组的遍历即依次访问数组的每一个元素 ,JS 提供三种遍历数组的方式:
1)、普通 for 循环遍历
for(var i = 0; i < 数组名.length; i++) {
}
注:可以拿到undefinded的值,无法获取数组中属性对应的值
2)、for ... in
for(var i in 数组) {
// i是下标或属性名
}
注:无法拿到undefinded的值,可以获取数组中属性对应的值
3)、foreach
数组.foreach(function(element,index){
// element:元素;index:下标
});
注:无法获取属性对应的值与undefinded的值
* for -- 不遍历属性
* foreach -- 不遍历属性和索引中的 undefined
* for in -- 不遍历索引中的 undefined
console.log("=======数组的遍历=========");
// 1、普通 for 循环遍历
for (var i = 0; i < arr1.length; i++) {
console.log(i + "----------" + arr1[i]);
}
console.log("===============");
// for... in
for (var i in arr1) {
console.log(i + '----------' + arr1[i]);
}
console.log("===============");
// foreach
arr1.forEach(function(elem,index){
console.log(index+ '----' + elem);
});
4、数组提供的方法
push 添加元素到最后
unshift 添加元素到最前
pop 删除最后一项
shift 删除第一项
reverse 数组翻转
join 数组转成字符串
indexOf 数组元素索引
slice 截取(切片)数组,原数组不发生变化
splice 剪接数组,原数组变化,可以实现前后删除效果
concat 数组合并
array.splice(index,howmany,item1,.....,itemX)
参数 描述
index 必需。规定从何处添加/删除元素。
该参数是开始插入和(或)删除的数组元素的下标,必须是数字。
howmany 必需。规定应该删除多少元素。必须是数字,但可以是 "0"。
如果未规定此参数,则删除从 index 开始到原数组结尾的所有元素。
item1, ..., itemX 可选。要添加到数组的新元素
Type 描述
Array 如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组。
console.log("========数组提供的方法=======");
console.log(arr2);
arr2.push("dd"); // 数组的最后添加元素
arr2[arr2.length] = "ee";
console.log(arr2);
arr2.unshift("hello");
console.log(arr2);// 数组的最前面添加元素
// 分割数组
var str = arr2.join("-");
console.log(str);
// 将字符串转换成数组
var strarr = str.split("-");
console.log(strarr);
三、 函数
函数, 即方法。
就是一段预先设置的功能代码块,可以反复调用,根据输入参数的不同,
返回不同的值。 函数也是对象。
1、函数的定义
定义方式有3种:
1)、函数声明语句
function 函数名([形参]) {
}
调用:函数名([实参]);
2)、函数定义表达式
var 变量名/函数名 = function([形参]){
}
调用:变量名([实参])/函数名([实参]);
3)、Function构造函数
var 函数名 = new Function('参数1','参数2','函数的主体内容');
调用:函数名([实参]);
注:构造韩束的最后一个参数是函数体。
注意:
1)、js 中的函数没有重载,同名的函数,会被后面的函数覆盖。
2)、js 中允许有不定数目的参数,后面介绍 arguments 对象
函数名的提升(了解)
JavaScript 引擎将函数名视同变量名,所以采用 function
命令声明函数时,整个函数会像变量声明一样,被提升到代码头部。所以,下面的代码不会报错
但是,如果采用赋值语句定义函数,JavaScript 就会报错。
<script type="text/javascript">
/* 函数的定义 */
// 1、函数声明语句
function fn1(a,b) {
console.log(a+b);
}
fn1(1,1);
// 2、函数定义表达式
var fn2 = function(x){
console.log(x);
}
console.log(fn2);
fn2(10);
// 3、Function构造函数
var fn3 = new Function('x','y','console.log(x+y);')
fn3(1,2);
fn4();
/*函数名的提升*/
function fn4() {
console.log("函数名的提升。。。。");
}
fn5();
var fn5 = function(){
console.log("函数名的提升...");
}
</script>
2. 函数的参数、调用和 return 语句
2.1参数
函数运行的时候,有时需要提供外部数据,不同的外部数据会得到不同的结果,这种外部
数据就叫参数,定义时的参数称为形参,调用时的参数称为实参
实参可以省略,那么对应形参为 undefined
若函数形参同名(一般不会这么干):在使用时以最后一个值为准。
可以给参数默认值: 当参数为特殊值时,可以赋予默认值。
参数为值传递, 传递副本 ; 引用传递时传递地址,操作的是同一个对象。
2.2函数的调用
1、常用调用方式:函数名([实参]);
存在返回值可以变量接收,若接收无返回值函数则为 undefined
2、函数调用模式
3、方法调用模式
4、call()和apply()
javascript 中函数也是对象,函数对象也可以包含方法。 call()和 apply()方法可以用来间
接地调用函数。任何函数可以作为任何对象的方法来调用,哪怕这个函数不是那个对象的方
法。两个方法都可以指定调用的实参。 call()方法使用它自有的实参列表作为函数的实参,
apply()方法则要求以数组的形式传入参数
注:谁调用函数,this就指向谁
匿名函数立即调用
(1)匿名函数:function ([参数]){}
(2)调用:(function ([形参]) {})([实参]);
在函数只被使用一次的情况下可以使用这种方式,简便省事
2.3 return 语句
函数的执行可能会有返回值,需要使用 return 语句将结果返回。return
语句不是必需的,
如果没有的话,该函数就不返回任何值,或者说返回 undefined。
作用:在没有返回值的方法中,用来结束方法。
有返回值的方法中,一个是用来结束方法,一个是将值带给调用者。
<script type="text/javascript">
/* 参数 */
// 1、实参可以省略,那么对应形参为 undefined
function fn1(a,b) {
console.log(a);
}
fn1();
fn1(1);
fn1(1,2);
// 2、若函数形参同名(一般不会这么干):在使用时以最后一个值为准。
function fn2(x,x){
console.log(x);
}
fn2(10,20);
// 3、可以给参数默认值:当参数为特殊值时,可以赋予默认值。
function fn3(str) {
str = str || "Hello";
console.log(str);
}
fn3();
fn3("你好");
function fn4(str) {
(str !== undefined && str !== null) ? str = str : str = "值不存在";
console.log(str);
}
fn4();
fn4("你好呀");
// 4、参数为值传递,传递副本 ;引用传递时传递地址,操作的是同一个对象
// 值传递
var num = 10;
function fn5(n) {
n = 20;
}
fn5(num);
console.log(num);
// 引用传递
var arr = [1,2,3];
var obj = {
uname:"zhangsan"
};
function fn6(a,b) {
a[0] = 100;
b.uname = "lisi";
}
fn6(arr,obj);
console.log(arr);
console.log(obj);
function fn7(a,b) {
a = [4,5,6];
b = {
uname:"wangwu"
};
}
fn7(arr);
console.log(arr);
console.log(obj);
console.log("===============函数的调用==============");
// 直接调用
function fn8() {
console.log(this); // Window对象
}
fn8();
// 函数调用模式
var fn9 = function() {
console.log(this); // Window对象
return 1;
}
var f = fn9();
console.log(f);
// 方法调用模式
var obj = {
uname:"zhangsan",
uage:18,
cats:["喵喵","猫猫"],
sayHello:function() {
console.log(this); // obj对象
console.log("你好呀~");
}
};
console.log(obj.sayHello);
obj.sayHello();
// 间接调用
var obj2 = {};
function fn10(x,y) {
console.log(x+y);
console.log(this);
}
fn10(1,2); // Window对象
fn10.call(); // Window对象
fn10.call(obj2); // obj2
fn10.call(obj2,10,20); // obj2
fn10.apply(obj2,[100,200]); // obj2
console.log("===============匿名函数立即调用==============");
(function(a,b) {
console.log(a-b);
})(10,2);
</script>
2.3. arguments 对象和函数的方法及属性
arguments 对象中存放了调用该函数时传递的实际参数。由于 JavaScript
允许函数有不定数目的参数,所以我们需要一种机制,可以在函数体内部读取所有参数,这就是
arguments
对象的由来 。函数中可以使用 arguments 对象来获取实参。
函数名.name 得到函数名称
函数名.length 得到函数的形参数量
函数名.toString() 得到函数的源码
<script type="text/javascript">
function fn1 (a,b,c) {
// arguments对象可以得到函数的实参数量
console.log(arguments.length);
console.log("函数....");
console.log(arguments);
}
fn1(1,2);
console.log(fn1.name);
console.log(fn1.length);
console.log(fn1.toString());
</script>
2.4函数的作用域
函数作用域:全局(global variable)和局部(local variable)
1)全局变量与局部变量同名问题
2)在函数中定义变量时,若没有加 var 关键字,使用之后自动变为全局变量
3)变量作用域提升
<script type="text/javascript">
var num = 1;
function fn() {
var num = 10; // 这是个局部变量,与全部变量毫无关系
console.log(num); // 就近原则
var b = 2; // 局部变量
c = 3; // 不用var修饰符声明的变量时全局变量
}
fn();
console.log(num);
//console.log(b);
console.log(c);
function foo(x) {
if (x > 100) {
var tmp = x - 100;
}
console.log(tmp);
}
function foo(x) {
var tmp;
if (x > 100) {
tmp = x - 100;
}
console.log(tmp);
}
foo(1);
</script>
2.5 闭包
出于种种原因,我们有时候需要得到函数内的局部变量。但是,正常情况下,这是办不到
的,只有通过变通方法才能实现。那就是在函数的内部,再定义一个函数。
闭包就是能够读取其他函数内部变量的函数。由于在 Javascript
语言中,只有函数内部的\子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,
在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变
量,另一个就是让这些变量的值始终保持在内存中。
以及还可以避免变量名冲突的问题。
闭包的形成:
1、外部函数内部嵌套内部函数
2、内部函数中使用外部函数的环境
3、外部函数返回内部函数
闭包的作用:
1、获取函数内部的变量
2、保存变量的值在内存中
3、避免变量名重复
<script type="text/javascript">
// 1、外部函数内部嵌套内部函数
function fn1() {
var a = "Hello!";
function fn2() {
// 2、内部函数中使用外部函数的环境
console.log(a);
}
// 3、外部函数返回内部函数
return fn2;
}
var f = fn1();
console.log(f);
f();
function test() {
var num = 1;
num++;
console.log(num);
}
test();
test();
test();
console.log("====================");
// 1、外部函数内部嵌套内部函数
function outFn() {
var num = 1;
function inFn(){
// 2、内部函数中使用外部函数的环境
num++;
console.log(num);
}
// 3、外部函数返回内部函数
return inFn;
}
var inF = outFn();
inF();
inF();
inF();
inF();
var inF1 = outFn();
inF();
console.log("===========浇水实例=========");
document.write("==========浇水实例=========<br>");
// 定义外部函数,设置形参(水壶的容量)
function waterFlower(total) {
// 定义内部函数,执行浇水过程 (每次浇水,水容量减50ml)
function water(flower) {
// 当水容量大于50ml则浇水
if (total >= 50) {
// 每次浇水减50
total = total - 50;
} else {
// 如果没水,则自动加水
document.write("<h4>正在重新装水....</h4>");
total = 200;
// 浇水
total = total - 50;
//
}
document.write("给"+flower+"浇水50ml,剩余" + total + "ml的水!<br>");
}
// 返回内部函数
return water;
}
// 装水
var t = waterFlower(200);
// 浇水
t("桃花");
t("兰花");
t("玫瑰花");
t("菊花");
t("桂花");
</script>
2.6 JS 内置对象
Arguments 只在函数内部定义,保存了函数的实参
Array 数组对象
Data 日期对象,用来创建和获取日期
Math 数学对象
String 字符串对象,提供对字符串的一系列操作
String:
◦ charAt(idx):返回指定位置处的字符
◦ indexOf(Chr):返回指定子字符串的位置,从左到右。找不到返回-1
◦ substr(m,n):返回给定字符串中从 m 位置开始,取 n 个字符,如果参数 n 省略,
则意味着取到字符串末尾。
◦ substring(m,n):返回给定字符串中从 m 位置开始,到 n 位置结束,如果参数 n 省
略,则意味着取到字符串末尾。
◦ toLowerCase():将字符串中的字符全部转化成小写。
◦ toUpperCase():将字符串中的字符全部转化成大写。
◦ length: 属性,不是方法,返回字符串的长度。
Math:
◦ Math.random()
◦ Math.ceil() :天花板 大于最大整数
◦ Math.floor() :地板 小于最小整数 String
Date:
//获取
◦ getFullYear()年, getMonth()月, getDate()日,
◦ getHours()时,getMinutes()分,getSeconds()秒
//设置
◦ setYear(), setMonth(), ...
◦ toLoacaleString()
说明
1.getMonth():得到的值: 0~11(1 月~12 月)
2.setMonth():设置值时 0~11
3.toLocaleString():可根据本地时间把 Date 对象转换为字符串,并返回结果。
<script type="text/javascript">
// 得到系统当前时间
var mydate = new Date();
console.log(mydate);
// toLocaleString():可根据本地时间把 Date 对象转换为字符串,并返回结果。
console.log(mydate.toDateString());
console.log(mydate.toLocaleString());
var mon = mydate.getMonth()+1;
if (mon < 10) {
mon = "0" + mon;
}
var newDate = mydate.getFullYear() + "-" + mon + "-" + mydate.getDate();
newDate += " " + mydate.getHours() + ":" + mydate.getMinutes() + ":" + mydate.getSeconds();
console.log(newDate);
</script>
2.7 JS 对象
对象(object)是 JavaScript 的核心概念,也是最重要的数据类型。
JavaScript 的所有数
据都可以被视为对象。 JavaScript 提供多个内建对象,比如 String、 Date、
Array 等等。对象是带有属性和方法的特殊数据类型。
简单说,所谓对象,就是一种无序的数据集合,由若干个"键值对"(key-value)构成。通
过 JavaScript 我们可以创建自己的对象。 JavaScript
对象满足的这种"键值对"的格式我们成为JSON 格式,
以后会见得非常多,即伟大的 JSON 对象。
1、定义对象
JS 创建自定义对象,主要通过三种方式:
1)、字面量形式创建对象
var 变量名 = {}; // 空对象
var 变量名 = {键:值,....};
2)、通过 new Object 对象创建
var 变量名 = new Object();
3)、通过 Object 对象的 create 方法创建对象
var 变量名 = Object.create(null或对象);
// 1、字面量形式创建对象
var obj = {}; // 空对象
var obj2 = {
uname:"zhangsan",
uage:18
};
obj2.usex=true;
console.log(obj);
console.log(obj2);
// 2、通过 new Object 对象创建
var obj3 = new Object();
obj3.name = "Tom";
console.log(obj3);
// 3、通过 Object 对象的 create 方法创建对象
var obj4 = Object.create(null);
console.log(obj4.uname);
var obj5 = Object.create(obj2);
console.log(obj5.uname);
// 2、通过 new Object 对象创建
console.log('============序列化和反序列化============');
var str = '{"uname":"zhangsan", "uage":18 }';
// 反序列化:将字符串转换成对象
var object1 = JSON.parse(str);
console.log(object1);
console.log(object1.uname);
// 序列化,将对象转换成字符串
var json1 = JSON.stringify(object1)
console.log(json1);
console.log(json1.uname);
2、对象的序列化和反序列化
序列化即将 JS 对象序列化为字符串,反序列化即将字符串反序列化为 JS 对象。
JS 中通过调用 JSON
方法,可以将对象序列化成字符串,也可以将字符串反序列化成对象 。
- 序列化对象,将对象转为字符串
JSON.stringify(object)
- 反序列化,将一个 Json 字符串转换为对象。
JSON.parse(jsonStr)
console.log('============序列化和反序列化============');
var str = '{"uname":"zhangsan", "uage":18 }';
// 反序列化:将字符串转换成对象
var object1 = JSON.parse(str);
console.log(object1);
console.log(object1.uname);
// 序列化,将对象转换成字符串
var json1 = JSON.stringify(object1)
console.log(json1);
console.log(json1.uname);
3、eval()
1、可借助 eval()动态函数,将参数字符串解析成 js
代码来执行,只接受原始字符串作为参数
eval("console.log('你好')");//控制台输出你好
2、可将 json 串转为 json 对象
1)第一种解析方式:得到的 json 对象名就是 jsonObj
eval("var jsonObj = " + jsonStr);
2)第二种解析方式:对象中有多个属性
var jsonObj = eval("(" + jsonStr + ")");
由于 json 是以{ }的方式来开始以及结束的,在 eval
中会被当成一个语句块来处理,故必
须强制将它转换成一种表达式。加上圆括号是使 eval
函数在处理时强制将括号内的表达式转化为对象而不作为语句来执行。
3)第二种解析方式:对象中只有一个属性
eval(jsonStr);
console.log("=============eval()============");
console.log('你好');
eval("console.log('你好')");//控制台输出你好
// 1)第一种解析方式:得到的 json 对象名就是 jsonObj
var ab = '{"uname":"zhangsan", "uage":18 }';
eval("var jsonObj = " + ab);
console.log(jsonObj);
// 2)第二种解析方式:对象中有多个属性
var jsonObj2 = eval("(" +ab + ")");
console.log(jsonObj2);
var arrStr = "[1,'1a','fg']";
// 第一种解析方式eval("var arrObj = " + arrStr);
eval("var arr=" + arrStr);
console.log(arr);
// 第二种解析方式:eval(arrStr);
console.log(arrStr);
console.log(eval(arrStr));
2.8 this
**
**this 是 JavaScript 语言的一个关键字。
它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。
随着函数使用场合的不同, this 的值会发生变化。但是有一个总的原则,那就是
this 指的
是,调用函数的那个对象。
在函数中使用 this
**
**在函数中使用 this 属于全局性调用,代表全局对象,通过 window
对象来访问。
function test () {
this.x = 1;
console.log(this.x);
}
test();
console.log(x);//相当于定义在全局对象上的属性
var x = 10;
console.log(x) // 10
function test (){
console.log(this.x) //10
this.x = 1;
console.log(this.x) //1
console.log(this)
}
test()
console.log(x) //1
console.log(this)