Javascript 基础入门(一)

一. Javascript基本介绍

Javascript 简称JS,是一门独立的编程语言,是可以运行在浏览器上的脚本;名称上有Java,但是它与Java没有任何关系的。
在HTML中引入JS的方法:
方案一, 直接在<script>标签中引入编写js代码
方案二, 将js代码写在js文件中, 然后通过script标签的src属性进行引入
两种方式运行出的效果是一致的. 但是需要各位注意一点, HTML程序在执行的时候是从上到下进行渲染的. (代码也是从上到下执行的)

在js中使用// 来表示单行注释. 使用/* */表示多行注释.

二. Javascript基本数据类型

常见的两行JS代码

console.log('开始学习了');    // 在控制台打印,相当于python中的print
let a = '1002';
console.log(typeof a);    //打印变量a的数据类型

1、主要是以下几种数据类型

number  数字, 不论是整数还是小数, 数据类型都是number
string  字符串, 这个没啥可聊的. 就是很单纯的字符串
boolean  布尔值, 只有两个, true和false. 注意不是大写T和F. 
object 对象, 这个比较特殊. 你可以理解为所有被new出来的东西都是对象  
undefined, 这个表示未定义. 所有没有被定义过的东西默认都是该类型 类似像空一样的东西

2、定义变量

JS中,要使用一个变量要先定义变量,关键词是 var 或者 let,可以定义变量名称,不赋值。要注意一行代码同时创建多个变量的情况。

var 变量名; // 创建变量, 此时该变量除了被赋值啥也干不了. 
let 变量名; // 创建变量, 此时该变量除了被赋值啥也干不了. 
var 变量名 = 值; // 创建一个变量, 并且有值. 
var 变量名 = 值1, 变量名2 = 值2, 变量名3 = 值3.....; // 一次创建多个变量.并都有值
var 变量名1, 变量名2, 变量名3 = 值3;  // 创建多个变量. 并且只有变量3有值

3、JS中的运算符

JS中的运算符和Python几乎一致. 但有些特殊的.

and, or, not 到了js中注意,换成了&&, ||, !, 其含义和概念是一致的.

var a = 10, b = 20, c = 30 ;
console.log(a > b && b > c);  // false
console.log(!(a > b)) // 注意括号

4、JS 中的 == 和 ===,

== 只是判断值是否一致,  
=== 会判断数据类型和数据是否都一致. 
var a = "123";
var b = 123;
console,log(a == b);  // true
console.log(a === b); // false

5、数据类型及进制转换

字符串转换成数字,使用parseInt(字符串),parse英文翻译是“解析”的意思

let a = '1002';
console.log(typeof a);
let b = parseInt(a);
console.log(typeof b); //输出 number

数字转换成字符串
方法1:数字.toString(),参数不填是默认是十进制
方法2: 数字 + ""

var a = 10;
var b = a.toString(16);  //输出是16进制数字对应的字符串,10对应16进制是a,
console.log(b);
console.log(typeof b);
//方法2
b = a+"";    //b就是字符串了

进制转换
parseInt 的结果是十进制,参数中要说明要转换的参数是多少进制的
toString() 要说明转换成多少进制的

var a = 10;
// 16进制的数字是多少
var x = a.toString(16);  // a,字符串类型
console.log(x, typeof x)    //a string


// AB的十进制是多少
var d = parseInt("AB", 16); // parseInt的结果是十进制,参数中要说明要转换的参数是多少进制的 171
console.log(d, typeof d)    //171 number

6、JS中的++与--

a++; 就是a = a + 1
++a; 就是a = a + 1
a--; 就是a = a - 1
--a; 就是a = a - 1
重点概括:

  1. 不论是a++还是++a. 目的都是让a自增1.

a++这个表达式整体运算出来的结果等于 a
++a这个表达式整体运算出来的结果等于 a + 1
表达式执行完成后,a自增1

a = 10
b = a++    //a++表达式运算结果为a,就是10,所以b=10;运算完成后,a自增1,那么a=11
console.log(b)  // 10
console.log(a)  // 11
a = 10
b = ++a  //++a表达式运算结果为a+1,就是10+1,所以b=11;运算完成后,a自增1,那么a=11
console.log(b)  // 11
console.log(a)  // 11

以下逻辑比较奇怪,一般不会这么使用

