JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到<head>中:
<head> <script> alert('Hello, world'); </script> </head>
第二种方法是把JavaScript代码放到一个单独的.js文件,然后在HTML中通过<script src="..."></script>引入这个文件:
<head> <script src="/static/js/abc.js"></script> </head>
把JavaScript代码放入一个单独的.js文件中更利于维护代码,并且多个页面可以各自引用同一份.js文件。
有些时候你会看到<script>标签还设置了一个type属性:
<script type="text/javascript"></script>
但这是没有必要的,因为默认的type就是JavaScript,所以不必显式地把type指定为JavaScript。
可以在同一个页面中引入多个.js文件,还可以在页面中多次编写<script> js代码... </script>,浏览器按照顺序依次执行。
大部分的时候,我们查看一些知名网站时,查看源码会发现他们的js都是放在网页最底部,那么把代码放在最底部和放在头部有什么区别呢?
http://www.mfbuluo.com/19131.html
https://www.zhihu.com/question/34147508
变量
变量名取名规则
- 变量必须以字母开头
- 变量也能以 $ 和 _ 符号开头(不过我们不推荐这么做)
- 变量名称对大小写敏感(y 和 Y 是不同的变量)
var x=2; var y=3; var z=x+y;
另外JavaScript的变量是无类型的,不能为变量指定类型,可以指定任意数据给声明好的变量。
默认值
var x;
此时x的值为undefined,表示未定义其值。
数据类型
不同的数据,需要定义不同的数据类型。在JavaScript中定义了以下几种数据类型:
null和undefined
JavaScript的设计者希望用null表示一个空的值,而undefined表示值未定义。事实证明,这并没有什么卵用,区分两者的意义不大。大多数情况下,我们都应该用null。undefined仅仅在判断函数参数是否传递的情况下有用。
布尔值
布尔值和布尔代数的表示完全一致,一个布尔值只有true、false两种值,要么是true,要么是false,可以直接用true、false表示布尔值,也可以通过布尔运算计算出来:
true; // 这是一个true值 false; // 这是一个false值 2 > 1; // 这是一个true值 2 >= 3; // 这是一个false值
Number
JavaScript不区分整数和浮点数,统一用Number表示,以下都是合法的Number类型:
123; // 整数123 0.456; // 浮点数0.456 1.2345e3; // 科学计数法表示1.2345x1000,等同于1234.5 -99; // 负数 NaN; // NaN表示Not a Number,当无法计算结果时用NaN表示 Infinity; // Infinity表示无限大,当数值超过了JavaScript的Number所能表示的最大值时,就表示为Infinity
需要注意的是,JS是无类型的,所以声明一个Number类型时请填写其默认值,否则将会是undefined,同时Number类型是64位的双精度浮点数,最大可以表示53位整数,大约是Math.pow(2,53)-1=9007199254740991。
另外我们需要看看 NaN 这个特殊的数值,该值表示不是一个数字“Not a Number”,NaN 与其他数值进行比较的结果总是不相等的,包括它自身在内。因此,不能与 Number.NaN 比较来检测一个值是不是数字,而只能调用 isNaN() 来比较。
字符串
字符串是以单引号'或双引号"括起来的任意文本,比如'abc',"xyz"等等。
字符串提供了很多的操作方法进行操作:
var s = 'Hello, world!'; s.length; // 13 s[0]; // 'H' s[6]; // ' ' s[7]; // 'w' s[12]; // '!' s[13]; // undefined 超出范围的索引不会报错,但一律返回undefined
需要特别注意的是,字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果:
var s = 'Test'; s[0] = 'X'; alert(s); // s仍然为'Test'
JavaScript为字符串提供了一些常用方法,注意,调用这些方法本身不会改变原有字符串的内容,而是返回一个新字符串:
toUpperCase()把一个字符串全部变为大写:
var s = 'Hello'; s.toUpperCase(); // 返回'HELLO'
toLowerCase()把一个字符串全部变为小写:
var s = 'Hello'; var lower = s.toLowerCase(); // 返回'hello'并赋值给变量lower lower; // 'hello'
indexOf()会搜索指定字符串出现的位置:
var s = 'hello, world'; s.indexOf('world'); // 返回7 s.indexOf('World'); // 没有找到指定的子串,返回-1
substring()返回指定索引区间的子串:
var s = 'hello, world' s.substring(0, 5); // 从索引0开始到5(不包括5),返回'hello' s.substring(7); // 从索引7开始到结束,返回'world'
比较运算符
当我们对Number做比较时,可以通过比较运算符得到一个布尔值:
2 > 5; // false 5 >= 2; // true 7 == 7; // true
实际上,JavaScript允许对任意数据类型做比较:
false == 0; // true false === 0; // false
==和===的区别
第一种是==比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果;
第二种是===比较,它不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再比较。
由于JavaScript这个设计缺陷,不要使用==比较,始终坚持使用===比较。
数组
数组是一组按顺序排列的集合,集合的每个值称为元素。JavaScript的数组可以包括任意数据类型。
[1, 2, 3.14, 'Hello', null, true];
JS中的数组不同于静态语言中的数组,不需要确定数组长度,切数组长度在运行中可以改变。
数组的元素可以通过索引来访问。请注意,索引的起始值为0:
var arr = [1, 2, 3.14, 'Hello', null, true]; arr[0]; // 返回索引为0的元素,即1 arr[5]; // 返回索引为5的元素,即true arr[6]; // 索引超出了范围,返回undefined
当直接更改到数组长度时,长度变大时,空白项目会被undefined填充,长度变小时,不在范围内的项目会被删除,效率最高的清除数组所有元素的代码如下:
var arr = [1, 2, 3]; arr.length = 0;
对象
JavaScript的对象是一组由键-值组成的无序集合。
var person = { name: 'Bob', age: 20, tags: ['js', 'web', 'mobile'], city: 'Beijing', hasCar: true, zipcode: null };
JavaScript对象的键都是字符串类型,值可以是任意数据类型。
要获取一个对象的属性,我们用对象变量.属性名的方式:
person.name; // 'Bob' person.zipcode; // null
如果键值包含变量名不允许的值时,请使用""号包含,获取时也使用数组索引方式获取:
var person = {"middle-school": "No.1 Middle School"}; person["middle-school"];
访问不存在的属性时返回undefined。
删除属性时使用delete关键字:
delete person.age; delete person["middle-school"];
判断是否存在某项属性
在JS中,有两种方式判断一个对象是否包含指定的属性,下面我们来看看他的区别:
- in:判断一个属性存在,这个属性不一定是当前对象的,它可能是当前对象继承得到的;
- hasOwnProperty:判断一个属性是否是自身拥有的,而不是继承得到的;
请看下面的例子:
var xiaoming = { name: '小明' }; 'name' in xiaoming; // true 'toString' in xiaoming; // true xiaoming.hasOwnProperty('name'); // true xiaoming.hasOwnProperty('toString'); // false
name本身是xiaoming这个对象的属性,而toString则是从Object对象上继承得到的一个方法,在JS中,方法也是作为属性存在对象上的。
严格模式
JavaScript在设计之初,为了方便初学者学习,并不强制要求用var申明变量。这个设计错误带来了严重的后果:如果一个变量没有通过var申明就被使用,那么该变量就自动被申明为全局变量:
i = 10; // i现在是全局变量
在同一个页面的不同的JavaScript文件中,如果都不用var申明,恰好都使用了变量i,将造成变量i互相影响,产生难以调试的错误结果。
使用var申明的变量则不是全局变量,它的范围被限制在该变量被申明的函数体内(函数的概念将稍后讲解),同名变量在不同的函数体内互不冲突。
为了修补JavaScript这一严重设计缺陷,ECMA在后续规范中推出了strict模式,在strict模式下运行的JavaScript代码,强制通过var申明变量,未使用var申明变量就使用的,将导致运行错误。
启用strict模式的方法是在JavaScript代码的第一行写上:
'use strict';
for in循环
该循环可以把一个对象的所有属性依次循环出来,需要注意的是,该循环得到的是键而不是值:
var o = { name: 'Jack', age: 20, city: 'Beijing' }; for (var key in o) { alert(key); // 'name', 'age', 'city' }
由于Array也是对象,而它的每个元素的索引被视为对象的属性,因此,for ... in循环可以直接循环出Array的索引:
var a = ['A', 'B', 'C']; for (var i in a) { alert(i); // '0', '1', '2' alert(a[i]); // 'A', 'B', 'C' }
请注意,for ... in对Array的循环得到的是String而不是Number。