全称JavaScript但是与Java一毛钱关系都没有 之所以这么叫是为了蹭Java的热度。JavaScript是一门前端工程师的编程语言 但是它本身有很多逻辑错误(不是很严谨)。
IT行业鄙视链: 后端 > 前端、运维、测试、产品、老板
前端想一统天下:node.js
1996年11月,JavaScript的创造者–Netscape公司,决定将JavaScript提交给国际标准化组织ECMA,希望这门语言能够成为国际标准。次年,ECMA发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为ECMAScript,这个版本就是1.0版。
该标准一开始就是针对JavaScript语言制定的,但是没有称其为JavaScript,有两个方面的原因。一是商标,JavaScript本身已被Netscape注册为商标。而是想体现这门语言的制定者是ECMA,而不是Netscape,这样有利于保证这门语言的开发性和中立性。
因此ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现。
年份 | 名称 | 描述 |
---|---|---|
1997 | ECMAScript 1 | 第一个版本 |
1998 | ECMAScript 2 | 版本变更 |
1999 | ECMAScript 3 | 添加正则表达式添加try/catch |
ECMAScript 4 | 没有发布 | |
2009 | ECMAScript 5 | 添加"strict mode"严格模式添加JSON支持 |
2011 | ECMAScript 5.1 | 版本变更 |
2015 | ECMAScript 6 | 添加类和模块 |
2016 | ECMAScript 7 | 增加指数运算符(**)增加Array.prototype.includes |
尽管 ECMAScript 是一个重要的标准,但它并不是 JavaScript 唯一的部分,当然,也不是唯一被标准化的部分。实际上,一个完整的 JavaScript 实现是由以下 3 个不同部分组成的:
核心(ECMAScript)
文档对象模型(DOM) Document object model (整合js,css,html)
浏览器对象模型(BOM) Broswer object model(整合js和浏览器)
简单地说,ECMAScript 描述了JavaScript语言本身的相关内容。
JavaScript 是脚本语言
JavaScript 是一种轻量级的编程语言。
JavaScript 是可插入 HTML 页面的编程代码。
JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行。
JavaScript 很容易学习。
如今,JavaScript 不仅可以在浏览器中执行,也可以在服务端执行,甚至可以在任意搭载了 JavaScript 引擎 的设备中执行。JavaScript 是一种脚本,一门编程语言,它可以在网页上实现复杂的功能,网页展现给你的不再是简单的静态信息,而是实时的内容更新,交互式的地图,2D/3D 动画,滚动播放的视频等等。JavaScript 怎能缺席。它是标准 Web 技术蛋糕的第三层,其中 HTML 和 CSS 我们已经在学习中心的其他部分进行了详细的讲解。
HTML是一种标记语言,用来结构化我们的网页内容并赋予内容含义,例如定义段落、标题和数据表,或在页面中嵌入图片和视频。
CSS 是一种样式规则语言,可将样式应用于 HTML 内容, 例如设置背景颜色和字体,在多个列中布局内容。
JavaScript 是一种脚本语言,可以用来创建动态更新的内容,控制多媒体,制作图像动画,还有很多。(好吧,虽然它不是万能的,但可以通过简短的代码来实现神奇的功能。)
单行注释 //
多行注释 /**/
1.head内script标签内编写
<script>
// 在这里写你的JS代码
</script>
2.head内script标签src属性引入外部js资源
<script src="myscript.js"></script>
3.body内最底部通过script标签src属性引入外部js资源(最常用)
ps:注意页面的下载是从上往下的 所以操作标签js代码一定要等待标签加载完毕再执行才可以正常运行
; # 分号
JavaScript中的语句要以分号(;)为结束符。
注意:很多时候不写也没问题
pycharm创建js文件或者html文件(适合编写较为复杂的js代码),浏览器提供编写js代码的环境
JavaScript的变量名可以使用_,数字,字母,$组成,不能以数字开头。在js中 首次定义一个变量名的时候需要用关键字声明
1.关键字var
var name='kimi'
2.ECMA6推出新语法
let name='kimi'
老版本 var(全部都是全局变量),新版本 let(可以声明局部变量)如果你的编辑器支持的版本是5.1那么无法使用let,如果是6.0则向下兼容 var let 都可以使用!基本数据类型
变量的命名规则:
a.变量名是区分大小写的。
b.推荐使用驼峰式命名规则。
c.关键字不能用做变量名。
与python变量名命名规划相比较
1.变量名只能是(比python多一个$)
数字 字母 下划线 $
2.变量名命名规范(不遵循也可以)
1.js中推荐使用驼峰式命名
userName
dataOfDb
2.python推荐使用下划线的方式
user_name
data_of_db
3.不能用关键字作为变量名
n = 10
for n in range(5):
print(n)
print(n)
var 在for循环里面定义也会影响到全局,let 在局部定义只会在局部生效
关键字let
python中没有真正意义上的常量 默认全大写就是表示常量
js中是有真正意义上的常量。需要关键字声明 : const
const pi = 3.14
pi = 3.44 # 报错
声明一个常量,声明之后就不能改了
1.可以单独开设js文件书写
2.还可以直接在浏览器提供的console界面书写( 左上方的清空按钮只是清空当前界面 代码其实还在 如果你想要重新来 最好重新开设一个页面)
js/python是一门动态类型
name = 'kimi'
name = 123456
name = [1, 2, 3, 4,5,6]
name可以指向任意的数据类型
但是有一些语言中,变量名之间指向一种后续不能更改
var x; // x 是undefined
var x=1; // x 是数字('number')
var x='kiki' // x 是字符串('string')
在JS中整型和浮点型
var a = 11;
var b = 11.11;
var c=123e5
var d=123e-5;
如何查看当前数据类型 使用typeof
typeof a; // 'number'
typeof b; // 'number'
typeof c; // 'number' 12300000
typeof d; // 'number' 0.00123
整型 浮点型 都为number类型,
JavaScript不区分整型和浮点型,就只有一种数字类型。
转换整型 parseInt()
转换浮点型 parseFloat()
parseInt('123') // 123
parseFloat('11.11') // 11.11
parseInt('11.11') // 11
parseInt('11adasdasdasd11') // 11
parseInt('asddsad11') // NaN(返回NaN,NaN属性是代表非数字值的特殊值。该属性用于指示某个值不是数字。)
注意: NaN属于数值类型 表示的意思是你操作的对象不是一个数字
单引号 'kimi'
多引号 "kimi"
模板字符串 `kimi`
不支持 三单/双引号
var s2 = '''hello'''
VM1243:1 Uncaught SyntaxError: Unexpected string
常用方法
1.字符串拼接推荐使用加号
方法一 字符的拼接 +
var a = "Hello"
var b = "world;
var c = a + b;
console.log(c); // 得到Helloworld
方法二 支持格式化输出
let name='kimi';
let age=18;
let desc=`my name is ${name} my age is ${age}`
desc //'my name is kimi my age is 18'
注意:python 不推荐用加号去拼接,而是join方法
2.常见内置方法
方法 | 说明 |
---|---|
.length | 返回长度 |
.trim() | 移除空白 |
.trimLeft() | 移除左边的空白 |
.trimRight() | 移除右边的空白 |
.charAt(n) | 返回第n个字符 |
.concat(value,…) | 拼接 |
.indexOf(substring,start) | 子序列位置 |
.substring(from,to) | 根据索引获取子序列 |
.slice(start,end) | 切片 |
.toLowerCase() | 小写 |
.toUpperCase() | 大写 |
.split(delimiter,limit) | 分割 |
var a= true; // undefined
var b = false; //undefined
typeof a; // 'boolean'
typeof b; // 'boolean'
布尔值在js中布尔值是全小写的,而python布尔值是大写True/False
“”(空字符串)、0、null、undefined、NaN 都是false
null表示值是空,一般在需要指定或清空一个变量时才会使用,如 name=null;
undefined表示当声明一个变量但未初始化时,该变量的默认值是undefined。还有就是函数无明确的返回值时,返回的也是undefined。
注意:null表示变量的值是空(null可以手动清空一个变量的值,使得该变量变为object类型,值为null),undefined则表示只声明了变量,但还没有赋值。
JavaScript 中的所有事物都是对象。字符串、数值、数组、函数…,且JavaScript 允许自定义对象,JavaScript 提供多个内建对象,比如 String、Date、Array 等等。对象只是带有属性和方法的特殊数据类型。
对象之数组(Array)>>>:类似于python中的列表
let l1 = []
对象之自定义对象(Object)>>>:类似于python的字典
let d1 = {'name':'jason',}
let d2 = new Object(); // 产生一个自定义对象
d2.name='kimi' // 往字典添加值
数组对象的作用是:使用单独的变量名来储存一系列的值。类似于Python中的列表。
var a=[123,'kimi'];
console.log(a[1]); // VM3524:1 kimi
数组常用内置方法:
方法 | 说明 |
---|---|
.length | 数组的大小 |
.push(ele) | 尾部追加元素 |
.pop() | 获取尾部的元素 |
.unshift(ele) | 头部插入元素 |
.shift() | 头部移除元素 |
.slice(start,end) | 切片 |
.reverse() | 反转 |
.join(seq) | 将数组元素连接成字符串 |
.concat(val,…) | 连接数组 |
.sotr() | 排序 |
.forEach() | 将数组的每个元素传递给回调函数 |
.splice() | 删除元素,并向数组添加新元素 |
.map() | 返回一个数组元素调用函数处理后的值的新数组 |
对象之数组(Array)>>>:类似于python中的列表
let l1 = []
对象之自定义对象(Object)>>>:类似于python的字典
let d1 = {'name':'jason',}
let d2 = new Object();
参数 | 描述 |
---|---|
function(currentvalue,index,arr) | 必需。 数组中每个元素需要调用的函数。 函数参数:参数描述currentValue必需。当前元素index可选。当前元素的索引值。arr可选。当前元素所属的数组对象。 |
this Value | 可选。传递给函数的值一般用 “this” 值。 如果这个参数为空, “undefined” 会传递给 “this” 值 |
1.一个参数就是数组里面每一个元素对象
var ll = [111, 222, 333, 444, 555, 666]
ll.forEach(function(value){console.log(value)},ll)
2.两个参数就是元素+元素索引
ll.forEach(function(value, index){console.log(value, index)},ll)
3.元素+元素索引+元素的数据来源
ll.forEach(function(value, index, arr){console.log(value, index, arr)},ll)
最多同时三个
语法:splice(index,howmany,item1,…itemX)
参数:
参数 | 描述 |
---|---|
index | 必需。规定从何处添加/删除元素。 该参数是开始插入和(或)删除的数组元素的下标,必须是数字。 |
howmany | 必需。规定应该删除多少元素。必须是数字,但可以是 “0”。 如果未规定此参数,则删除从 index 开始到原数组结尾的所有元素。 |
item1, …, itemX | 可选。要添加到数组的新元素 |
let l1=[111,222,333,444,555,666]
1.两个参数,第一个起始位置,第二个是删除的个数
l1.splice(0,3);
// [111, 222, 333]
2.三个参数先删除前面指定的参数 在添加后面指定的参数(先删除后添加)
l1.splice(0,1,888);
[444]
// l1=[888, 555, 666]
3.先删除指定前面的参数,在将数组添加到Array内 Array=数组
l1.splice(0,1,[111,222,333,444]);
[888]
// [Array(4), 555, 666] Array(4)=[111, 222, 333, 444]
语法:map(function(currentValue,index,arr),thisValue)
参数:
参数 | 描述 |
---|---|
function(currentValue, index,arr) | 必须。函数,数组中的每个元素都会执行这个函数 函数参数: 参数描述currentValue必须。当前元素的值index可选。当期元素的索引值arr可选。当期元素属于的数组对象 |
thisValue | 可选。对象作为该执行回调时使用,传递给函数,用作 “this” 的值。 如果省略了 thisValue ,“this” 的值为 “undefined” |
var l2=[11,22,33,44,55];
l2.map(function(value){console.log(value)},l2);
11
VM4761:1 22
VM4761:1 33
VM4761:1 44
VM4761:1 55
l2.map(function(value,index){
return value*2},l2);
(5) [22, 44, 66, 88, 110]
l2.map(function(value,index,arr){
return value*2},l2);
(5) [22, 44, 66, 88, 110]
+ - * / % ++(自增1) --(自减1)
var x=10;
var res1=x++; 加号在后面 先赋值后自增
var res2=++x; 加号在前面 先自增后赋值
!=(值不等 弱) ==(值相等 弱) ===(值相等 强) !==(值不等 强)
ps:会不会自动转换类型
1 == “1” // true 弱等于
1 === "1" // false 强等于
//上面这张情况出现的原因在于JS是一门弱类型语言(会自动转换数据类型),所以当你用两个等号进行比较时,JS内部会自动先将
//数值类型的1转换成字符串类型的1再进行比较,所以我们以后写JS涉及到比较时尽量用三等号来强制限制类型,防止判断错误
&&(与) ||(或) !(非)
= += -= *= /=
if (条件){
条件成立执行的代码
}
if (条件){
条件成立执行的代码
}else{
条件不成立执行的代码
}
if (条件1){
条件1成立执行的代码
}else if(条件2){
条件1不成立条件2执行的代码
}else if(条件3){
条件1和2不成立条件3执行的代码
}
else {
条件1,2,3都不成立执行的代码
}
注:如果分支结构中else if很多还可以考虑使用switch语法
switch(){
case 条件1:
条件1成立执行的代码;
break; # 如果没有break,就会基于某个case条件一直往下执行
case 条件2:
条件2成立执行的代码;
break
case 条件3:
条件3成立执行的代码;
break;
case 条件4:
条件4成立执行的代码;
break;
defualt:
条件都不满足执行的代码
}
for(起始条件;循环条件;条件处理){
循环体代码
}
1.for 循环列表
for(let i=0;i<10;i++){
console.log(i)
}
2.for 循环字典
let dd = {'name':'jason','age':18}
for(let k in dd){
console.log(k)
}
for(let k in dd){
console.log(dd[k])
};
while循环
while(循环条件){
循环体代码
}
eg:
var i = 0;
while (i < 10) {
console.log(i);
i++;
}
值1 if 条件 else 值2
res = 1 if 1>2 else 3
条件成立取 1
条件不成立取 3
js中三元运算
python中: 值1 if 条件 else 值2
JS中: 条件?值1:值2
eg1:
res = 1>2?1:3
条件成立 取问号后面的1
不成立 取冒号后面的3
eg2:
var a = 1;
var b = 2;
var c = a > b ? a : b
//这里的三元运算顺序是先写判断条件a>b再写条件成立返回的值为a,条件不成立返回的值为b;三元运算可以嵌套使用;
var a=10,b=20;
var x=a>b ?a:(b=="20")?a:b;
x=10
def 函数名(形参):
''' 函数注释'''
函数体代码
return 返回值
fuction 函数名(形参){
//函数注释
函数体代码
return 返回值
}
eg1:
function f1() {
console.log("Hello world!");
}
eg2:
// 带参数的函数
function f2(a, b) {
console.log(arguments); // 内置的arguments对象
console.log(arguments.length);
console.log(a, b);
}
eg3:
// 带返回值的函数
function sum(a, b){
return a + b;
}
sum(1, 2); // 调用函数
var sum=function(a,b){
return a+b;
}
sum(1,2)
var f = v => v;
var f = fuction(v){
return v
}
eg1:
var f = () => 5; //箭头函数不需要参数
var f = function(){return 5};
eg2:
var sum = (num1, num2) => num1 + num2; //需要多个参数
var sum = function(num1, num2){
return num1 + num2; ////这里的return只能返回一个值,如果想返回多个值需要自己手动给他们包一个数组或对象中
}
function add(a,b){
console.log(a+b);
console.log(arguments.length); console.log(arguments[0]); //arguments相当于将出传入的参数全部包含,这里取得就是第一个元素1
}
add(1,2)
输出:
3
2
1
1.JS中函数的形参与实参个数可以不对应,
传少了缺少的那个变量就是undefined,传多了多余的不用接收
2.函数体代码中有一个关键字arguments用来接收所有的实参
3.函数的返回值如果有多个需要自己处理成一个整体
在JavaScript函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它(该变量的作用域是函数内部)。只要函数运行完毕,本地变量就会被删除。
在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。
JavaScript变量的生命期从它们被声明的时间开始。
局部变量会在函数运行以后被删除。
全局变量会在页面关闭后被删除。
首先在函数内部查找变量,找不到则到外层函数查找,逐步找到最外层。与python作用域关系查找一模一样
eg1:
var city = "BeiJing";
function f() {
var city = "ShangHai";
function inner(){
var city = "ShenZhen";
console.log(city);
}
inner();
}
f();
eg2:
var city = "BeiJing";
function Bar() {
console.log(city);
}
function f() {
var city = "ShangHai";
return Bar;
}
var ret = f();
ret();
eg3:
var city = "BeiJing";
function f(){
var city = "ShangHai";
function inner(){
console.log(city);
}
return inner;
}
var ret = f();
ret();
补充知识
词法分析:JavaScript中在调用函数的那一瞬间,会先进行词法分析
当函数调用的前一瞬间,会先形成一个激活对象:Avtive Object(AO),并会分析以下3个方面:
1:函数参数,如果有,则将此参数赋值给AO,且值为undefined。如果没有,则不做任何操作。
2:函数局部变量,如果AO上有同名的值,则不做任何操作。如果没有,则将此变量赋值给AO,并且值为undefined。
3:函数声明,如果AO上有,则会将AO上的对象覆盖。如果没有,则不做任何操作。
函数内部无论是使用参数还是使用局部变量都到AO上找。
eg:
var age = 18;
function foo(){
console.log(age);
var age = 22;
console.log(age);
}
foo(); // 问:执行foo()之后的结果是? 22
eg:
var age = 18;
function foo(){
console.log(age);
var age = 22;
console.log(age);
function age(){
console.log("呵呵");
}
console.log(age);
}
foo(); // 执行后的结果是?
var d = new Date();
//getDate() 获取日
//getDay () 获取星期
//getMonth () 获取月(0-11)
//getFullYear () 获取完整年份
//getYear () 获取年
//getHours () 获取小时
//getMinutes () 获取分钟
//getSeconds () 获取秒
//getMilliseconds () 获取毫秒
//getTime () 返回累计毫秒数(从1970/1/1午夜)
let dd = {name: 'jason', age: 18}
JSON.stringify(dd) 序列化
JSON.parse(ss) 反序列化
定义正则两种方式
var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9]{5,11}");
var reg2 = /^[a-zA-Z][a-zA-Z0-9]{5,9}$/;
1.全局模式的规律
lastIndex
2.test匹配数据不传默认传undefined
作业
1.编写代码,将当前日期按“2017-12-27 11:11 星期三”格式输出
<body>
<script>
const WEENKMAP={
0:'星期日',
1:'星期一',
2:'星期二',
3:'星期三',
4:'星期四',
5:'星期五',
6:'星期六',
}
function showTime(){
var d1 = new Date();
var year=d1.getFullYear();
var month=d1.getMonth()+1; //注意月份是从0~11
var day = d1.getDate();
var hour=d1.getHours();
var minute=d1.getMinutes() < 10?"0"+d1.getMinutes():d1.getMinutes(); //三元运算
var week =WEENKMAP[d1.getDay()]
var strTime=`${year}-${month}-${day} ${hour}:${minute} ${week}`
console.log(strTime)
}
showTime();
</script>