a = 10;
a = a++;    //a=a,也就是a=10,运算完成后a自增1,所以a又变成了11,但是最终赋值的时候,还是按照之前计算的a=a++,而由于是先计算a++,所以a++的值是a=10,a=11只是短暂的瞬间
console.log(a);  // 10

a = 10;
a = ++a;    //a=a+,也就是a=11,运算完成后a自增1,所以a短暂瞬间变成了12,a=12,但是赋值是最后运算的,而++a是最初运算的,值是11
console.log(a)  // 11

剖析:

a = 10;
a = a++;  
console.log(a);  // 10

第一步:a = 10
第二步:1)先计算a++,表达式的值是a,也就是10;
2)a自增1,而原来a=10,所以,此时a==11;
3)最终赋值,a = a++,记住,这一步只是赋值,而不再进行对a进行任何计算,a++之前已经计算好了,表达式的值就是10,所以,赋值这步的结果就是把之前计算好的a++的值赋值给a,所以,a==10。(在上一步a通过自增已经从10变成11了,但是最后这步又对a重新进行赋值了)
第三步:打印a的值,所以打印的结果是a=10

第二部分代码:

a = 10;
a = ++a;  
console.log(a);  // 11

第一步:a = 10
第二步:1)先计算++a,表达式的值是a+1的值,也就是++a == 11;
2)a自增1,而原来a=10,所以,此时a==11;
3)最终赋值,a = ++a,记住,这一步只是赋值,而不再进行对a进行任何计算,++a之前已经计算好了,表达式的值就是11,所以,赋值这步的结果就是把之前计算好的a++的值赋值给a,所以,a=11;
第三步:打印a的值,所以打印的结果是a=11

7、字符串操作

s.split() 字符串切割

let s = "刘德华_张学友_黎明_郭富城";

let res=s.split('_');
console.log(res);    // [ '刘德华', '张学友', '黎明', '郭富城' ]
console.log(typeof res);    // object

s.substr(start, len) 字符串切割, 从start开始切, 切len个字符

let s = "刘德华_张学友_黎明_郭富城"
let res = s.substr(4, 3);  // 从索引为4的位置开始切,切取长度为3
console.log(res);  // 张学友

s.substring(start, end) 字符串切割, 从索引start切割到索引end,取左不取右

let s = "刘德华_张学友_黎明_郭富城"
let res1=s.substring(0,3)
console.log(res1)  //刘德华

(重点)s.length 字符串长度

let s = "刘德华_张学友_黎明_郭富城"
console.log(s.length)

s.charAt(i) 第i索引位置的字符

let s = "刘德华_张学友_黎明_郭富城"
console.log(s.charAt(0))  //刘

(重点)st.charCodeAt(索引),对应索引的字符在ASCII码中的字符编码

let st='nameAge天空'
let res=st.toUpperCase()
console.log(st.charCodeAt(3)); //索引3对应的字符是e,在ASCII编码中对应是101

把ASCII字符编码转换成字符

let as = String.fromCharCode(101)
console.log(as);  //输出字符是e

s.indexOf('xxx')返回xxx的第一个索引位置, 如果没有xxx. 则返回-1

let s = "刘德华_张学友_黎明_郭富城华"
let res=s.indexOf('华')
console.log(res);  //结果是2,返回的是,第一个“华”的索引
console.log(s.indexOf('哈'))  //没有'哈'这个字符,所以返回-1

s.lastIndexOf("xxx") 返回xxx的最后一次出现的索引位置,如果没有xxx. 则返回-1

let s = "刘德华_张学友_黎明_郭富城华"
let res=s.lastIndexOf('华')
console.log(res);  //结果是14,返回的是,最后一个“华”的索引

s.includes("xxx") 判断xxx是否出现在s中. 在就返回 true,不在就返回 false;相当于是python中的in

let s = "刘德华_张学友_黎明_郭富城华"
console.log(s.includes('刘德华'));//返回true

s.toUpperCase() 把字符串中所有小写字母转换成大写字母

let st='nameAge天空'
let res=st.toUpperCase()
console.log(res); // NAMEAGE天空

s.startsWith("xxx") 判断是否以xxx开头

let st='nameAge天空'
let res=st.toUpperCase()
console.log(res)
console.log(st.startsWith('n'))    ;// true
console.log(st.startsWith('an'))    ;// false

关于null和undefined. null可以理解为变量创建了,但是值为空. undefined就是没有定义变量。

