JavaScript语法讲解

javascript数据类型和变量

js是弱类型语言,支持变量声明,存在作用范围,有局部变量和全局变量之分。

1.定义变量

隐式定义:直接给变量赋值;

现实定义:使用var关键字定义变量。

隐式定义:

<script type="text/javascript">
    a="See me";
    alert(a);
</script>    

显示定义:

<script type="text/javascript">
   var a="See me";
    alert(a);
</script>

2.类型转换

js支持自动类型转换:

<script type="text/javascript">
    var a="3.125";
    var b=a-2;
    var c=a+2;
    alert(b+"\n"+c);
</script>

减号自动识别为算术运算,加号识别为字符串运算。

强制类型转换:

toString():将布尔值,数值等转换为字符串

parseInt():将字符串,布尔值等转换为整型

parseFloat():将字符串,布尔值等转换为浮点型

其中parseInt()和parseFloat()只能将带数字的字符串且开头是数字的数字部分转换。

<script type="text/javascript">
    var a="3.125";
    var b=parseFloat(a)+2;
   
    alert(b);
</script>

3.作用域

全局变量:在全局范围(不在函数内)定义的变量,不使用var定义的变量。可以被所有脚本访问;

局部变量:在函数内定义的变量,只在函数内有效。当局部变量与全局变量同名时,局部变量会覆盖全局变量。

4.变量提升

<script type="text/javascript">
    var a="全局变量";
    function test(){
	document.writeln(a + "<br>");
		var a="局部变量";
		document.writeln(a + "<br>");
	} 
  test();
</script>

在这里插入图片描述
之所以发上上述情况,是因为js运行机制使得变量声明总是被解释器提升到函数体的顶部,上述程序等同于如下代码:

<script type="text/javascript">
    var a="全局变量";
    function test(){
	var a;
	document.writeln(a + "<br>");
		var a="局部变量";
		document.writeln(a + "<br>");
	} 
  test();
</script>

变量提升只是提升变量的声明部分,而不是提升变量的赋值部分。

基本数据类型

JavaScript中有五种基本数据类型,它们分别是:数值类型,布尔类型,字符串类型,undefined类型,null类型。
undefined类型只有一个值,这个值就是它自己本身(undefined),在使用var声明变量但未对其进行初始化时,比较这个变量与undefined字面量,结果表明它们是相等的。
数值类型
与强类型语言如C、Java不同,JavaScript的数值类型不仅包括所有的整形变量,也包括所有的浮点型变量。JavaScript语言中的数值都是以IEEE 754双精度浮点数格式保存。JavaScript中的数值形势非常丰富,完全支持用科学计数法表示。科学计数法形如5.12e2代表5.12乘以10的2次方,5.12E2也代表5.12乘以10的2次方。
科学计数法中E为间隔符号,E不区分大小写。
当数值类型超出了其表述范围时,将出现两个特殊值:Infinity(正无穷大)和-Infinity(负无穷大。)
字符串类型
JavaScript的子串富川必须用引号括起来,此处的引号既可以是单引号,也可以是双引号。
注意:JavaScript和Java中的字符串主要有两点区别:

(1)JavaScript中的字符串可以用单引号括起来;

(2)JavaScript中比较两个字符串的字符序列是否相等使用 == 即可,无需使用equals()方法。

JavaScript以String内建类表示字符串,String类里包含了一系列方法操作字符串,String类有如下基本方法和属性操作字符串:

(1)charCodeAt() :返回字符串中特定索引处的字符所对应的Unicode值

(2)Legth():返回字符串的长度

(3)toUpperCase() : 将stringObj中的小写字母全部转成大写字母

(4)toLowerCase() :将stringObj中的大写字母全部转成小写字母

(5)fromCharCode() :直接通过String类调用方法,将一系列Unicode值转换成字符串

(6)indexOf() :返回字符串第一次出现的位置

(7)lastIndexOf() :返回字符串最后一次出现的位置

