版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_30162859/article/details/82812273
目录
JS 基础
JS能做的东西:
- 网页特效
- 服务端开发 node.js
- 命令行工具 node.js
- 桌面 Electron
- App Cordova
- 控制硬件-物联网 Ruff
- 游戏开发 cocos2d-js
第0部分: 预备
1. Js代码书写地方
1. 在script标签中
2. 写在html标签中: `<button onclick="alert('abc');" />`
3. 在外部.js文件中,由html文件引入: <script src="demo.js" ></script>
2. js代码的注意问题
- 在一对
script
标签中有错误的代码,后面的代码也不会执行 - 一对
script
标签的错误,不会影响其他script
标签中的代码执行; - 在
script
标签中,本来要写type="text/javascript"
或者language="JavaScript"
,但是html5标准中可以省略 type
和language
也可以同时写在script
中script
标签在页面中可以出现多个script
标签的位置一般放在<body>
内部的最后端- 如果一个
script
标签的作用是引入外部的js文件,那么这个script
标签中不要写代码
第一部分: ECMAScript
1. 变量
1.1 基本代码规范:
- JS变量区分大小写
- 字符串使用单引号或者双引号
- 语句用分号结尾
1.2 变量名规范:
- 一般以字母,$,下划线,数组组成,但不能以数字开头
- 变量名一般小写
- 使用camelCase方式命名
- 不能使用关键字
- 第二次初始化同一个变量名,则初始化会变成赋值
1.3 声明+初始化:
var num = 10;
var num1, num2, num3;
var num1, num2, num3 = 10;
var num1=10, num2 = 10, num3 = 20;
var num1 = num2 = num3 = 30;
var name = '小黑'; // 字符串使用 " 或者 '
var flag = true;
var obj = null;
console.log(flag);
** 案例1:交换2个变量的值
var num1 = 10, num2 = 20;
var num1 = num1 + num2;
num2 = num1 - num2;
num1 = num1 - num2;
var num1 = 10, num2 = 20;
var temp = num2;
num2 = num1;
num1 = temp;
console.log(num1,num2);
var num1 = 10, num2 = 20;
num1 = num1 ^ num2;
num2 = num1 ^ num2;
num1 = num1 ^ num2;
2. 变量类型
2.1 原始数据类型:
- number: 整数和小数都是 number 类型
- string
- boolean
- null: 类型还是 object
- undefined : 变量声明没赋值、 函数没有返回值确赋值给了一个变量; undefined 和数字运算,结果为 NaN,也是number类型
- object
2.2 查看变量类型:
typeof(变量);
typeof 变量;
// number string boolean object undefined object
- number类型的最大最小值
Number.MAX_VALUE
Number.MIN_VALUE
- 不要用小数和小数相等
(0.1+0.2) == 0.3 // false
- 和NaN比较:
数字和undefined运算,结果是NaN,类型为number; 数字和NaN运算,结果是NaN,类型为number
isNaN(10); // NaN != NaN
- 字符串
// 长度
strvar.length
//转义
\\
// 拼接:
str3 = str1 + str2
console.log(10+"20"); // 1020
console.log(10-"20"); // -10
console.log(10 * "5"); // 50
2.3 进制表示
十六进制: 0x
八进制: 0
2.4 类型转换
- 字符串转数字:
parseInt(str)
parseFloat(str) // 从str开头,能转多少字符转多少
Number(str) // 要整体是数字才能转换,不像parse从起始转
- 转字符串:
num.toString(); //变量无意义,则无法使用 toString()
String(var);
var + '';
- 转boolean:
Boolean(var):
1 true
0 false
11 true
-10 true
"hah" true
"" false
null false
undefined false
2.5 操作符
== 不严格的等于:
var str = "5";
var int = 5;
str == int ; // true
=== 严格的等于:
str === int ; // false
3. 条件判断
if (条件){ // 条件部分会被转换成 Boolean
}
if(){
}else{
}
switch (key) {
case value:
break;
default:
break;
}
3.1 switch 注意事项
switch内部的比较是使用的===
,判断类型+内容,而不是==
var age = "10"
switch (key) {
case 10:
..
break;
case "10":
console.log("字符串10"); // 会执行这一句
break;
}
4. 循环
document.write()
写到HTML文档中的东西,在源代码中看不到,而在调试窗口能看到。
while (condition) {
}
do {
} while (condition);
for (let index = 0; index < array.length; index++) {
const element = array[index];
}
for in
5. 数组
创建
var ar = new Array(); // 构造函数创建
var ar = new Array(5);
var ar = new Array(10,20,30,40,50);
var ar = []; //字面量创建
动态改变数组长度
var ar = [];
ar[0] = 1;
ar[1] = "";
a[2] ; //undefined 不存在的值会undefined
遍历:
a.forEach(element => {
console.log(element);
});
for (const iterator of a) {
console.log(iterator);
}
6. 函数
function funcname(arg1, arg2){
...
return result;
}
Math.PI
6.1 函数的注意问题:
- 函数一旦后面的会覆盖前面的函数
- 形参的个数和实参的个数可以不一致, 没有传递的值或者接收了没有return的函数值,结果是
undefined
- 直接输出函数名字,结果为函数的代码
6.2 arguments
arguments
是一个伪数组
function funcname(){
arguments // 获取所有传入的参数 arguments.length
}
6.3 命名函数和匿名函数
- 函数声明和函数表达式
函数能够调用,是因为函数名存储的函数的代码:
function f1(){
}
f1(); // 函数代码();
var f2 = function (){
};
f2();
函数声明,同名的后面覆盖前面:
function f1(){
console.log('1');
}
f1();
function f1(){
console.log('2');
}
f1();
// 结果会打印2次 2
下面这个是函数表达式,它不像函数声明y一样后面的覆盖前面的
f2 = function (){
console.log('1');
}
f2();
f2 = function (){
console.log('2');
}
f2();
// 结果会打印 1 2
- 匿名函数
匿名函数本质也是一样,只是没有函数名:
(function (){
})()
- 函数作为参数和返回值
函数作为参数,叫做回调函数
typeof f1 // function
function f1(f2){
f2();
}
function f2(){
}
function f3(){
return function(){
console.log();
}
}
fn = f3();
fn();
6.4 作用域
1.全局变量和局部变量****全局作用域、局部作用域、块级作用域
var
在函数外面声明的变量是全局变量- 函数内部定义的是局部变量
- JS中的块级作用域,如果用
var
定义的是全局变量,用let
定义的是块级变量 - 声明变量没有使用
var
,叫作隐式全局变量: function中定义的,外面也能访问 - 定义变量使用
var
是不会被删除的,没有使用var
是会被删除的
num1 = 10;
delete num1; //删除隐式全局变量; 而`var`定义的全局变量无法被删除
2.作用域链
0级链–1级链–2级链…
var num = 10;
function f1(){
var num = 20;
function f2(){
var num = 30;
function f3(){
var num = 40;
console.log(num);
}
}
}
6.5 预解析
- 浏览器把变量、函数的声明提前了,提前到当前作用域的最上面
- 不会提升到作用域之外
- 不同的
<script>
之间的预解析不会互相干扰 - 先提升
var
再提升function
,即 var在function之前
例1:
console.log(num); // 结果为 undefined,代表变量声明了但是没赋值
var num = 10;
例2:
f1();
var num = 20;
function f1(){
console.log(num); // 结果为undefined
var num = 10;
}
例3:
f1(); // 结果为undefined
var num = 20;
function f1(){
console.log(num);
}
例4:
console.log(a); // 易错点:输出函数代码
function a(){
console.log('hahaha');
}
var a = 1;
console.log(a); // 输出1
// 上面提升后的结果为(先var,后function):
var a ;
function a(){...}
console.log(a);
a = 1;
console.log(a);
例5:
f1();
console.log(c); // 9
console.log(b); // 9
console.log(a); // 报错
function f1(){
var a = b= c = 9; //易错点
console.log(a);
console.log(b);
console.log(c);
}
//提升后为:
function f1(){
var a; //局部变量
a = 9;
b = 9; //隐式全局变量
c = 9; //隐式全局变量
console.log(a);
console.log(b);
console.log(c);
}
console.log(c);
console.log(b);
console.log(a);
例6:
f1(); //无法调用, 因为函数表达式不会提升, 只提升函数定义
var f1 = function(){
console.log(a);
var a = 10;
}
7. 对象
js不是面向对象的语言,但是可以模拟面向对象的思想
7.1 创建对象
1. 通过调用系统的构造函数创建
var obj = new Object();
obj.age = 18;
obj.name = "foo";
obj.eat = function(){
this.age ... //当前对象中使用 this关键字
};
变量 instanceof 类型
2. 自定义构造函数创建
使用构造函数. 和普通函数的区别就是名字开头是否大写
function Person(name, age){
this.name = name;
this.age = age;
this.sayHi = function(){
console.log(this.name);
}
}
var obj = new Person('haha',18);
obj instanceof Person
创建对象经历的事情:
- 在内存中申请一块空闲的空间,创建对象
- 把this设置为当前对象
- 设置对象属性和方法
- 返回this对象
3. 字面量形式创建
var obj = {};
var obj = {
name: "小明",
age: 20;
sayHi: function(){
},
eat: function(){
}
};
7.2 获取和设置对象的属性、方法
obj.属性名 // 不管有没有,都能 点出来,点出来是 undefined
obj["属性名"] = 值
obj.plary();
obj['play']();
7.3 Json
var json = {
"name":"ab",
"age" : "18",
"sex": "male"
}
json.ddsdsd // 能点出来,但是没有的属性,都是 undefined
json.name
json["name"]
// 遍历对象
for(var key in obj){
console.log(key); // 遍历对象的属性
console.log(obj[key]); // 注意不要使用 obj.key,这就成了访问 'key'这个属性了
}
6.4 简单和复杂数据类型
- 值类型: number, string, boolean
- 引用类型: object
- 空类型:undefined, null
6.5 内置对象
JS有三种对象:内置对象、自定义对象、浏览器对象
在MDN上自学
内置对象:
- Math
Math的所有属性都是静态属性
// Math在内部的定义方式
Math = {} //Math是用 {}定义的,而不是 function Math() , 所以无法new
Math.abs = function(){} //静态
Math.prototype.funcname = function(){} // 实例方法
// Math 的方法/属性
Math.PI
Math.E
Math.abs .ceil .floor .random()
- Date
var d = new Date('2019-9-11')
d.valueof() //获得毫秒
var d = + new Date() //不支持H5的浏览器 通过这种方式获取毫秒
d.getMonth() // 从0开始
d.toString()
- String
字符串是不可变的
var str = "值类型";
var str2 = new String("引用类型");
str.length
str.concat(str2,str3..)
str.indexOf('substr')
str.match(regex)
.replace .search .slice .split .substr .substring
.toLowerCase .toUpperCase .trim()
String.fromcharcode()
- Array
Array.isArray()
arr1.concat(arr2)
arr.every() // 所有元素都要满足条件,才返回true
arr.filter() // 返回满足条件元素构成的新数组
arr.pop() // 从后面删除并且返回
.push(值) // 在后面插入,返回数组长度
.shift() 删除第一个元素并且返回
.unshift(值) // 在前面插入,返回长度
.foreach
var str = arr.join('符号')
.slice // 截取
6.6 基本包装类型
本身是基本类型,但是在执行代码的过程中,如果调用了属性或者方法,则该变量就变成了包装类型:
- string
- number
- boolean
str.indexOf()
num.toString()
var flag = new Boolean(false);
flag && true // true , 因为第一个是对象,对象是true
true && flag // 返回是这个对象
var num2 = Number("10"); //类型转换
var num3 = new Number("10"); //基本包装类型