练习:提取json字符串

s = "callback_jsonp({'name': '刘德华', 'age': 18, zhiye:  {'one': '歌手'}})";

let start = s.indexOf('{')
let end = s.lastIndexOf('}')
let ret = s.substring(start, end+1)
console.log(ret)

二. JS条件语句

注:如果代码块1中的内容只有一行. 则可以省略外面的大括号(一些逆向工程里会有)

// 语法
if(条件1){
    代码块1    
}

// 解读: 当`条件1`成立时, 执行代`码块1`中的内容, 如果`条件1`不成立. 则不执行该`代码块1`中的内容

例子

let a = 10;
if(a>1){
    console.log('条件成立');
};

if (a>1) console.log('如果大括号中的内容只有一行. 则可以省略外面的大括号');

双条件分支

// 语法
if(条件1){
    代码块1
} else {
    代码块2
}
// 解读: 当`条件1`成立时, 执行`代码块1`中的内容, 如果`条件1`不成立. 则执行`代码块2`中的内容

例子

let b=10;
if (b>20){
    console.log('条件为真是执行');

}else {
    console.log('条件为假是执行');
}

多条件分支

// 语法
if(条件1){
    代码块1
} else if(条件2) {
    代码块2
} else if(条件3) {
    代码块3
} ... {
    代码块n
} else {
    代码块else
}
// 解读: 当`条件1`成立时, 执行`代码块1`中的内容, 如果`条件2`不成立. 则执行`代码块2`中的内容...如果都不成立, 最终执行`代码块else`中的内容. 

例子

let c = 85;
if (c>=85){
    console.log('优秀')}
else if(c>=75){
    console.log('良好')}
else if(c>=60){
    console.log('及格')}
else {
    console.log('不及格')}

switch语句. 也是一种多分支,在JS中常用于混淆,打乱case的执行顺序。

switch(变量){
    case 值1:
        代码块1
        break  // 可选
    case 值2:
        代码块2
        break  // 可选
    case 值3:
        代码块3
        break  // 可选
        
    default:   // 可选
        default代码块
}

/*
    解读: 
        执行时, 
        switch会判断变量的值是否是`值1`, 
        如果是, 则执行代码块1以及代码块1中的break, 
        如果不是, 则继续判断`值2`...
        如果前面的`值`都没有和`变量`相等的.则执行`default代码块`. 
        
    注意, 
        每一个`case`中都可以选择`break`, 也可以不选择`break`, 需要注意的是, 如果不写`break`. 
        那么就会形成`case穿透`现象. 
        
    例, `变量`的值如果和`值1` 相等. 并且case1中没有写`break`, 
    则在执行的时候. 会执行完`case1`中的代码. 
    然后会自动穿透到`case2`中去执行里面的代码, 而不经过case2中的数据的验证. 

*/

例子

let t=10;
switch (t){
    case 1:
        console.log('我是1');
        console.log('我就是1');
        break;
    case 2:
        console.log('我是2');
        console.log('我就是2');
        break;
    case 3:
    console.log('我是3');
    console.log('我就是3');
    break;
    default:
        console.log('我是默认');
}

case穿透现象的利用

let month=5
switch (month){
    case 1:
    case 2:
    case 3:
        console.log('第一季度');
        break;
    case 4:
    case 5:
    case 6:
        console.log('第二季度');
                break;

    case 7:
    case 8:
    case 9:
        console.log('第三季度');
                break;

    case 10:
    case 11:
    case 12:
        console.log('第四季度');
        break;
    default:
        console.log('输入的月份要在1-12之间')
}

三. JS中的循环语句

在js中有三种循环语句. 首先是while循环. 它的逻辑和python中的while几乎一模一样, 就是符号上有些许的区别.

// 语法
while(条件){
    循环体 ->  里面可以有break和continue等关键字
}


/*
    判断`条件`是否为真, 如果`真`, 则执行`循环体`.执行完`循环体`, 会再次判断`条件`....
    并且在循环中也可以使用`break`和`continue`等关键字来控制循环的走向. 
*/
// 语法
do{
    循环体
} while(条件);

/*
    解读:
        先执行`循环体`, 然后判断`条件`是否成立, 如果成立.在来一次. 
    注意, 由于do..while是先执行的`循环体`. 所以, 不论条件如何, 至少执行一次`循环体`
*/