(8)subString() :截取stringObj从start开始,至end为止之前的所有字符,即包括start处的字符,但不包含end处的字符

(9)slice() :截取stringObj从start开始,到end为止之前的所有字符;即包括start处的字符,但不包括end处的字符。start与end均可为负值,当为负值时,表示从最后一个字符算起的第n个字符,比如-1表示最后一个字符,-2表示倒数第二个字符。

(10)match() :在字符串内检索指定的正则表达式的匹配结果,该结果与regexp是否有指定全局标志g有关

(11)split() :将separtor为为分隔,将stringObj分割成一个字符串数组。separator可以是字符串或者正则表达式,若为字符串,则以separator为分割符;弱separator为正则表达式,则以符合separator指定模式的字符串作为分隔符。

(12)replace() :将字符串中某个子串以特定字符串替代。

null类型:
null类型和undefined类型一样,这个值也就是它本身。从逻辑角度,null值表示一个空对象指针。如果定义的变量将用于保存对象,最好将该变量初始化为null。
boolean类型
bool值就只有两个值,true和false。任何数据类型要将一个值转换相应的boolean值,可以调用函数boolean();

复合类型

1、Object:对象

(1)对象:是一系列命名变量和函数的集合

(2)对象中的命名变量称为属性,而对象中的函数称为方法

(3)对象访问属性和函数的方法都是通过“.”

2、Array:数组

(1)数组是一系列的变量

(2)语法格式

A、var a = [1,2,3,4,5,6];

B、var b = [];

C、var c = new Array();

(3)数组的特征

JavaScript数组的长度可变
同一个数组里数组元素的类型可以互不相同
访问数组元素时不会产生数组越界,访问未赋值的数组元素时,该元素的值为undefined

3、Function:函数

(1)JavaScript函数无须声明返回值类型

(2)JavaScript函数无须声明形参类型

(3)JavaScript中函数可以独立存在,无须属于任何类

(4)JavaScript函数必须使用function关键字定义

运算符

JavaScript中运算符主要用于连接简单表达式,组成一个复杂的表达式。常见的有算数表达式、比较表达式、逻辑表达式、赋值表达式等,也有单目运算符,指操作原始表达式。大多数运算符都由标点符号组成(+、>=、!),也有关键字表示的运算符,如typeof、delete、instanceof等。

赋值运算符
赋值运算符用于给变量赋值,最常见的赋值运算符,当然就是等号,表达式x=y表示将y赋值给x。除此之外,JavaScript还提供其他11个赋值运算符。

x += y // 等同于 x = x + y
x -= y // 等同于 x = x - y
x *= y // 等同于 x = x * y
x /= y // 等同于 x = x / y
x %= y // 等同于 x = x % y
x >>= y // 等同于 x = x >> y
x <<= y // 等同于 x = x << y
x >>>= y // 等同于 x = x >>> y
x &= y // 等同于 x = x & y
x |= y // 等同于 x = x | y
x ^= y // 等同于 x = x ^ y

算数运算符
加法运算符(Addition):x + y
减法运算符(Subtraction): x - y
乘法运算符(Multiplication): x * y
除法运算符(Division):x / y
余数运算符(Remainder):x % y
自增运算符(Increment):++x 或者 x++
自减运算符(Decrement):–x 或者 x–
求负运算符(Negate):-x
数值运算符(Convert to number): +x

位运算符
或运算(or):符号为|,表示两个二进制位中有一个为1,则结果为1,否则为0。
与运算(and):符号为&,表示两个二进制位都为1,则结果为1,否则为0。
否运算(not):符号为~,表示将一个二进制位变成相反值。
异或运算(xor):符号为ˆ,表示两个二进制位中有且仅有一个为1时,结果为1,否则为0。
左移运算(left shift):符号为<<
右移运算(right shift):符号为>>
带符号位的右移运算(zero filled right shift):符号为>>>

