原生js学习笔记
- 内容中的链接是相关的学习链接
- 是学习过程中的记录在代码中
开发环境配置
-安装HBuilder:HBuilder快捷键:
- 中途换行“Ctrl+Alt”
第一个HTML代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
// script标签用于引入js包,src值为js的路径
<script src="index.js">
</body>
</html>
</html>
- 小技巧:HBuilder中使用“Enter”快捷键可以快速补全代码。
如 输入sc+"Enter"键生成script标签,上述将代码写在html中,不推荐。更好的方法是写在一个文件中,再在html中引用js文件
第一个js代码块hello world
console、alert函数
// console.log方法用于打印,与浏览器F12控制台配合可以对Js进行调试
console.log("hello world");
// alert方法用于显示带有一条指定消息和OK的警告框
alert("error");
规则
- 每个语句后缀加上符号;
- 严格区分大小写
变量命名
// 以var开头,变量未赋值在控制台打印结果不会显示
var name = "hello js";
console.log(name);
变量命名规则
// 变量命名以值意义命名为英文,可以使用驼峰命名
var fontColor = "red";
// 可以使用下划线命名
var font_color = "blue"
变量简单运算
// 变量的运算
var a = 1;
var b = 2;
var c = a + b;
console.log(c);
常量
// 常量使用const关键字命名,不能变化的数据用常量来储存,不能改变常量的值
const Five_SECONDS = 100;
console.log(Five_SECONDS);
基本数据类型
// 数据类型
// 布尔值 true 和false
var visible = true;
var isTrue = false;
console.log(visible)
console.log(isTrue)
// 整型、浮点型
var num_a = 100
var float_a = 0.1
var negative = -100
console.log(num_a)
console.log(float_a)
console.log(negative)
// 字符串
var str_a = "hello"
console.log(str_a)
// 未定义
// notUndef等同于notUndef_1 = undefined;
var notUndef;
var notUndef_1 = undefined;
console.log(notUndef);
console.log(notUndef_1);
// 空值 null,与未定义不同,未定义是没有值,null为null值
var empty_a = null;
console.log(empty_a);
数据类型转换
// 数据类型转换
// type0f 获取数据类型
// visible是boolean类型
console.log(typeof visible);
// num_a 是 number类型
console.log(typeof num_a);
// notUndef是undefined类型
console.log(typeof notUndef);
// empty_a 是 object类型
console.log(typeof empty_a);
// str_a是string类型
console.log(typeof str_a);
// float_a是number类型
console.log(typeof float_a);
// 转换 number类型和string类型相加后为string类型
//
var result = num_a +str_a;
console.log(result);
console.log(typeof result);
// parseInt(str_b)f方法将string类型转换为number类型
var str_b = "123";
console.log(parseInt(str_b) + num_a);
console.log(str_b);
操作符、算术操作符
// 操作符 "="赋值
var x = 10;
var y = x;
console.log(y);
// A=+B 会将B转化为数字并赋值给A
var strNum = 0;
var strNum = + "3";
console.log(strNum, typeof strNum);
// ++ 会自增长1
var num_b = 8;
// 8,++先返回变量值num_b的值
console.log(num_b++);
// 9
console.log(num_b);
// ++num_b变量值自增长1
// 10
console.log(++num_b);
// 10
console.log(num_b);
// --num_b变量值自减1
// 9
console.log(--num_b);
// 9
console.log(num_b);
// num_b--返回前面的变量值9,值不变
console.log(num_b--);
// 值-1,8
console.log(num_b);
// 算术操作符,加减乘除,取余,次方
console.clear()
console.log("1+5", 1+5);
console.log("5-1=", 5-1);
console.log("3*9=",3*9);
console.log("7/2=", 7/2)
console.log("7%2", 7%2);
console.log("4 ** 2 = ", 4**2);
比较操作符号
console.clear()
console.log("1>5", 1>5);
console.log("1>=5", 1>=5);
console.log("5>=5", 5>=5);
// ==不同的类型比较值是否相等,===类型不同返回false
// true
console.log("5==5", 5==5);
// true
console.log('5 == "5"', 5 == "5");
// false
console.log('5==="5"', 5 === "5");
// true
console.log('5 === "5"', 5 === 5);
// true 值相等
console.log("undefined == null", undefined == null);
// false 类型不同
console.log("undefined === null", undefined === null);
// 逻辑操作符,与或非
console.clear();
// && 与
//真
console.log("true && true", true && true);
// false
console.log("true && false", true && false)
// 或
// false
console.log("true || false", true || false);
// true
console.log("true || true", true || true)
// 非
// false
console.log("!true", !true);
// 与链接布尔和 其他类型数据
// 返回hello
console.log('true && "hello"', true && "hello" );
// 或链接false 和 其他类型值返回default
console.log("false || 'default'", false || 'default');
// 5
var a = null;
b = a || 5;
console.log(b);
// 与第一个操作符为false,第二个值不会被打印出来.false
console.log('false && "not printed"', false && "not printed");
// 返回5,与或非会返回表达式的结果
console.log('true || "not printed"', (4+1) || "not printed");
// !一个!会将数据转换为布尔值 ,false
console.log(!4);
// !!两个!!会将其他数据转化为布尔值,true
console.log(!!4);
// 5 101
// 5 011
// 转化为二进制,5二进制101,3二进制 011, 与有0返回0,2个1返回1,5和3返回001,
// 二进制001,十进制1
console.log("5 & 3", 5 &3);
// 与 二进制计算:有一个1返回1,都是0才会返回0,这里返回111,十进制7
console.log("5 | 3", 5 | 3);
// 异或, ^相同返回0,不同返回1,返回110
console.log("5 ^ 3", 5 ^ 3);
// 取反 ~ 一般为-(num+1)对数字取反,0转化为1,1转化为0;并对所有二进制位转化,如5的二进制位有32位
// -6
console.log("~5 ", ~5 );
// -4
console.log("~3",~3 );
// 左移:对二进制整体往左移一位,右边不够用0补齐
// 5 101 左移 1010 返回10 >>
console.log("5 << 1", 5 << 1);
// 右移:对二进制整体向右移一位,左边不够用0补齐
// 5 101 右移, 0101,返回2
console.log("5 >> 1", 5 >> 1);
返回结果
Console was cleared
index.js:157 true && true true
index.js:159 true && false false
index.js:162 true || false true
index.js:164 true || true true
index.js:167 !true false
index.js:170 true && "hello" hello
index.js:172 false || 'default' default
index.js:177 5
index.js:180 false && "not printed" false
index.js:182 true || "not printed" 5
index.js:184 false
index.js:186 true
index.js:191 5 & 3 1
index.js:193 5 | 3 7
index.js:195 5 ^ 3 6
index.js:198 ~5 -6
index.js:200 ~3 -4
index.js:203 5 << 1 10
index.js:206 5 >> 1 2
三目运算符
判断条件+问号,满足条件执行冒号前的代码,不满足执行后面的。
// 三目运算符:满足条件执行冒号前的代码,不满足执行后面的
console.clear();
var temperature = 10;
console.log(temperature > 9 ? "出门" : "在家");
console.log(temperature > 15 ? "出门" : "在家");
返回值
Console was cleared
index.js:213 出门
index.js:214 在家
流程图语句模块
用let定义的变量和const定义的常量只能在语句块内部使用,var可以在全局使用.
语句块中 使用 let 定义变量.
console.clear();
// 语句块,用let定义的变量和const定义的常量只能在语句块内部使用,var可以在全局使用
// 实际最好的语句块中 使用 let 定义变量
{
var name = "啊米";
console.log(name);
let age = "20";
// 20
console.log(age);
}
// 啊米
console.log(name);
// not defined
console.log(age);
啊米
index.js:226 20
index.js:229 啊米
index.js:231 Uncaught ReferenceError: age is not defined
at index.js:231
if-else流程控制
// if-else流程控制
console.clear();
// prompt()函数让你输入框输入值
var password = prompt();
if (password === "1234"){
alert("登录成功");
} else {
alert("登录失败");
}
if --else if --else流程语句
// if --else if --else流程语句
var role = prompt("请输入用户权限")
if (role === "超级管理员"){
alert("跳转到超级管理员页面");
} else if (role === "管理员"){
alert("跳转到普通页面");
} else {
alert ("提示error");
}
流程控制语句 switch case。
使用break阻止下一个case的运行,使用default规定匹配不存在时执行的程序.
break必须写上
var role = prompt("请输入用户权限");
switch(role){
case "超级管理员":
alert("超级管理员页面");
break;
case "管理员":
alert("管理员页面");
break;
default:
alert("默认页面");
}
流程控制 循环 while语句
var password = "";
while(password !== "123456"){
password = prompt("请输入密码");
}
console.log("登录成功")
do while 、 for语句
// do while 循环
// do{
// 循环体;
// }while(判断条件);
// 5,6,7,8,9,10
var x = 5;
do {
console.log(x++);
} while (x > 5 && x <= 10);
// 流程控制for循环
// 初始化变量,条件,增量表达式
console.clear()
for(let i = 0; i < 10; i+= 2){
console.log(i);
}
流程控制 break continue
break强行中止循环,不会执行后面的程序;
continue强行中止循环,仍会执行后面的程序;
// 返回0~5
for(let i = 0; i < 10;i ++){
if(i === 6){
break;
}
console.log(i);
}
// CONTIUE打断当前条件,但后面的会打印出来,break则不会
// 返回0~5,7~9
for(let i = 0; i < 10;i ++){
if(i === 6){
continue;
}
console.log(i);
}
函数
// 函数
// 函数三部曲,定义函数,传参,调用函数
// 函数名称最好用动词
console.clear()
// function putToCat(a,b){
// return a + b;
// }
// putToCat(1,2);
// console.log(putToCat(1,2));
// return可以打断函数,或者返回函数值
console.clear()
function putTodog(c,d){
if (c>4) return d;
return
}
var data1 = putTodog(4,5);
// 未定义undefined
console.log(data1);
var data2 = putTodog(5,6);
// 返回 6
console.log(data2);
// 函数的返回值可以作为变量
var result = putTodog(6,data2);
// 返回6
console.log(result);
// 不传参,返回undefined
var data5 = putTodog();
console.log(data5);
函数表达式、匿名函数
// 函数表达式
// 返回函数本身的值
// ƒ putTodog(c,d){
// if (c>4) return d;
// return
// }
console.log(putTodog);
// 函数表达式可以把函数名赋值给新变量,使用新变量调用函数
var add = putTodog;
var res = add(7,8);
// 返回8
console.log(res);
// 匿名函数,省略函数名称,赋值给变量,调用函数
var multiply = function(a,b){
return a * b ;
};
// 返回2
console.log(multiply(1,2));
函数提升、默认参数传参
// 变量及函数提升
// 函数的提升。可以把函数放到底部,调用代码放在前面
console.clear();
var data4 = divide(2,1);
// 返回2
console.log(data4);
function divide(a,b){
return a/b;
};
// 函数:默认参数 para = ""
console.clear()
// 不传参返回10
var age = setdefault();
console.log(age);
var age1 = setdefault("11");
console.clear();
// 返回11
console.log(age1);
function setdefault(age = "10"){
return ("小民今年"+age+"岁了")
}
// 多个参数,第一个传undefined,会传递默认参数
function greetingWith(name = "哈哈", word ){
// name返回默认值哈哈,
console.log(name+word);
};
greetingWith(undefined, "你好");
递归
示例:和、费波切那数列
// 函数递归:函数自己递归自己,和条件结合
// 计算num+...+1到的和
function getit(num){
if (num <= 1){
return 1;
};
return num + getit(num-1);
};
var data10 = getit(100);
// 返回5050 ,1.+100的值
console.log(data10);
// 费波切那数列
// 1 1 2 3 5 8 13--
function fib(num){
if (num <= 1){
return 1;
};
return fib(num -1) + fib(num -2);
}
// 返回8,5意思从0开始计算出坐标第6个值
console.log(fib(5));
函数arguments
// 函数arguments,可变参数,接收多个参数,函数定义不需要写形参
console.clear();
// 定义函数
function cal(){
// for 循环, 变量初始化, 条件,变量自增长
for(let i = 0 ; i < arguments.length; i++){
// arguments通过下标[]获取参数值
console.log(arguments[i]);
};
};
// 1,2
cal("1","2");
作用域、全局变量、局部变量
// 作用域:没有在函数内定义的变量:全局变量
// 局部变量:定义在函数内的变量
// 外部不能访问到局部变量
// 相同的变量名,外部变量会被内部变量覆盖
// x全局变量
var x = 4;
// var a = 3;
function sum(a){
// a 为局部变量参数
// 返回4,x为局部变量
var x = 2;
//
console.log( a + x );
}
// 返回6
sum(2);
var/let的区别
// var/let的区别
// 相同:定义变量。定义的变量出了函数不能访问。全局变量都可以使用
// 不同:除了函数外的代码块中定义的变量是否能被访问到。如在if-else,for语句块中
// var声明的变量在代码块外部也可以使用,let声明的变量在代码快外部不能使用。
// const定义的常量规则和let一样
// if-else代码块中的var变量可以在外部访问
console.clear();
var i = 2;
if( i > 1){
var j = 2;
// console.log(i);
}
// 2
console.log(j);
// for循环中的let变量在代码块外部无法访问
console.clear();
for (let m = 0;m <5; m ++){
// console.log(a);
let n = 3;
};
// console.log("m",m);
// 程序阻塞,Uncaught ReferenceError: n is not defined
// console.log("n",n);
箭头函数
// 箭头函数
// 格式var 变量名 = (多个参数)=> 或者 var 变量名 = 单个参数 =>{}
console.clear()
// 多个函数
var print_hello = (word,langa) => {
console.log(word+","+langa);
};
// 返回hello,javascript
print_hello("hello", "javascript")
// 单个函数
console.clear()
// 单个函数的语法
var calsum = x => x * 2;
// 返回12
console.log(calsum(6));
闭包
// 闭包:函数内定义另一个函数,内函数可以访问外函数变量,外函数不暴露内函数,外部无法访问
// 内函数,内函数形成为私有函数private
// 定义函数,箭头函数语法
var getage = (x,y) => {
var age = (x) => {
return x * x ;
};
return age(x) + age(y);
};
console.log(getage(1,2));
// 闭包二
var getname = () => {
// 定义外部变量
var name = 'hah';
// 定义内部函数
var setname = () => {
// 返回外函数变量
return name;
};
// 返回内函数名
return setname;
};
console.clear();
// 返回内函数名setname
var res = getname();
// res值为内函数内容
console.log(res);
// 返回内函数返回值 hah
console.log(res());
函数柯里化
// 函数柯里化:把接收多个参数的函数换成接收一个单一参数的函数
// 函数柯里化思想:一个JS预处理的思想,降低通用性,提高适用性。
// 正常函数
console.clear();
function addTreeNums(a , b ,c){
return a + b + c;
};
// 6
console.log(addTreeNums(1,2,3));
// 改造成柯里化函数
function add_threenum(a){
// 返回新的函数,fuction()
return function(b){
// 返回新的函数
return function(c){
// 返回表达式
return a + b + c;
};
};
};
// 调用柯里化函数 6,调用语法fuction(a)(b)(c)
var value = add_threenum(1)(2)(3);
console.log(value);
// 函数柯里化一般可以用于前两个参数固定的情况下,第三个参数变化,调用不同参数
// 返回
console.clear()
var add_two = add_threenum(1)(2);
// 返回7
console.log(add_two(4));
// 返回8
console.log(add_two(5));
自执行函数
// 自执行函数:将代码放在自执行函数,创建一个命名空间。直接调用函数,内部变量为私有变量
// 也可以传参数的,把外部的函数,变量什么穿进去也是可以的
console.clear();
var a =2;
function get_a(){
var a = 1;
// 1
console.log(a);
}
// 调用函数
get_a();
// 打印变量a的值.2
console.log(a);
console.clear();
var num_c = 2;
(function get_self(){
var num_c = 1;
// 返回1
console.log(num_c);
}())
// 全局变量返回2
console.log(num_c);
回调函数
// 回调函数:一段代码执行完后,需要调用的另一个函数
// 一般是调用一个函数内,执行另一个函数
// 语法1
// 传入函数名
function request(cb){
console.log("调用回调");
// 调用传入的回调函数;
cb("js");
console.log("回掉结束");
};
function callback(result){
console.log("hello,"+result);
};
// 调用主函数request 返回 hello, js
request(callback);
// 语法2 不用单独定义回调函数callback,插入函数体,缺点是不能复用回掉函数
request(result => {
// 插入回调函数的函数体
// 调用主函数request 返回 hello, js
console.log("hello,"+result);
});