例子

let a=10;
do{
    console.log(a);
    a++;
} while (a<=10)
// 语法: for的第一种语法
for(表达式1; 表达式2; 表达式3){
    循环体
}
表达式1
while 表达式2:
    循环体
    表达式3

/*
    解读: 
        for循环和我们python中的循环是完全不一样的. 解读起来会有点儿麻烦. 
        首先, 在执行的时候, 先执行`表达式1`, 
        然后, 判断`表达式2`得到的结果是否真, 如果`真`, 则执行循环体, 
        再然后, 执行`表达式3`, 
        再然后, 判断`表达式2`执行的结果是否为`真`, 如果`真`, 则执行`循环体`
        再然后, 执行`表达式3`
        .....
        直到, `表达式2`得到的结果是`假`, 则跳出循环
*/
// 看起来很绕. 我们用for循环来跑一个1~99
for(var i = 1; i < 100; i++){
    console.log(i);
}
/*
    首先, i = 1, 
    然后, 判断 i < 100 成立
        打印i
    在然后, i++, i变成2
    再然后, 判断 i < 100 还是成立
        打印i
    再然后, i++, i变成3
    再然后, 判断 i< 100 还是成立
        打印3....
    ....
    当i = 100了. i < 100不成立. 程序结束 
*/

// for循环的固定逻辑也就这样了
for(变量声明; 条件判断; 改变变量){
    循环体
}

// for的第二种用法
var a = [11,22,33,44,55,66]
for(let i in a){
    console.log(i + "_" + a[i])
}
// 这种写法非常类似python中的for循环. 但是要注意. 这里的`i`拿到的仅仅是 `数组a`的索引信息. 
// 如果需要数据 a[i]

四.JS中的数组和对象(重点)

在JS中创建数组. 直接[ ]即可. 也可以用new Array(). 效果都是一样的.
在JS中 new 出来的东西,数据类型都是object;在JS中 创建空对象的时候,可以不写()

// 定义数字的两个方法

let a1=['刘德华', '张学友', '黎明', '郭富城'];

console.log(a1, typeof a1);     // [ '刘德华', '张学友', '黎明', '郭富城' ] object

// 在JS中 new 出来的东西,数据类型都是object
let a2=new Array('刘德华', '张学友', '黎明', '郭富城');
console.log(a2, typeof a2);     // [ '刘德华', '张学友', '黎明', '郭富城' ] object

// 在JS中 创建空对象的时候,可以不写()
let a3=new Array;
console.log(a3, typeof a3);     //[] object

数组的常用操作

arr.push(data); // 在数组后面添加数据

// 在JS中 创建空对象的时候,可以不写()
let a3=new Array;
console.log(a3, typeof a3);     //[] object

a3.push('下雨天')
a3.push('无名火', '666')
console.log(a3 );    //[ '下雨天', '无名火', '666' ]

arr.length; // 数组长度

let res=a3.length
console.log(res)

arr.pop(); // 删除数据, 从后面删除, 并返回被删除的内容

let a3=[ '下雨天', '无名火', '666' ]
let del = a3.pop()
console.log(del)    //666
console.log(a3)    // [ '下雨天', '无名火' ]

arr.shift() // 删除数据, 从前面删除, 并返回被删除的内容

let a=[ '下雨天', '无名火', '666' ]
let del = a.shift()
console.log(del)    // 下雨天
console.log(a)    // [ '无名火', '666' ]

arr.unshift(xxx); // 在数组之前增加数据

let b=[ '下雨天', '无名火', '666' ]
let add = b.unshift('刘德华', '张学友')     // 返回的是数组的长度;也可以不用变量接收
console.log(add)    // 5,返回的是数组的长度
console.log(b)    // [ '刘德华', '张学友', '下雨天', '无名火', '666' ]

arr.flat(); // 扁平化处理数组

let arr=[1, 2, 3, [4, 5, 6]]
arr = arr.flat()
console.log(arr)

arr.slice(开始索引,结束索引);切片功能,取左不取右;和python一样

let arr=[0, 1, 2, 3, 4, 5, 6]
let res = arr.slice(1,3)
console.log(res)

arr.join("连接符"); // 使用连接符将arr中的每一项拼接起来. 和python中的 "".join()雷同

let name=['刘德华', '张学友', '黎明', '郭富城'];
let res = name.join('-')
console.log(res);    // 刘德华-张学友-黎明-郭富城