比较运算符
比较运算符比较两个值,然后返回一个布尔值,表示是否满足比较条件。JavaScript提供了8个比较运算

== 相等
=== 严格相等
!=不相等
!== 严格不相等
< 小于
<= 小于或等于

>大于
>= 大于等于

逻辑运算符
逻辑运算符通常用于布尔值的操作,一般和关系运算符配合使用,有三个逻辑运算符:逻辑与(AND)、逻辑或(OR)、逻辑非(NOT)。

逗号运算符
逗号运算符用于对两个表达式求值,并返回后一个表达式的值。

void
void运算符的作用是执行一个表达式,然后返回undefined。

流程控制

(1)顺序控制
(2)分支控制
让程序有选择的执行,分支控制有三种
①单分支②双分支③多分支

①单分支
if(条件表达式){
语句;
}
②双分支
if(条件表达式){
语句;
}else{
语句;
}
③多分支
if(条件表达式1){
//执行
}else if(条件表达式2){
//执行
}else if…{
//可以有多个else if
}
else{
//可以没有
}

多分支 switch
switch(条件表达式){
case 常量1:
语句; break;
case 常量2:
语句; break;

case 常量n:
语句; break;
default:
语句;
}
注意:case有几个都行,default可以没有。当case1~n都不满足的时候,则default。default并不一定要在最后。

(3)循环控制
循环控制有三种
①for循环
for(循环初值;循环条件;步长){
语句; //循环体
}
②while循环
while(循环条件){
语句; //循环体
}

特别说明:while循环是先判断再执行语句。
③do while循环
do{
语句;//循环体
}
while(循环条件);
特别说明:do while循环是先执行,再判断。
while和do while区别的通俗讲解:
还钱的问题
while:上来先问你还不还钱,还钱,就不打你(先判断,再执行)
do while:上来先打一顿,打完了再问,还钱吗(先执行,再判断)

函数

定义函数的3种方式
命名函数,匿名函数,使用Function类匿名函数。

递归函数
递归函数是一种特殊的函数,递归函数允许在函数定义中调用函数本身。

var factorial = function(n)
{
	if (typeof(n) == "number")
	{
		if (n == 1)
		{
			return 1;
		}
		else
		{
			return n * factorial(n - 1);
		}
	}
	else
	{
		alert("参数类型不对!");
	}
}
alert(factorial(6));

局部变量和局部函数
如果局部变量和全局变量的变量名相同,局部变量会覆盖全局变量,局部变量只能在函数里访问,全部变量可以在所有的函数里访问。
局部函数与之类似,局部函数也在函数里定义,如:

function outer()
{
	function inter1()
	{
		document.write("1111<br/>");
	}
	function inter2()
	{
		document.write("2222<br/>");
	}
	document.write("测试<br/>");
	inter1();
	niter2();
	document.write("结束<br/>");
}
document.write("调用全局之前<br/>");

document.write("调用全局之后<br/>");

函数,方法,对象,变量,类
函数:函数可以被调用。
对象:定义一个函数时,系统也会创建一个对象,该对象是Function类的实例。
方法:定义一个函数时,该函数通常会附加给某个对象,作为该对象的方法。
变量:在定义函数的同时,也会得到一个变量。
类:在定义函数的同时,也得到一个与函数同名的类。

var hello = function(name)
{
	return name + ",您好";
}
alert("hello是否为Function对象"+(hello instanceof Function)
	+"\nhello是否为Object对象"+(hello instanceof Object));
alert(hello());

定义一个函数后,可以直接调用函数,也可以使用new关键字调用函数。

var test = function(name)
{
	return "您好,"+name;
}
var rval = test('leegang');
var obj = new test('leegang');
alert(rval+"\n"+obj);

下面定义了一个Person函数,也就是定义了一个Person类,该Person函数也会作为Person类唯一的构造器。

function Person(name,age)
{
	this.name = name;
	this.age = age;
	this.info = function()
	{
		document.writeln("我的名字是:"+this.name+"<br/>");
		document.writeln("我的年级是:"+this.age+"<br/>");
	};
}
var p = new Person('ly',26);
p.info();

