JavaScript
一、简介
前面我们学习了html和css,但是我们写的网页不能动起来,如果我们需要网页出现各种效果,那么我们就要学习一门新的语言了,那就是JavaScript,JavaScript是世界上最流行的脚本语言,而且Javascript和Python一样也是一门全栈开发语言,并且跨平台。浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处理。
二、代码存放位置
理论上放在body和head中都可以,但是推荐放在body代码块底部,因为Html代码是从上到下执行,如果Head中的js代码耗时严重,就会导致用户长时间无法看到页面,如果放置在body代码块底部,那么即使js代码耗时严重,也不会影响用户看到页面效果,只是js实现特效慢而已。
Js代码可以放在一个单独的文件中,然后通过 <script src="common.js" type="text/javascript"></script>可以将其导入进来,或者直接在html文件中直接书写代码,如下面所示,其中两种方式的 type都可以不用写,因为浏览器默认的便是javascript
<script
type=
"text/javascript"
>
Js代码内容
<
/
script>
三、变量
JavaScript中变量的声明是一个非常容易出错的点,局部变量必须一个 var 开头,如果未使用var,则默认表示声明的是全局变量。
name = 'alex'; //不加var 定义的是全局变量 function f1() { //name = 123 ; // 不加var 函数里面修改的还是全局变量 var name = 'jason' // 加var 函数里面修改的是局部变量 }
四、数据类型
1、数字Number
JavaScript中不区分整数值和浮点数值,JavaScript中所有数字均用浮点数值表示。下面来看一下代码示例
var num1 = new Number(123); //创建了一个数字类型的对象 var num3 = Number(456); // 456 var num2 = 666; var s1 = 's123'; var num4 = parseInt(s1); console.log(num1.valueOf(),num2,num3); console.log(num4); // NaN if(isNaN(num4)){ console.log('not a number'); // not a number } else { console.log('a number'); } console.log(isFinite(num3)); // 是否是有限值 true Infinity表示无穷大。 console.log(typeof num3); // 'number' 返回的是字符串 var a = 1222.4444444; console.log(a.toFixed(2)); // 1222.44 console.log(a.toExponential(3)); // 1.222e+3
2、字符串
字符串是由字符组成的数组,在JavaScript中字符串是不可变的,下面来看一下代码示例
var num1 = new Number(123); //创建了一个数字类型的对象 var num3 = Number(456); // 456 var num2 = 666; var s1 = 's123'; var num4 = parseInt(s1); console.log(num1.valueOf(),num2,num3); console.log(num4); // NaN if(isNaN(num4)){ console.log('not a number'); // not a number } else { console.log('a number'); } console.log(isFinite(num3)); // 是否是有限值 true Infinity表示无穷大。 console.log(typeof num3); // 'number' 返回的是字符串 var a = 1222.4444444; console.log(a.toFixed(2)); // 1222.44 console.log(a.toExponential(3)); // 1.222e+3
3、布尔值
布尔类型仅包含真假,与Python不同的是其首字母小写。下面来简单的看一下代码示例,
var a = 123; var s = '123'; console.log(a==s); // true console.log(a===s); // false 判断值和类型一样
4、数组
JavaScript中的数组类似于Python中的列表,里面也提供了一些内置方法,下面我们来看一下
var a = [1,2,3,4]; console.log(a.length); // 4 a.push(5); console.log(a); // [1, 2, 3, 4, 5] var ret = a.pop(); console.log(ret); // 5 a.unshift('aaa'); // 头部插入元素 console.log(a); // ["aaa", 1, 2, 3, 4] var ret1 = a.shift(); // 头部移除元素 console.log(ret1); // aaa var ret2 = a.slice(1,3); // 切片, console.log(ret2); // [2,3] // obj.splice(start, deleteCount, value, ...) 插入、删除或替换数组的元素 console.log(a); a.splice(1,0,'first'); // 指定位置插入元素 a.splice(2,1,'second'); // 指定位置替换元素 a.splice(2,1); // 指定位置删除元素 console.log(a); var b = ['22']; console.log(b.concat(a)); // 连接字符串 ["22", 1, "first", 3, 4] console.log(a.join('-')); // 拼接字符串 1-first-3-4 console.log(a.reverse()); // 反转字符串 [4, 3, "first", 1] console.log([3,2,5].sort()) //对number数组进行排序
1、序列化
序列化就是将JavaScript中的数据类型转换成字符串,反序列化的过程则相反
var a = 'ss'; ret = JSON.stringify(a); // 'ss' 序列化 console.log(ret); console.log(JSON.parse(ret)); // ss 反序列化
2、转义
一般使用在URL中字符的转义等,下面来看一下具体的用法
// 转义 其中escape() unescape()主要是对cookies使用 var a = 'http://www.baidu.com?name=李杰'; console.log(encodeURI(a)); // http://www.baidu.com?name=%E6%9D%8E%E6%9D%B0 console.log(decodeURI(encodeURI(a))); // http://www.baidu.com?name=李杰 console.log(encodeURIComponent(a)); // http%3A%2F%2Fwww.baidu.com%3Fname%3D%E6%9D%8E%E6%9D%B0 console.log(decodeURIComponent(encodeURIComponent(a))); // http://www.baidu.com?name=李杰
3、eval
JavaScript中的eval是Python中eval和exec的合集,既可以编译代码也可以获取返回值。
console.log(eval('1+2*5-5')); // 6 console.log(eval(a = 1)); // 1 声明了一个局部变量a值为1
4、正则表达式
JavaScript中支持正则表达式,其主要提供了两个功能:
- test(string) 用于检测正则是否匹配
- exec(string) 用于获取正则匹配的内容
注:定义正则表达式时,“g”、“i”、“m”分别表示全局匹配,忽略大小写、多行匹配。下面来简单的看一下使用
var a = /\d+h/; console.log(a.test('123h434')); // true 检测正则是否匹配,表单数据验证可用到 console.log(a.test('12a34')); // false console.log(a.exec('123h434')); // ["123h", index: 0, input: "123h434"] 获取正则匹配内容 console.log(a.exec('123e434')); // null
5、时间
在JavaScript中,Date
对象用来表示日期和时间。JavaScript中提供了时间相关的操作,分别为获取时间和设置时间,时间操作中分为两种时间,统一时间(UTC),以及本地时间(东8区)
var now = new Date(); now.getFullYear(); now.getMonth(); // 6, 月份,注意月份范围是0~11,6表示7月 now.getDate(); // 7, 表示7号 now.getDay(); // 3, 表示星期三 now.getHours(); // 19, 24小时制 now.getMinutes(); // 49, 分钟 now.getTime(); // 1435146562875, 以number形式表示的时间戳
六、语句
1、条件语句
if(条件){ }else if(条件){ }else{ } switch(name){ case '1': age = 123; break; case '2': age = 456; break; default : age = 777; }
2、循环语句
var names = ["alex", "tony", "rain"]; for(var i=0;i<names.length;i++){ console.log(i); console.log(names[i]); } var names = ["alex", "tony", "rain"]; for(var index in names){ console.log(index); console.log(names[index]); } while(条件){ // break; // continue; }
3、异常处理
try { //这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行 } catch (e) { // 如果try代码块中抛出了异常,catch代码块中的代码就会被执行。 //e是一个局部变量,用来指向Error对象或者其他抛出的对象 主动跑出异常 throw Error('xxxx') } finally { //无论try中代码是否有异常抛出(甚至是try代码块中有return语句),finally代码块中始终会被执行。 }
七、函数
1、函数类型
JavaScript中函数基本上可以分为一下三类,普通函数,匿名函数,自执行函数,此外需要注意的是对于JavaScript中函数参数,实际参数的个数可能小于形式参数的个数,函数内的特殊值arguments中封装了所有实际参数。
// 普通函数 function func(arg){ return true; } // 匿名函数 var func = function(arg){ return "tony"; } // 自执行函数 (function(arg){ console.log(arg); })('123')
2、函数作用域
JavaScript中每个函数都有自己的作用域,当出现函数嵌套时,就出现了作用域链。当内层函数使用变量时,会根据作用域链从内到外一层层的循环,如果不存在,则异常。下面就是一个简单其实就是简单的闭包。
name = 'jason'; function f1() { var name = 'kobe'; function f2() { console.log(name); } return f2; } ret = f1(); ret(); //打印出kobe f2函数的作用域已经定死,上一级作用域为f1
八、面向对象
// 面向对象,没有class 用function定义 function Person(name,age) { this.name = name; // Person充当构造函数 this.age = age; // this指代对象 } // 使用原型保存类中的函数,如果放在person中,则每创建一个 // 对象都会在内存中创建一份,这样会浪费内存 Person.prototype = { Show:function () { console.log(this.name,this.age); } }; Person.prototype.Show2 = function () { console.log(this.name,this.age) }; person1 = new Person('jason',18); person1.Show(); // jason 18 person1.Show2() // jason 18
javascript补充
- 为了强制使用var定义变量,可以在代码开始加上'use strict',这样未被var声明的变量将会报错,前提是浏览器支持该模式
- 可以用转义字符
\,
'I\'am "ok"' - 要获取字符串某个指定位置的字符,可以使用s[1]下表进行操作, 如果对s[1] = 'f'赋值的话,不会报错,原字符串也不会改变。调用字符串的相关方法只会产生一个新的字符串
- 对数组进行操作,var f = [1,2],f[4] = 5,超过了数组长度,但是不会报错,相反数组f变成了 [1, 2,undefined × 2, 5]这一点需要特别注意,此外如果在pycharm中运行的话,不会出现上述情况但是会在数组中增加一个键值对。因此千万要注意自己操作数组的时候不要越界
- 数组切片,
arr.slice(3)表示从索引3开始到结束,
arr.slice(0, 3)表示从索引0开始,到索引3结束,arr.slice()可以复制一个数组。
- 对象,每个对象的属性用逗号分隔,访问不存在的属性会返回一个undefined,可以通过delete 删除某一属性,当然也可以直接动态的添加某一属性,要判断一个对象是否有某个属性,可以使用 in 比如 onsole.log('name' in xiaoming),但是这样可以能有一个问题,如果xiaoming继承了某一属性,那么判断这一属性也会成功,所以最好用 xiaoming.hasOwnProperty('name')
- 函数传参的时候,可以多传,也可以少传,少传的话,未被传入的参数会被定义为undefined,在函数内部用arguments获取到所有函数传入的参数,
- 函数内部的变量会"提前声明",具体的请看下面的代码
function foo() { var x = 'Hello, ' + y; alert(x); // Hello, undefined var y = 'Bob'; } foo(); // 对于上述foo()函数,JavaScript引擎看到的代码相当于: function foo() { var y; // 提升变量y的申明 var x = 'Hello, ' + y; alert(x); y = 'Bob'; }
9.不在任何函数内定义的变量就具有全局作用域,实际上,JavaScript默认有一个全局对象window
,全局作用域的变量实际上被绑定到window
的一个属性
var a = 'hello'; console.log(window.a); console.log(a); function foo() { console.log('foo'); } foo(); window.foo();
可以看到上面两种方式的执行效果一样,JavaScript实际上只有一个全局作用域。任何变量(函数也视为变量),如果没有在当前函数作用域中找到,就会继续往上查找,最后如果在全局作用域中也没有找到,则报ReferenceError错误。全局变量会绑定到window
上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局属性中。例如:
// 唯一的全局属性MYAPP: var MYAPP = {}; // 其他变量: MYAPP.name = 'myapp'; MYAPP.version = 1.0; // 其他函数: MYAPP.foo = function () { return 'foo'; };
10. Array
的sort()
方法默认把所有元素先转换为String再排序,结果'10'
排在了'2'
的前面,因为字符'1'
比字符'2'
的ASCII码小。