arr.forEach中的每一项循环出来. 分别去调用function函数, 会自动的将数据传递给函数的第一个参数,第二个参数是数组的索引,第三个参数就是数组本身arr

let arr=[11, 22, 33, 44, 55, 66]
arr.forEach(function fn(a,b,c){
    console.log(a, b, c, a+b);
})

在JS中创建一个字典(也属于对象,object类)非常容易. 和python中的字典几乎一样,JS中的字典的key可以加引号,也可以不加。

var p = {
    name: "刘德华",
    age: 18,
    wife: "朱丽倩",
    
    sin: function(){
        console.log("唱歌")
    }
};

重点:
把对象变成json字符串: JSON.stringify()
把字符串变成对象: JSON.parse()

let p = {
    name: "刘德华",
    age: 18,
    wife: "朱丽倩",

    sin: function(){
        console.log("唱歌")
    }
};

console.log(typeof p, p)
// 把字典对象转换成json字符串
let json_str=JSON.stringify(p)
console.log(typeof json_str, json_str)  // string {"name":"刘德华","age":18,"wife":"朱丽倩"}

// 把json字符串转换成字典对象
let dic = JSON.parse(json_str)
console.log(typeof dic)     // object

(重点)使用对象(数组、字典)的两种方法:
方法1:对象.key
方法2:对象['key']

console.log(p.name, p['age'])
p.sin()

从上述内容中几乎可以看到. JS对象的使用几乎是没有门槛的. 十分灵活

for(var n in p){
    if(typeof(p[n]) != 'function'){
        console.log(p[n])
    }
}

五. JS中的函数(重点)

// 函数:标准函数,有函数名,有参数
function fn(a,b){
    return a+b;
}

let res1 = fn(3, 4)
console.log(res1)

// 函数名可以是特殊符号,如 $、_
function $(){
    console.log('函数名称是$')
}
// 调用函数
$()

function _(){
    console.log('函数名称是_')
}
// 调用函数
_()

// 赋值,内存地址复制,函数运行的时候不是依赖函数的名字,而是函数的地址
sdgjksfldfgkjdsfh = _
sdgjksfldfgkjdsfh()

扩展一下
数组的元素是函数

let arr=[function (){
    console.log(123)}, function (){console.log(456)}, function (){console.log(789)}]

arr[0]()

// for循环运行函数
for (let i=0;i<arr.length;i++){
    arr[i]()
}

JS中的函数可以没有函数名,也可以自运行.
注意:JS中只要能够形成 xxx() 并且xxx是一个函数的话就可以执行。

自运行函数
(function gn(){
    console.log('我要自己运行');
})();

(function (){
    console.log('我是一个函数,我没有函数名,我自己运行')})()

带参数

// 带参数
(function (a, b){
    let sum=a+b;
    console.log('我是一个函数,我没有函数名,我自己运行 结果是:', sum)})(3, 4)

自运行函数带返回值,需要用变量接收

// 带返回值的自运行函数
let new_arg = (function (a, b){
    let sum=a+b;
    return sum
    })(3, 4)

console.log(new_arg)

自运行函数使用window中参数值的两种方法
window是HTML中的顶级作用域,作用于全局,是所有作用域的根。window中的方法可以直接使用,也就是可以直接省略window。如

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>        // 方法1:
        (function () {
    window.name = '刘德华';
})();console.log(name);
        // 方法2:
        (function (a) {
    a.age = 18;
})(window)

console.log(window.age)
</script>
</head>
<body>

</body>
</html>

注意:JS文件的时候,不可以直接使用window,因为window只是HTML中的顶级作用域,直接运行下面JS代码会报错,提示 window 没有定义。所以,在逆向扣代码的时候,要注意

(function () {
    window.name = '刘德华';
})()
console.log(name)

this的用法
字典对象可以使用this来调用对象本身的参数

let dic={
    name:'刘德华',
    age: 18,
    song: function (){
        console.log(this.name+'唱了一手歌')},
    today: function (){
        console.log('今天');
        this.song();
    }
}

JS中return多个值时,前面的表达式也会执行,但只返回最后一个

function fn(){
    let a=2;
    let b=3;
    return a++, a*b, a+b
}

console.log(fn())

执行顺序的时候,先执行a++,再执行a*b,最后执行并返回a+b的值

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容