函数的实例属性和类属性

函数中的变量

局部变量:在函数中以var声明的变量。
实例属性:在函数中以this前缀修饰的变量。
类属性:在函数中以函数名前缀修饰的变量。

看如下代码:

function Person(national,age)
{
	this.age = age;
	Person.national = national;
	var bb = 0;
}
var p1 = new Person('中国',29);
document.writeln("创建第一个Person对象<br/>");
document.writeln("p1的age属性为"+p1.age+"<br/>");
document.writeln("p1的national属性为"+p1.national+"<br/>");
document.writeln("通过Person访问静态national属性为"+Person.national+"<br/>");
document.writeln("p1的bb属性为"+p1.bb+"<br/><hr/>");
var p2 = new Person('美国',32);
document.writeln("创建两个Person对象之后<br/>");
document.writeln("p1的age属性为"+p1.age+"<br/>");
document.writeln("p1的national属性为"+p1.national+"<br/>");
document.writeln("p2的age属性为"+p2.age+"<br/>");
document.writeln("p2的national属性为"+p2.national+"<br/>");
document.writeln("通过Person访问静态national属性为"+Person.national+"<br/>");

这里的this.age = age;是实例属性,也就是对象属性
Person.national = national是类属性,可以与java中的static一起理解
var bb = 0;这个是局部变量

调用函数的三种方式

直接调用函数

function fun(){
	console.log("aaa");
}
fun();

用call方法调用函数

var each = function(array,fn){
	for(var index in array){
		fn.call(null,index,array[index]);
	}
}
each([4,20,3],function(index,ele){
	console.log(index+" " + ele);
})	
这里面的call可以调用函数的引用,动态调用函数,call的第一个参数可以改变对象的作用域
和this的指向,为null时默认为全局作用域。

apply方法调用
这个和call是一样得到,就是传递参数的时候是1以数组的形式,对于参数很多的函数调用,很有用。

var each = function(array,fn){
	for(var index in array){
		fn.apply(null,[index,array[index]]);
	}
}
each([4,20,3],function(index,ele){
	console.log(index+" " + ele);
})	

函数提升
典型的函数提升,就是在同一个<script…/>元素内,JS允许先调用函数,然后在后面再定义函数,举个简单的例子如下:

<script>
	//先调用add函数
	alert(add(2,5));
	//后定义add函数
	function add(a,b)
	{
		return a+b;
	}
</script>

上面的代码先调用add()函数,再定义函数,完全可以正常执行.这是因为JS会将add()函数提升到<script…/>元素的顶端,也就是说,上面这段代码,和下面这段代码是一样的效果,代码如下:

<script>
	//定义add函数
	function add(a,b);
	{
		return a+b;
	}
	//调用add函数
	alert(add(2,5))
</script>

局部函数会被提升到所在函数的顶部
例如如下代码:

<script>
	function test()
	{
		//先调用add函数
		alert(add(2,5));
		//后定义add函数
		function add(a,b)
		{
			return a+b;
		}
	}
	test();
</script>

上面JS代码在test()函数中定义了一个局部函数add(),JS会将add()函数提升到test()函数的顶端,因此可以先调用add()函数,再定义.

特别注意: 如果局部函数为匿名函数,然后将匿名函数赋值给add局部变量,对于使用这种方式定义的函数,JS将只提升add变量,但函数定义本身并不会被提升.还是会发生如下报错:在这里插入图片描述

面向对象

继承和prototype

所有的JavaScript对象之间并没有明显的继承关系。而且JavaScript是一种动态语言,它允许自由地为对象增加属性和方法。
当定义函数时,函数中以this修饰的变量是实例属性,如果某个属性值是函数时,即可认为该属性变成了方法。如下:

