JavaScript01: 基础入门
JavaScript 是一门能够运行在浏览器上的脚本语言,简称JS。
首先,Javascript这个名字的由来就很有意思,不少人认为 Javascript 和 Java 貌似很像,容易想象成Java的脚本
但其实两者之间没有任何关系,纯粹是商业碰瓷。
既然JS是可以运行在浏览器上的脚本,并且本质上,浏览器是执行HTML程序的
那么如何在HTML中引入JS呢?
方案一:直接在 <script>
标签中引入编写js代码
方案二:将js代码写在js文件中,然后通过<script>
标签的src属性,进行引入
两种方式运行出的效果是一致的
但注意:HTML程序在执行的时候是从上到下进行渲染的
那如果把脚本放在下面,和放在上面,是有一些不同的
一、基本数据类型
JS虽然是一个脚本语言,麻雀虽小,五脏俱全。
在js中也可以像其他编程语言一样,声明变量、条件判断、流程控制等.
1.1 主要数据类型
number // 数字 不论是整数还是小数, 数据类型都是numberstring // 字符串boolean // 布尔值 true和false 注意 全小写object // 对象 这个比较特殊. 可理解为所有被new出来的东西,都是对象 undefined // 表示未定义 所有没有被定义过的东西,默认都是该类型 类似像空一样的东西// null 与 undefined
null 空对象
undefined 空变量 声明了变量,但没有赋值
两者都可以表示空,本质都一样的. 都啥也干不了
两者都可以当做false,来看待就好了// 查看变量类型
typeof 变量var a = '猪总';
console.log(typeof n)
1.2 变量声明、注释
- 声明变量用
var
来声明 //
来表示单行注释,使用/* 内容*/
表示多行注释- 每行以
;
作为结束标志
// js启动严格模式 在scrip标签 最上方
"use strict"var 变量名; // 创建一个变量, 此时该变量只能被赋值 es5let 变量名; // es6新版 主要作用是变量作用域const 常量 = 值; // 声明常量var 变量名 = 值; // 创建一个变量, 并且有值var 变量名 = 值1, 变量名2 = 值2, 变量名3 = 值3.....; // 一次创建多个变量,并都有值var 变量名1, 变量名2, 变量名3 = 值3; // 一次创建多个变量, 并且只有变量3有值
1.3 运算符
JS中的运算符和Python几乎一致,但有些特殊的
// 1 连接运算符 与 或 非 and or not <==> && || ! var a = 10, b = 20, c = 30 ;console.log(a > b && b > c); // false
console.log(!(a > b)) // true 注意括号// 2 等于 == 和 ===
== 只判断 值是否一致
=== 会判断 数据类型和值 是否都一致var a = "123";
var b = 123;
console.log(a == b); // true
console.log(a === b); // false
1.4 数据类型转换
// 1 string -> number : parseInt(字符串) 转化为整数
var a = "10086";
a = parseInt(a); // 字符串转成整数
console.log(a + 10); // 10096// 2 number -> string : 数字.toString() 或者 数字 + ""
var a = 100;
var b = a.toString();
var c = a + "";
console.log(b);
console.log(c);// 3 number -> string : 数字.toString(n进制) 数字转化成n进制的字符串
var m = 122;
var n = m.toString(16); // 数字转化成16进制的字符串
console.log(n); // 7a// 4 进制转换
var a = 10;
// 16进制的数字是多少
var x = a.toString(16); // a// AB的十进制是多少
var d = parseInt("AB", 16); // 171
1.5 关于自增 ++
// 1 在python中是没有++操作的,但是在js中是有的
a++; // a = a + 1
++a; // a = a + 1a--; // a = a - 1 同理
--a; // a = a - 1// 2 a++ 和 ++a的区别 困扰无数初学者的疑惑1. 不论是a++还是++a. 目的都是让a自增1. 2. a++ 该表达式 整体的 运算结果是 a++a 该表达式 整体的 运算结果是 a + 1// 个人理解: a 在 +前面,表示该表达式 是a 先赋值给表达式,a再自增+ 在 a前面,表示该表达式 是a+1 先自增,再赋值给表达式// 理解一下, 这里还好理解
var a = 10;
var b = a++;
console.log(b); // 10
console.log(a); // 11var a = 10;
var b = ++a;
console.log(b); // 11
console.log(a); // 11// 难度升级
var a = 10;
var a = a++;
console.log(a); // 10var a = 10;
var a = ++a;
console.log(a); // 11
1.6 字符串操作
s.split('a') // 以a,进行字符串切割 返回的是 数组 attr[]s.split() // 不指定字符,字符串切割 返回是 数组 [s] 以字符串本身为元素的数组s.split('') // 以'' 为指定字符,字符串切割 返回是 数组 [s] 以字符串全部拆开为元素的数组// eg:var s = 'edmond'
s.split('e') // ['e', 'dmond]
s.split() // ['edmond']
s.split('') // ['e', 'd', 'm', 'o', 'n', 'd']s.substr(start_index, len) // 按照索引 + 长度,取子字符串 从start开始切, 切len个字符 注意是字符数,不是字节
s.substring(start, end) // 按照两个索引位置,取子字符串 从start切割到ends.substr(start_index) // 只有一个参数时,两个都是从索引开始,截止到末尾
s.substring(start)s.length // 字符串长度s.charAt(i) // 第i索引位置的字符 s[i]s.indexOf('xxx') // 返回xxx的第一次出现的索引位置, 如果没有xxx. 则返回-1 从左往右
s.lastIndexOf("xxx") // 返回xxx的最后一次出现的索引位置,如果没有xxx. 则返回-1 从右往左// eg:截取字符串中的json部分
var a = '{ "name":"alex", "age":17, {"hobby":"zhuqiu"} }一堆其他的字符串'
a.substring(0, a.lastIndexOf('}')+1) // '{ "name":"alex", "age":17, {"hobby":"zhuqiu"} }'s.toUpperCase() // 转换成大写字母s.startsWith("xxx") // 判断是否以xxx开头s.charCodeAt(i) // 某个位置的字符 对应 ascii码的 10进制 数字
// 相反:String.fromCharCode(n); 数字n 对应的ascii码的 字母// js为了隐藏字符串本身(eg:字符串很重要,是加密解密的key),常用一些混淆代码// eg:
// 混淆代码
var offset = 18;
// 中间再隔着很多其他障眼法的代码
var x = 115;// 一系列神奇操作
x -= offset; // 115-18 = 96
x = String.fromCharCode(x);
console.log(x) // 'a'// 源代码:上面实质就是
x = 'a'
// 再正常通过x 去加密
二、条件分支
2.1 if 判断
// 语法1:
if(条件1){代码块1
}// 解读:
当 条件1 成立时, 执行 代码块1中的内容// 注:如果代码块1 中的内容只有一行. 则可以省略外面的大括号(一些逆向工程里会有)
if (条件1) 一行代码块1;
else 一行代码块2;// 语法2:
if(条件1){代码块1
} else {代码块2
}// 解读:
当 条件1 成立时, 执行 代码块1中的内容
若 条件1 不成立,则执行 代码块2中的内容// 语法3:
if(条件1){代码块1
} else if(条件2) {代码块2
} else if(条件3) {代码块3
} ... {代码块n
} else {代码块else
}
// 解读:
当 条件1 成立时, 执行 代码块1中的内容,
当 条件2 成立时. 则执行 代码块2中的内容
...
如果都不成立, 最终执行 代码块else 中的内容
2.2 switch语句
该语句是python中不存在的,但是在Java、C以及JS中依然会有使用
switch(变量){case 值1:代码块1break // 可选case 值2:代码块2break // 可选case 值3:代码块3break // 可选default: // 可选default代码块
}// 解读:
执行时, switch会判断变量的值 是否是 值1,
如果是, 则执行代码块1 以及代码块1中的break,
如果不是, 则继续判断 值2 ...
如果变量的值 都没有和 这些条件的值相等,则执行 default代码块// 注意:
每一个 case 中都可以 选择或不选择 break
需要注意的是, 如果不写 break ,那么就会形成 case穿透现象// eg: 变量的值 和值1 相等,并且case1中没有写 break
则在执行的时候. 会执行完 case1 中的代码块1
然后会自动穿透到后续所有 case中 去执行里面的代码块, 而不经过case中的条件验证// case穿透 是语法机制,不是bug,作用可以简化case代码体中的代码// eg:判断月份是上下半年
var a = 1;
switch(a){case 1:case 2:case 3:case 4:case 5:case 6:console.log("上半年");break;case 7:case 8:case 9:case 10:case 11:case 12:console.log("下半年");break;
}
三、循环语句
在js中有三种循环语句
3.1 while循环
while循环逻辑和python中的while几乎一模一样, 就是符号上有些许的区别// 语法1:
while(条件){循环体 -> 里面可以有break和continue等关键字
}// 解读:
先判断 条件 是否为真, 如果真, 则再执行循环体
执行完循环体 , 会再次判断 条件 ....
循环中也可以使用 break 和 continue 等关键字,来控制循环的走向// 语法2: 和
do{循环体
} while(条件);// 解读:
先执行循环体, 然后判断 条件是否成立, 如果成立,再来一次注意:由于do..while是先执行的循环体. 所以, 不论条件如何, 至少执行一次 循环体
3.2 for 循环
// 语法1: for的第一种语法
for(表达式1; 表达式2; 表达式3){循环体
}// 解读:
for循环和python中的for循环是完全不一样的
首先, 在执行的时候, 先执行 表达式1 然后, 判断 表达式2 执行结果是否为真, 如果真 , 则执行循环体
再然后, 执行 表达式3 再然后, 判断 表达式2 执行结果是否为真 , 如果真, 则执行循环体
再然后, 执行 表达式3
.....直到, 表达式2 得到的结果是 假, 则跳出循环// eg: 用for循环来跑一个 1~99
for(var i = 1; i < 100; i++){console.log(i);
}// 解读:
首先, i = 1,
然后, 判断 i < 100 成立打印i 1
再然后, i++, i变成2
再然后, 判断 i < 100 还是成立打印i 2
再然后, i++, i变成3
再然后, 判断 i< 100 还是成立打印i 3
....// for循环的固定逻辑也就这样了 ***
for(变量声明; 条件判断; 改变变量){循环体
}
// 语法2: for的第二种语法
var a = [11,22,33,44,55,66] // 数组for(let i in a){ // in 后面放被遍历的对象 可以是 数组、对象(字典)console.log(i + "_" + a[i])
}// 这种写法 非常类似python中的for循环
// 注意:
这里的 i 是 数组a 的索引信息,若需要数据:a[i]// 遍历数组 等价于: 语法1
for(var i = 0; i < a.length; i++){console.log(i + "_" + a[i])
}
四、数组和对象
4.1 数组
在JS中创建数组非常简单. 直接[ ]
即可, 也可以用new Array()
,效果都一样
var as = [11,22,33,44,55];// 通过方法声明的方式
var bs = new Array(11,22,33,44,55);
数组的常用操作
arr.length; // 获取数组长度arr.push(data); // 添加数据 尾部追加arr.pop(); // 删除数据, 从后面删除, 并返回被删除的内容arr.shift() // 删除数据, 从前面删除, 并返回被删除的内容 // 遍历数组,去执行某个回调函数 *** 其实function函数 就是回调函数
数组中的每一项循环出来. 分别去调用function函数, 会自动的将 数据 传递给函数的第一个参数arr.forEach(function(e, i){ // 第一个参数 e 是元素 (数据本身)console.log(i+"__"+e); // 第二个参数 i 是可选的, 元素索引
});for(let i in arr){console.log(i+"__"+arr[i])
}arr.join("连接符"); // 使用 连接符,将数组中的每一项拼接起来. 和python中的 "".join()雷同
4.2 对象
在JS中创建一个自定义对象非常容易. 和python中的字典几乎一样{ }
// js有很多种的对象,自定义对象 <===> python的字典var p = {name: "汪峰",age: 18,wife: "章子怡",'wife': "ab", // key可以是变量,也可以字符串chi: function(){ // value 也可以是函数console.log("吃饭")}
};// 通过方法声明的方式
var p2 = new Object()
使用对象
p.name
p.age// 对象的'.' 获取方法 和 对象的'[""]' 获取属性 是互通的,都可以使用
p['wife']
p.wife // 都可以取出来 注意:中括号形式,要引号,点形式 不加引号p.chi() // 调用函数
p['chi']()// 引申:恶心的混淆
var s = "吐啊吐啊就习惯了" // s是字符串类型的对象
var arr = s.split("") // 字符串.方法var arr = s["split"]("") // 变相1:通过字符串["属性"],获取对象的方法函数,再() 调用var arr = s["s" + "p" + "li" +"" + "t"]("") // 变相2:在变相1 上拓展 拆分字符串var arr = s["s" + "p" + "li" +"" + String.fromCharCode(116)]("") // 变相3:在变相2 上拓展 字符串的ASCII码
从上述内容中几乎可以看到. JS对象的使用几乎是没有门槛的. 十分灵活
for(var n in p){if(typeof(p[n]) != 'function'){console.log(p[n])}
}
五、函数(重点)
// 语法:// 声明函数
function 函数名(形参1, 形参2, 形参3....){ // 没有函数名,就是匿名函数函数体return 返回值
}// 调用函数
函数名(实参1, 实参2, 实参3....)// 除了写法换了一丢丢. 其他的东西和python完全一致,
简单案例
function an(a, b){return a + b
}ret = an(1, 2)
console.log(ret); // 3
很简单,不是么? 那为什么,在网页上看到一些网站的JS是如此的复杂呢?
注意:JS其实没有一个非常严格的语法规则,只要能够形成xxx()
并且xxx是一个函数的话,就可以执行
例如:
var an = function(a, b){return a + b
}
an(1, 2) // an虽然是var声明的变量, 但是它指向是一个函数. 那就可以执行var $ = function(a, b){return a + b
}
$(1, 2) // $没有被JS内置使用,就可以用啊 同理 '. _' 也OK// 这个也很过分. 要拆开来看 第一个括号里面放的就是一个函数,所以依然可以执行.
(function(a, b){return a + b
})(1, 2)c = (function(){var m = {name:'alex',age:'18',xijiao: function(a){ console.log(a+"来帮我洗脚"); }}return m
})
c() // c 也可以执行// 还有一个问题. 未来我们也会遇到的. 就是这个return
var an = function(){return console.log("我爱你"), console.log("爱你妹"), "哈哈"
}// 注意:
发现js会把return后的每一个','分割语句,都执行一次
但最终返回值,其实只是最后的那个 "哈哈"