function Person(name,age){
	this.name = name;
	this.age = age;
	this.info = function(){
		document.writeln("姓名:" + this.name + "<br/>");
		document.writeln("年龄:" + this.age + "<br/>");
	}
}
var p1 = new Person('yeeku',29);
p1.info();
Person.prototype.walk = function(){
	document.writeln(this.name + '正在慢慢溜达...<br/>');
}
document.writeln('<hr/>');
var p2 = new Person('leegang',30);
p2.info();
document.writeln('<hr/>');
p2.walk();
p1.walk();

通过使用prototype属性,可以对JS的内建类进行扩展。下面代码为JS内建类Array增加了indexof方法,该方法用于判断数组中是否包含了某元素。

Array.prototype.indexof = function(obj)
{
	var result = -1;
	for (var i=0;i<this.length;i++)
	{
		if(this[i] == obj)
		{
			result = i;
			break;
		}
	}
	return result;
}
var arr = [4,5,7,-2];
alert(arr.indexof(-2));

此外,JS类的prototype属性代表了该类的原型对象。在默认情况下,JS类的prototype属性值是一个Object对象,将JS类的prototype设为父类实例,可实现JS语言的继承。代码如下:

function Person(name,age){
	this.name = name;
	this.age = age;
	this.sayHello = function(){
		console.log(this.name + "向您打招呼!");
	}
}
var per = new Person('牛魔王',22);
per.sayHello();
function Student(name,age,grade){
	this.grade = grade;
}
Student.prototype = new Person("未命名",0);
Student.prototype.intro = function(){
	console.log("%s是个学生,读%d年级",this.name,this.grade);
}
var stu = new Student(5);
stu.name =("孙悟空");
console.log(stu instanceof Student );
console.log(stu instanceof Person );
stu.sayHello();
stu.intro();

构造器实现伪继承
下面再介绍一种伪继承的实现方式,代码如下:

function Person(name,age){
	this.name = name;
	this.age = age;
	this.sayHello = function(){
		console.log(this.name + "向您打招呼!");
	}
}
var per = new Person('牛魔王',22);
per.sayHello();
function Student(name,age,grade){
	this.inherit_temp = Person;
	this.inherit_temp(name,age);
	this.grade = grade;
}
Student.prototype.intro = function(){
	console.log("%s是个学生,读%d年级",this.name,this.grade);
}
var stu = new Student("孙悟空",34,5);
console.log(stu instanceof Student );
console.log(stu instanceof Person );
stu.sayHello();
stu.intro();

this.inherit_temp = Person中将Person直接赋值给Student的inherit_temp实例属性,
this.inherit_temp(name,age)中以this为调用者,调用了Person构造器。

创建对象

JS创建对象的三种方式:
使用new关键字调用构造器创建对象。
使用Object类创建对象。
使用JSON语言创建对象。

下面举例使用JSON语言创建对象,代码如下:

person = 
{
	name : 'yeeku',
	gender : 'male',
	son : {
		name:'nono',
		grade:1
	},
	info : function()
	{
		document.writeln("姓名:"+this.name + "性别:" +this.gender);
	}
}
person.info();
alert(person.son.name);

使用JSON语言创建对象时,属性值不仅可以是普通字符串,也可以是任何基本数据类型,还可以是函数、数组,甚至可以是另一个JSON语法创建的对象。

与使用JSON语法创建对象相似的是,数组的最后一个元素后面不能有逗号,如下代码定义一个更复杂的JSON对象。

var person = {
	name : 'wawa',
	age: 29,
	schools : ['小学','中学',"大学"],
	parents :[
		{
			name:'father',
			age:60,
			address:'广州'
		}
		,
		{
			name:'mother',
			age:58,
			address:'深圳'
		}
	]
};
alert(person.parents[0]);
document.writeln(person.parents[0].age);
document.writeln(person.parents[1].address);

实际上,JSON已经发展成一种轻量级的、跨语言的数据交换格式,因此JSON格式已成为XML数据交换格式的有力竞争者。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值